From 49079886ecb491cb971ff31fea06cff3e22467c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 22:15:18 +0000 Subject: [PATCH 001/209] Bump github/codeql-action from 1 to 2 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v1...v2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e032c6652..13d66ad2c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,7 +23,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java @@ -31,7 +31,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # โ„น๏ธ Command-line programs to run using the OS shell. # ๐Ÿ“š https://git.io/JvXDl @@ -45,4 +45,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 From fbcb2c1336a705e0a7c7d7cbd8696baa46848258 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 May 2022 22:17:19 +0000 Subject: [PATCH 002/209] Bump docker/build-push-action from 1 to 3 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 1 to 3. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v1...v3) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/container.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index a768eba8f..a36751d0c 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -13,4 +13,4 @@ jobs: steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - - uses: docker/build-push-action@v1 + - uses: docker/build-push-action@v3 From 2bcfb865d0a88c3490c8304935263eb4a417aab2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jun 2022 15:44:20 +0000 Subject: [PATCH 003/209] Bump express-async-handler from 1.1.4 to 1.2.0 Bumps [express-async-handler](https://github.com/Abazhenov/express-async-handler) from 1.1.4 to 1.2.0. - [Release notes](https://github.com/Abazhenov/express-async-handler/releases) - [Commits](https://github.com/Abazhenov/express-async-handler/commits) --- updated-dependencies: - dependency-name: express-async-handler dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 99b113059..7c4993751 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "deepmerge": "4.2.2", "dotenv": "10.0.0", "express": "4.17.3", - "express-async-handler": "1.1.4", + "express-async-handler": "1.2.0", "express-session": "1.17.2", "express-sslify": "1.2.0", "file-size": "1.0.0", @@ -4953,9 +4953,9 @@ } }, "node_modules/express-async-handler": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.1.4.tgz", - "integrity": "sha512-HdmbVF4V4w1q/iz++RV7bUxIeepTukWewiJGkoCKQMtvPF11MLTa7It9PRc/reysXXZSEyD4Pthchju+IUbMiQ==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", + "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" }, "node_modules/express-session": { "version": "1.17.2", @@ -14408,9 +14408,9 @@ } }, "express-async-handler": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.1.4.tgz", - "integrity": "sha512-HdmbVF4V4w1q/iz++RV7bUxIeepTukWewiJGkoCKQMtvPF11MLTa7It9PRc/reysXXZSEyD4Pthchju+IUbMiQ==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", + "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" }, "express-session": { "version": "1.17.2", diff --git a/package.json b/package.json index 284d626b8..c6c8e13f9 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "deepmerge": "4.2.2", "dotenv": "10.0.0", "express": "4.17.3", - "express-async-handler": "1.1.4", + "express-async-handler": "1.2.0", "express-session": "1.17.2", "express-sslify": "1.2.0", "file-size": "1.0.0", From a6029fc9ff8603aa974c3efd5b47e623911101ea Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Mon, 12 Sep 2022 07:49:09 -0700 Subject: [PATCH 004/209] Add or update the Azure App Service build and deployment workflow config --- .github/workflows/main_nihgithubportal.yml | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/main_nihgithubportal.yml diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml new file mode 100644 index 000000000..46179cf17 --- /dev/null +++ b/.github/workflows/main_nihgithubportal.yml @@ -0,0 +1,56 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy Node.js app to Azure Web App - nihgithubportal + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Node.js version + uses: actions/setup-node@v1 + with: + node-version: '16.x' + + - name: npm install, build, and test + run: | + npm install + npm run build --if-present + npm run test --if-present + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v2 + with: + name: node-app + path: . + + deploy: + runs-on: ubuntu-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v2 + with: + name: node-app + + - name: 'Deploy to Azure Web App' + id: deploy-to-webapp + uses: azure/webapps-deploy@v2 + with: + app-name: 'nihgithubportal' + slot-name: 'Production' + publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_990190F22A5149AC859307273BAE196C }} + package: . From 4347cd38ae40efbe1a981ebb18450d82fa7a36f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:49:58 +0000 Subject: [PATCH 005/209] Bump actions/setup-node from 2 to 3.1.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2 to 3.1.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2...v3.1.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/main_nihgithubportal.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e8ca8319..7d603d128 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v2 - name: Setup Node - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 - name: Install Dependencies run: npm ci diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 46179cf17..a2cb2417d 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v2 - name: Set up Node.js version - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: '16.x' From 6f1ec0392d459c0597da71490d69aac5d8134f9c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:50:23 +0000 Subject: [PATCH 006/209] Bump luxon and @types/luxon Bumps [luxon](https://github.com/moment/luxon) and [@types/luxon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/luxon). These dependencies needed to be updated together. Updates `luxon` from 2.3.1 to 3.0.3 - [Release notes](https://github.com/moment/luxon/releases) - [Changelog](https://github.com/moment/luxon/blob/master/CHANGELOG.md) - [Commits](https://github.com/moment/luxon/compare/2.3.1...3.0.3) Updates `@types/luxon` from 2.3.1 to 3.0.1 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/luxon) --- updated-dependencies: - dependency-name: luxon dependency-type: direct:production update-type: version-update:semver-major - dependency-name: "@types/luxon" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 28 ++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 99b113059..25e25fa92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,7 @@ "jwks-rsa": "2.0.5", "language-map": "1.5.0", "lodash": "4.17.21", - "luxon": "2.3.1", + "luxon": "3.0.3", "memory-cache": "0.2.0", "moment": "2.29.1", "morgan": "1.10.0", @@ -94,7 +94,7 @@ "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", "@types/lodash": "4.14.180", - "@types/luxon": "2.3.1", + "@types/luxon": "3.0.1", "@types/memory-cache": "0.2.2", "@types/morgan": "1.9.3", "@types/multer": "^1.4.7", @@ -2167,9 +2167,9 @@ "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" }, "node_modules/@types/luxon": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.1.tgz", - "integrity": "sha512-nAPUltOT28fal2eDZz8yyzNhBjHw1NEymFBP7Q9iCShqpflWPybxHbD7pw/46jQmT+HXOy1QN5hNTms8MOTlOQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.0.1.tgz", + "integrity": "sha512-/LAvk1cMOJt0ghzMFrZEvByUhsiEfeeT2IF53Le+Ki3A538yEL9pRZ7a6MuCxdrYK+YNqNIDmrKU/r2nnw04zQ==", "dev": true }, "node_modules/@types/memory-cache": { @@ -7420,9 +7420,9 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "node_modules/luxon": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.3.1.tgz", - "integrity": "sha512-I8vnjOmhXsMSlNMZlMkSOvgrxKJl0uOsEzdGgGNZuZPaS9KlefpE9KV95QFftlJSC+1UyCC9/I69R02cz/zcCA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.0.3.tgz", + "integrity": "sha512-+EfHWnF+UT7GgTnq5zXg3ldnTKL2zdv7QJgsU5bjjpbH17E3qi/puMhQyJVYuCq+FRkogvB5WB6iVvUr+E4a7w==", "engines": { "node": ">=12" } @@ -12227,9 +12227,9 @@ "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" }, "@types/luxon": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.1.tgz", - "integrity": "sha512-nAPUltOT28fal2eDZz8yyzNhBjHw1NEymFBP7Q9iCShqpflWPybxHbD7pw/46jQmT+HXOy1QN5hNTms8MOTlOQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.0.1.tgz", + "integrity": "sha512-/LAvk1cMOJt0ghzMFrZEvByUhsiEfeeT2IF53Le+Ki3A538yEL9pRZ7a6MuCxdrYK+YNqNIDmrKU/r2nnw04zQ==", "dev": true }, "@types/memory-cache": { @@ -16260,9 +16260,9 @@ } }, "luxon": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.3.1.tgz", - "integrity": "sha512-I8vnjOmhXsMSlNMZlMkSOvgrxKJl0uOsEzdGgGNZuZPaS9KlefpE9KV95QFftlJSC+1UyCC9/I69R02cz/zcCA==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.0.3.tgz", + "integrity": "sha512-+EfHWnF+UT7GgTnq5zXg3ldnTKL2zdv7QJgsU5bjjpbH17E3qi/puMhQyJVYuCq+FRkogvB5WB6iVvUr+E4a7w==" }, "make-dir": { "version": "3.1.0", diff --git a/package.json b/package.json index 284d626b8..cde28e060 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "jwks-rsa": "2.0.5", "language-map": "1.5.0", "lodash": "4.17.21", - "luxon": "2.3.1", + "luxon": "3.0.3", "memory-cache": "0.2.0", "moment": "2.29.1", "morgan": "1.10.0", @@ -133,7 +133,7 @@ "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", "@types/lodash": "4.14.180", - "@types/luxon": "2.3.1", + "@types/luxon": "3.0.1", "@types/memory-cache": "0.2.2", "@types/morgan": "1.9.3", "@types/multer": "^1.4.7", From 8b942eee268a53e2e10498d8c23ba7293f45226d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Sep 2022 17:51:44 +0000 Subject: [PATCH 007/209] Bump @azure/identity from 2.0.1 to 3.0.0 Bumps [@azure/identity](https://github.com/Azure/azure-sdk-for-js) from 2.0.1 to 3.0.0. - [Release notes](https://github.com/Azure/azure-sdk-for-js/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md) - [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/identity_2.0.1...@azure/identity_3.0.0) --- updated-dependencies: - dependency-name: "@azure/identity" dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 179 ++++++++++++++++------------------------------ package.json | 2 +- 2 files changed, 64 insertions(+), 117 deletions(-) diff --git a/package-lock.json b/package-lock.json index add2f6267..ca2fe045f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@azure/cosmos": "3.11.5", "@azure/data-tables": "12.0.0-beta.2", - "@azure/identity": "2.0.1", + "@azure/identity": "3.0.0", "@azure/keyvault-secrets": "4.3.0", "@azure/service-bus": "7.7.1", "@azure/storage-blob": "12.8.0", @@ -370,21 +370,20 @@ } }, "node_modules/@azure/identity": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-2.0.1.tgz", - "integrity": "sha512-gdGGuLKlKIQaf2RefA84keoBfmWfiAntbW2SzcdKvwLSGzsio/qkyY3sYUpXRz/sqLDxguuimgZukp7TPgwIlg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.0.0.tgz", + "integrity": "sha512-MAwrefZE6T15wJe/tOA6dffdTNCh+S6DOQe2otO6drEEVCHDF0zb+GItlK6kQzD5hPm/YueFCW6sN1q6F4XYuQ==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.0.0", + "@azure/core-client": "^1.4.0", "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.0.0-beta.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^2.16.0", - "@azure/msal-common": "^4.5.1", - "@azure/msal-node": "^1.3.0", - "@types/stoppable": "^1.1.0", + "@azure/msal-browser": "^2.26.0", + "@azure/msal-common": "^7.0.0", + "@azure/msal-node": "^1.10.0", "events": "^3.0.0", "jws": "^4.0.0", "open": "^8.0.0", @@ -396,6 +395,17 @@ "node": ">=12.0.0" } }, + "node_modules/@azure/identity/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/keyvault-secrets": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.3.0.tgz", @@ -425,64 +435,35 @@ } }, "node_modules/@azure/msal-browser": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-2.23.0.tgz", - "integrity": "sha512-qxyWmsP/pf+xJFEhMgiJ0r1v6TjF+x8iMWYU5R63Lb/fjQfKalaNX9f5D6GbJYJS5s9OF3abtdGtB/Lxea15mQ==", + "version": "2.28.3", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-2.28.3.tgz", + "integrity": "sha512-2SdyH2el3s8BzPURf9RK17BvvXvaMEGpLc3D9WilZcmjJqP4nStVH7Ogwr/SNTuGV48FUhqEkP0RxDvzuFJSIw==", "dependencies": { - "@azure/msal-common": "^6.2.0" + "@azure/msal-common": "^7.4.1" }, "engines": { "node": ">=0.8.0" } }, - "node_modules/@azure/msal-browser/node_modules/@azure/msal-common": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-6.2.0.tgz", - "integrity": "sha512-SU2/vfbKn1WvtKM8tsBKZAbmRJvO8E3H773ZT0GGKuO9rwLfxP5qOzTHV5crCEm8DgvL/IppmWh2lsUFieDi1A==", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@azure/msal-common": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-4.5.1.tgz", - "integrity": "sha512-/i5dXM+QAtO+6atYd5oHGBAx48EGSISkXNXViheliOQe+SIFMDo3gSq3lL54W0suOSAsVPws3XnTaIHlla0PIQ==", - "dependencies": { - "debug": "^4.1.1" - }, + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-7.4.1.tgz", + "integrity": "sha512-zxcxg9pRdgGTS5mrRJeQvwA8aIjD8qSGzaAiz5SeTVkyhtjB0AeFnAcvBOKHv/TkswWNfYKpERxsXOAKXkXk0w==", "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-node": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.8.0.tgz", - "integrity": "sha512-rA5KzhvNuNef6Bzap8Sm/LbuesvA1yY2dj/W+QZuKMtT5nboZ4n4w8LRjwMMxucvYfizybPbLGTFpbq2IJtOfQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.0.tgz", + "integrity": "sha512-3XB7FuHLhmGBjw7bxuz1LCHOXQgmNIO3J56tlbOjuJcyJtd4aBCgnYIXNKLed3uRcQNHEO0mlg24I4iGxAV/UA==", "dependencies": { - "@azure/msal-common": "^6.2.0", - "axios": "^0.21.4", - "https-proxy-agent": "^5.0.0", + "@azure/msal-common": "^7.4.1", "jsonwebtoken": "^8.5.1", "uuid": "^8.3.0" }, "engines": { - "node": "10 || 12 || 14 || 16" - } - }, - "node_modules/@azure/msal-node/node_modules/@azure/msal-common": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-6.2.0.tgz", - "integrity": "sha512-SU2/vfbKn1WvtKM8tsBKZAbmRJvO8E3H773ZT0GGKuO9rwLfxP5qOzTHV5crCEm8DgvL/IppmWh2lsUFieDi1A==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@azure/msal-node/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" + "node": "10 || 12 || 14 || 16 || 18" } }, "node_modules/@azure/service-bus": { @@ -2401,14 +2382,6 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, - "node_modules/@types/stoppable": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/stoppable/-/stoppable-1.1.1.tgz", - "integrity": "sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/tunnel": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", @@ -10842,27 +10815,36 @@ } }, "@azure/identity": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-2.0.1.tgz", - "integrity": "sha512-gdGGuLKlKIQaf2RefA84keoBfmWfiAntbW2SzcdKvwLSGzsio/qkyY3sYUpXRz/sqLDxguuimgZukp7TPgwIlg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.0.0.tgz", + "integrity": "sha512-MAwrefZE6T15wJe/tOA6dffdTNCh+S6DOQe2otO6drEEVCHDF0zb+GItlK6kQzD5hPm/YueFCW6sN1q6F4XYuQ==", "requires": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.0.0", + "@azure/core-client": "^1.4.0", "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.0.0-beta.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^2.16.0", - "@azure/msal-common": "^4.5.1", - "@azure/msal-node": "^1.3.0", - "@types/stoppable": "^1.1.0", + "@azure/msal-browser": "^2.26.0", + "@azure/msal-common": "^7.0.0", + "@azure/msal-node": "^1.10.0", "events": "^3.0.0", "jws": "^4.0.0", "open": "^8.0.0", "stoppable": "^1.1.0", "tslib": "^2.2.0", "uuid": "^8.3.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "requires": { + "tslib": "^2.2.0" + } + } } }, "@azure/keyvault-secrets": { @@ -10888,53 +10870,26 @@ } }, "@azure/msal-browser": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-2.23.0.tgz", - "integrity": "sha512-qxyWmsP/pf+xJFEhMgiJ0r1v6TjF+x8iMWYU5R63Lb/fjQfKalaNX9f5D6GbJYJS5s9OF3abtdGtB/Lxea15mQ==", + "version": "2.28.3", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-2.28.3.tgz", + "integrity": "sha512-2SdyH2el3s8BzPURf9RK17BvvXvaMEGpLc3D9WilZcmjJqP4nStVH7Ogwr/SNTuGV48FUhqEkP0RxDvzuFJSIw==", "requires": { - "@azure/msal-common": "^6.2.0" - }, - "dependencies": { - "@azure/msal-common": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-6.2.0.tgz", - "integrity": "sha512-SU2/vfbKn1WvtKM8tsBKZAbmRJvO8E3H773ZT0GGKuO9rwLfxP5qOzTHV5crCEm8DgvL/IppmWh2lsUFieDi1A==" - } + "@azure/msal-common": "^7.4.1" } }, "@azure/msal-common": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-4.5.1.tgz", - "integrity": "sha512-/i5dXM+QAtO+6atYd5oHGBAx48EGSISkXNXViheliOQe+SIFMDo3gSq3lL54W0suOSAsVPws3XnTaIHlla0PIQ==", - "requires": { - "debug": "^4.1.1" - } + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-7.4.1.tgz", + "integrity": "sha512-zxcxg9pRdgGTS5mrRJeQvwA8aIjD8qSGzaAiz5SeTVkyhtjB0AeFnAcvBOKHv/TkswWNfYKpERxsXOAKXkXk0w==" }, "@azure/msal-node": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.8.0.tgz", - "integrity": "sha512-rA5KzhvNuNef6Bzap8Sm/LbuesvA1yY2dj/W+QZuKMtT5nboZ4n4w8LRjwMMxucvYfizybPbLGTFpbq2IJtOfQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.0.tgz", + "integrity": "sha512-3XB7FuHLhmGBjw7bxuz1LCHOXQgmNIO3J56tlbOjuJcyJtd4aBCgnYIXNKLed3uRcQNHEO0mlg24I4iGxAV/UA==", "requires": { - "@azure/msal-common": "^6.2.0", - "axios": "^0.21.4", - "https-proxy-agent": "^5.0.0", + "@azure/msal-common": "^7.4.1", "jsonwebtoken": "^8.5.1", "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/msal-common": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-6.2.0.tgz", - "integrity": "sha512-SU2/vfbKn1WvtKM8tsBKZAbmRJvO8E3H773ZT0GGKuO9rwLfxP5qOzTHV5crCEm8DgvL/IppmWh2lsUFieDi1A==" - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - } } }, "@azure/service-bus": { @@ -12578,14 +12533,6 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, - "@types/stoppable": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/stoppable/-/stoppable-1.1.1.tgz", - "integrity": "sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw==", - "requires": { - "@types/node": "*" - } - }, "@types/tunnel": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", diff --git a/package.json b/package.json index 2180b3474..b07133762 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "dependencies": { "@azure/cosmos": "3.11.5", "@azure/data-tables": "12.0.0-beta.2", - "@azure/identity": "2.0.1", + "@azure/identity": "3.0.0", "@azure/keyvault-secrets": "4.3.0", "@azure/service-bus": "7.7.1", "@azure/storage-blob": "12.8.0", From 851c891514ddbd2c153da69932dd1f9cd9e4b28c Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 22 Sep 2022 14:57:31 -0400 Subject: [PATCH 008/209] devoptimusprime's suggestions --- .github/workflows/main_nihgithubportal.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 46179cf17..15133d237 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -25,13 +25,27 @@ jobs: run: | npm install npm run build --if-present + cd ./default-assets-package + npm install + npm run build + cd .. npm run test --if-present + + - name: zip application folders + run: | + echo $PWD + ls -lah + cd .. + echo $PWD + ls -lah + tar -czf output.tar.gz ./opensource-management-portal + ls -lah - name: Upload artifact for deployment job uses: actions/upload-artifact@v2 with: name: node-app - path: . + path: /home/runner/work/opensource-management-portal/output.tar.gz deploy: runs-on: ubuntu-latest @@ -45,6 +59,11 @@ jobs: uses: actions/download-artifact@v2 with: name: node-app + + - name: Unpack tar + run: | + tar -xf output.tar.gz + ls -lah - name: 'Deploy to Azure Web App' id: deploy-to-webapp From 95525496abf67e4a1b06995bbed6fe960ff7b48f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Sep 2022 18:58:32 +0000 Subject: [PATCH 009/209] Bump actions/download-artifact from 2 to 3 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 3. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/main_nihgithubportal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 15133d237..511634305 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -56,7 +56,7 @@ jobs: steps: - name: Download artifact from build job - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: node-app From 656fb144fc0b567e7842a51c3a9141751565b10b Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 22 Sep 2022 15:00:55 -0400 Subject: [PATCH 010/209] Update paths for repo name --- .github/workflows/main_nihgithubportal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 15133d237..719091100 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -38,14 +38,14 @@ jobs: cd .. echo $PWD ls -lah - tar -czf output.tar.gz ./opensource-management-portal + tar -czf output.tar.gz ./github-portal ls -lah - name: Upload artifact for deployment job uses: actions/upload-artifact@v2 with: name: node-app - path: /home/runner/work/opensource-management-portal/output.tar.gz + path: /home/runner/work/github-portal/output.tar.gz deploy: runs-on: ubuntu-latest From d17dd5619e5602b82be63971e4e5ff558d99d96f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Sep 2022 19:01:46 +0000 Subject: [PATCH 011/209] Bump actions/upload-artifact from 2 to 3 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/main_nihgithubportal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 719091100..e5fe35dd6 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -42,7 +42,7 @@ jobs: ls -lah - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: node-app path: /home/runner/work/github-portal/output.tar.gz From 83738323658decbda023a5c371f7977d0294aeac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 22:19:14 +0000 Subject: [PATCH 012/209] Bump eslint from 8.11.0 to 8.24.0 Bumps [eslint](https://github.com/eslint/eslint) from 8.11.0 to 8.24.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.11.0...v8.24.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 327 +++++++++++++++++++++++++++++++++++----------- package.json | 2 +- 2 files changed, 253 insertions(+), 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index add2f6267..f293bccd4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -114,7 +114,7 @@ "@types/validator": "13.7.2", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", @@ -1171,23 +1171,26 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@hapi/boom": { @@ -1227,9 +1230,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1240,6 +1243,29 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -2747,9 +2773,9 @@ } }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4690,13 +4716,15 @@ } }, "node_modules/eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4706,30 +4734,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -4826,6 +4856,67 @@ "node": ">=4.0" } }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4842,17 +4933,20 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -5611,9 +5705,9 @@ } }, "node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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, "dependencies": { "type-fest": "^0.20.2" @@ -5650,6 +5744,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -7069,6 +7169,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -10256,12 +10362,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -10640,6 +10740,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -11466,19 +11578,19 @@ } }, "@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, @@ -11519,9 +11631,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -11529,6 +11641,18 @@ "minimatch": "^3.0.4" } }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -12792,9 +12916,9 @@ } }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "acorn-globals": { @@ -14297,13 +14421,15 @@ } }, "eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -14313,30 +14439,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "cross-spawn": { @@ -14366,6 +14494,43 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -14411,13 +14576,13 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } }, @@ -14995,9 +15160,9 @@ } }, "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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" @@ -15022,6 +15187,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -16045,6 +16216,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -18564,12 +18741,6 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -18860,6 +19031,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 2180b3474..ef1b38164 100644 --- a/package.json +++ b/package.json @@ -153,7 +153,7 @@ "@types/validator": "13.7.2", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", From 490a8656a40c24083622da5502c63054261912f7 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 28 Sep 2022 15:05:12 -0400 Subject: [PATCH 013/209] First Org Config --- env-orgs.json | 7 +++++++ env-orgs.json.example | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 env-orgs.json delete mode 100644 env-orgs.json.example diff --git a/env-orgs.json b/env-orgs.json new file mode 100644 index 000000000..be1870aa6 --- /dev/null +++ b/env-orgs.json @@ -0,0 +1,7 @@ +[ + { + "name" : "NIHGOV", + "id" : 2710462, + "description" : "NIHGOV" + } +] diff --git a/env-orgs.json.example b/env-orgs.json.example deleted file mode 100644 index b976ea538..000000000 --- a/env-orgs.json.example +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "name" : "contoso", - "id" : "your-github-user-id e.g. 123456789", - "ownerToken" : "your github owner token" - } -] From acacc9505410359434504726b9967fb6ba069290 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 29 Sep 2022 14:34:38 -0400 Subject: [PATCH 014/209] Testing repo visibility --- env-orgs.json | 1 + 1 file changed, 1 insertion(+) diff --git a/env-orgs.json b/env-orgs.json index be1870aa6..a44f32e12 100644 --- a/env-orgs.json +++ b/env-orgs.json @@ -2,6 +2,7 @@ { "name" : "NIHGOV", "id" : 2710462, + "type": "public", "description" : "NIHGOV" } ] From 27c4b4317070a8d9d561709784c1ab99a87c52a4 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 29 Sep 2022 15:01:22 -0400 Subject: [PATCH 015/209] More visibility testing --- env-orgs.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/env-orgs.json b/env-orgs.json index a44f32e12..b263495de 100644 --- a/env-orgs.json +++ b/env-orgs.json @@ -2,7 +2,13 @@ { "name" : "NIHGOV", "id" : 2710462, - "type": "public", - "description" : "NIHGOV" + "type": ["public", "private"], + "description" : "NIHโ€ฆTurning Discovery Into Healthยฎ" + }, + { + "name" : "STRIDES", + "id" : 69810051, + "type": ["public", "private"], + "description" : "NIH Science and Technology Research Infrastructure for Discovery, Experimentation, and Sustainability (STRIDES) Initiative" } ] From 4d588b81cf1b253ec520db45e1055d90fd2601c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:19:36 +0000 Subject: [PATCH 016/209] Bump @azure/cosmos from 3.11.5 to 3.17.1 Bumps [@azure/cosmos](https://github.com/Azure/azure-sdk-for-js) from 3.11.5 to 3.17.1. - [Release notes](https://github.com/Azure/azure-sdk-for-js/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md) - [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/cosmos_3.11.5...@azure/cosmos_3.17.1) --- updated-dependencies: - dependency-name: "@azure/cosmos" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 394 ++++++++++++++++++++++++++++++++++------------ package.json | 4 +- 2 files changed, 299 insertions(+), 99 deletions(-) diff --git a/package-lock.json b/package-lock.json index add2f6267..37f7b8ff8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "7.1.0", "license": "MIT", "dependencies": { - "@azure/cosmos": "3.11.5", + "@azure/cosmos": "3.17.1", "@azure/data-tables": "12.0.0-beta.2", "@azure/identity": "2.0.1", "@azure/keyvault-secrets": "4.3.0", @@ -114,7 +114,7 @@ "@types/validator": "13.7.2", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", @@ -310,24 +310,36 @@ } }, "node_modules/@azure/cosmos": { - "version": "3.11.5", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.11.5.tgz", - "integrity": "sha512-emKRLrrQLAzwVyOWo67THkPSWD646puwvUfr8oVhCYSs9OgfTCeNh29XB7uU4YZd3ufcumFrTupSCfH6AodZUA==", + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.17.1.tgz", + "integrity": "sha512-3pgPwNwAiTgiH/OgcntDLzrANy+roaaDFYoLOhC4bxoDC94nPCjpLYRRwueIpisZAdopPVrxQloNs9fEjVlL0A==", "dependencies": { "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.0.3", + "@azure/core-rest-pipeline": "^1.2.0", + "@azure/core-tracing": "^1.0.0", "debug": "^4.1.1", - "fast-json-stable-stringify": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", "jsbi": "^3.1.3", - "node-abort-controller": "^1.2.0", + "node-abort-controller": "^3.0.0", "priorityqueuejs": "^1.0.0", "semaphore": "^1.0.5", - "tslib": "^2.0.0", + "tslib": "^2.2.0", "universal-user-agent": "^6.0.0", "uuid": "^8.3.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" + } + }, + "node_modules/@azure/cosmos/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" } }, "node_modules/@azure/data-tables": { @@ -1171,23 +1183,26 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@hapi/boom": { @@ -1227,9 +1242,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1240,6 +1255,29 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -2747,9 +2785,9 @@ } }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4690,13 +4728,15 @@ } }, "node_modules/eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4706,30 +4746,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -4826,6 +4868,67 @@ "node": ">=4.0" } }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4842,17 +4945,20 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -5611,9 +5717,9 @@ } }, "node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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, "dependencies": { "type-fest": "^0.20.2" @@ -5650,6 +5756,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -7069,6 +7181,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -7904,9 +8022,9 @@ } }, "node_modules/node-abort-controller": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-1.2.1.tgz", - "integrity": "sha512-79PYeJuj6S9+yOHirR0JBLFOgjB6sQCir10uN6xRx25iD+ZD4ULqgRn3MwWBRaQGB0vEgReJzWwJo42T1R6YbQ==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", + "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==" }, "node_modules/node-bitmap": { "version": "0.0.1", @@ -10256,12 +10374,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -10640,6 +10752,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -10792,21 +10916,32 @@ } }, "@azure/cosmos": { - "version": "3.11.5", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.11.5.tgz", - "integrity": "sha512-emKRLrrQLAzwVyOWo67THkPSWD646puwvUfr8oVhCYSs9OgfTCeNh29XB7uU4YZd3ufcumFrTupSCfH6AodZUA==", + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.17.1.tgz", + "integrity": "sha512-3pgPwNwAiTgiH/OgcntDLzrANy+roaaDFYoLOhC4bxoDC94nPCjpLYRRwueIpisZAdopPVrxQloNs9fEjVlL0A==", "requires": { "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.0.3", + "@azure/core-rest-pipeline": "^1.2.0", + "@azure/core-tracing": "^1.0.0", "debug": "^4.1.1", - "fast-json-stable-stringify": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", "jsbi": "^3.1.3", - "node-abort-controller": "^1.2.0", + "node-abort-controller": "^3.0.0", "priorityqueuejs": "^1.0.0", "semaphore": "^1.0.5", - "tslib": "^2.0.0", + "tslib": "^2.2.0", "universal-user-agent": "^6.0.0", "uuid": "^8.3.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "requires": { + "tslib": "^2.2.0" + } + } } }, "@azure/data-tables": { @@ -11466,19 +11601,19 @@ } }, "@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, @@ -11519,9 +11654,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -11529,6 +11664,18 @@ "minimatch": "^3.0.4" } }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -12792,9 +12939,9 @@ } }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "acorn-globals": { @@ -14297,13 +14444,15 @@ } }, "eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -14313,30 +14462,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "cross-spawn": { @@ -14366,6 +14517,43 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -14411,13 +14599,13 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } }, @@ -14995,9 +15183,9 @@ } }, "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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" @@ -15022,6 +15210,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -16045,6 +16239,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -16748,9 +16948,9 @@ } }, "node-abort-controller": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-1.2.1.tgz", - "integrity": "sha512-79PYeJuj6S9+yOHirR0JBLFOgjB6sQCir10uN6xRx25iD+ZD4ULqgRn3MwWBRaQGB0vEgReJzWwJo42T1R6YbQ==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", + "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==" }, "node-bitmap": { "version": "0.0.1", @@ -18564,12 +18764,6 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -18860,6 +19054,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 2180b3474..f39c1f9d4 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "_end_microsoft_internal_": 0, "//...": "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ", "dependencies": { - "@azure/cosmos": "3.11.5", + "@azure/cosmos": "3.17.1", "@azure/data-tables": "12.0.0-beta.2", "@azure/identity": "2.0.1", "@azure/keyvault-secrets": "4.3.0", @@ -153,7 +153,7 @@ "@types/validator": "13.7.2", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", From a20ef751911f54cf6faf2d3b6738101625c7d93f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:20:08 +0000 Subject: [PATCH 017/209] Bump typescript from 4.6.3 to 4.8.4 Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.6.3 to 4.8.4. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v4.6.3...v4.8.4) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9ccd4b8e1..606b5e848 100644 --- a/package-lock.json +++ b/package-lock.json @@ -119,7 +119,7 @@ "jest-junit": "13.0.0", "ts-jest": "27.1.4", "ts-node": "10.7.0", - "typescript": "4.6.3" + "typescript": "4.8.4" } }, "node_modules/@ampproject/remapping": { @@ -10153,9 +10153,9 @@ } }, "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -18527,9 +18527,9 @@ } }, "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true }, "uid-safe": { diff --git a/package.json b/package.json index 9355c36f4..1ed147f80 100644 --- a/package.json +++ b/package.json @@ -158,6 +158,6 @@ "jest-junit": "13.0.0", "ts-jest": "27.1.4", "ts-node": "10.7.0", - "typescript": "4.6.3" + "typescript": "4.8.4" } } \ No newline at end of file From 978f4818f8fa195e6b20fb616077810f6205a6d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:20:10 +0000 Subject: [PATCH 018/209] Bump axios from 0.21.4 to 0.27.2 Bumps [axios](https://github.com/axios/axios) from 0.21.4 to 0.27.2. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v0.21.4...v0.27.2) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 20 +++++++++++--------- package.json | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9ccd4b8e1..7e7dc9ff0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "app-root-path": "3.0.0", "applicationinsights": "2.3.1", "async-prompt": "1.0.1", - "axios": "0.26.1", + "axios": "0.27.2", "bad-words": "3.0.4", "basic-auth": "2.0.1", "body-parser": "1.19.2", @@ -3112,11 +3112,12 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "dependencies": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "node_modules/babel-jest": { @@ -13141,11 +13142,12 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "requires": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "babel-jest": { diff --git a/package.json b/package.json index 9355c36f4..1b3ee91e6 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "app-root-path": "3.0.0", "applicationinsights": "2.3.1", "async-prompt": "1.0.1", - "axios": "0.26.1", + "axios": "0.27.2", "bad-words": "3.0.4", "basic-auth": "2.0.1", "body-parser": "1.19.2", From 9127a570a5a27f16b5865bae94ca1d61d405ac63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:20:11 +0000 Subject: [PATCH 019/209] Bump jest-junit from 13.0.0 to 14.0.1 Bumps [jest-junit](https://github.com/jest-community/jest-junit) from 13.0.0 to 14.0.1. - [Release notes](https://github.com/jest-community/jest-junit/releases) - [Commits](https://github.com/jest-community/jest-junit/compare/v13.0.0...v14.0.1) --- updated-dependencies: - dependency-name: jest-junit dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9ccd4b8e1..40205cedb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -116,7 +116,7 @@ "@typescript-eslint/parser": "5.36.2", "eslint": "8.24.0", "jest": "27.5.1", - "jest-junit": "13.0.0", + "jest-junit": "14.0.1", "ts-jest": "27.1.4", "ts-node": "10.7.0", "typescript": "4.6.3" @@ -6771,9 +6771,9 @@ } }, "node_modules/jest-junit": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.0.0.tgz", - "integrity": "sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-14.0.1.tgz", + "integrity": "sha512-h7/wwzPbllgpQhhVcRzRC76/cc89GlazThoV1fDxcALkf26IIlRsu/AcTG64f4nR2WPE3Cbd+i/sVf+NCUHrWQ==", "dev": true, "dependencies": { "mkdirp": "^1.0.4", @@ -15864,9 +15864,9 @@ } }, "jest-junit": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.0.0.tgz", - "integrity": "sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-14.0.1.tgz", + "integrity": "sha512-h7/wwzPbllgpQhhVcRzRC76/cc89GlazThoV1fDxcALkf26IIlRsu/AcTG64f4nR2WPE3Cbd+i/sVf+NCUHrWQ==", "dev": true, "requires": { "mkdirp": "^1.0.4", diff --git a/package.json b/package.json index 9355c36f4..4037e1219 100644 --- a/package.json +++ b/package.json @@ -155,7 +155,7 @@ "@typescript-eslint/parser": "5.36.2", "eslint": "8.24.0", "jest": "27.5.1", - "jest-junit": "13.0.0", + "jest-junit": "14.0.1", "ts-jest": "27.1.4", "ts-node": "10.7.0", "typescript": "4.6.3" From e1a398612c2424e0720083603c61dc219bbb748e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:21:08 +0000 Subject: [PATCH 020/209] Bump @types/validator from 13.7.2 to 13.7.7 Bumps [@types/validator](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/validator) from 13.7.2 to 13.7.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/validator) --- updated-dependencies: - dependency-name: "@types/validator" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 341 +++++++++++++++++++++++++++++++++++----------- package.json | 4 +- 2 files changed, 261 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index add2f6267..0d6d16a55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -111,10 +111,10 @@ "@types/semver": "7.3.9", "@types/simple-oauth2": "4.1.1", "@types/unzipper": "0.10.5", - "@types/validator": "13.7.2", + "@types/validator": "13.7.7", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", @@ -1171,23 +1171,26 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@hapi/boom": { @@ -1227,9 +1230,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1240,6 +1243,29 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -2427,9 +2453,9 @@ } }, "node_modules/@types/validator": { - "version": "13.7.2", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.2.tgz", - "integrity": "sha512-KFcchQ3h0OPQgFirBRPZr5F/sVjxZsOrQHedj3zi8AH3Zv/hOLx2OLR4hxR5HcfoU+33n69ZuOfzthKVdMoTiw==", + "version": "13.7.7", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", + "integrity": "sha512-jiEw2kTUJ8Jsh4A1K4b5Pkjj9Xz6FktLLOQ36ZVLRkmxFbpTvAV2VRoKMojz8UlZxNg/2dZqzpigH4JYn1bkQg==", "dev": true }, "node_modules/@types/yargs": { @@ -2747,9 +2773,9 @@ } }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4690,13 +4716,15 @@ } }, "node_modules/eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4706,30 +4734,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -4826,6 +4856,67 @@ "node": ">=4.0" } }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4842,17 +4933,20 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -5611,9 +5705,9 @@ } }, "node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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, "dependencies": { "type-fest": "^0.20.2" @@ -5650,6 +5744,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -7069,6 +7169,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -10256,12 +10362,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -10640,6 +10740,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -11466,19 +11578,19 @@ } }, "@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, @@ -11519,9 +11631,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -11529,6 +11641,18 @@ "minimatch": "^3.0.4" } }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -12604,9 +12728,9 @@ } }, "@types/validator": { - "version": "13.7.2", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.2.tgz", - "integrity": "sha512-KFcchQ3h0OPQgFirBRPZr5F/sVjxZsOrQHedj3zi8AH3Zv/hOLx2OLR4hxR5HcfoU+33n69ZuOfzthKVdMoTiw==", + "version": "13.7.7", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.7.tgz", + "integrity": "sha512-jiEw2kTUJ8Jsh4A1K4b5Pkjj9Xz6FktLLOQ36ZVLRkmxFbpTvAV2VRoKMojz8UlZxNg/2dZqzpigH4JYn1bkQg==", "dev": true }, "@types/yargs": { @@ -12792,9 +12916,9 @@ } }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "acorn-globals": { @@ -14297,13 +14421,15 @@ } }, "eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -14313,30 +14439,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "cross-spawn": { @@ -14366,6 +14494,43 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -14411,13 +14576,13 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } }, @@ -14995,9 +15160,9 @@ } }, "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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" @@ -15022,6 +15187,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -16045,6 +16216,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -18564,12 +18741,6 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -18860,6 +19031,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 2180b3474..e749f8bd5 100644 --- a/package.json +++ b/package.json @@ -150,10 +150,10 @@ "@types/semver": "7.3.9", "@types/simple-oauth2": "4.1.1", "@types/unzipper": "0.10.5", - "@types/validator": "13.7.2", + "@types/validator": "13.7.7", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", From 9ffa31bee3dce38005782e26cc80fda430888b3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:21:17 +0000 Subject: [PATCH 021/209] Bump @azure/data-tables from 12.0.0-beta.2 to 13.2.0 Bumps [@azure/data-tables](https://github.com/Azure/azure-sdk-for-js) from 12.0.0-beta.2 to 13.2.0. - [Release notes](https://github.com/Azure/azure-sdk-for-js/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md) - [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/data-tables_12.0.0-beta.2...@azure/data-tables_13.2.0) --- updated-dependencies: - dependency-name: "@azure/data-tables" dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 125 ++++++++++++++-------------------------------- package.json | 2 +- 2 files changed, 39 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index 52bda6b28..6bb180014 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@azure/cosmos": "3.17.1", - "@azure/data-tables": "12.0.0-beta.2", + "@azure/data-tables": "13.2.0", "@azure/identity": "3.0.0", "@azure/keyvault-secrets": "4.3.0", "@azure/service-bus": "7.7.1", @@ -298,15 +298,15 @@ } }, "node_modules/@azure/core-xml": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.0.0-beta.1.tgz", - "integrity": "sha512-7d2w0yd8pb1c9aj87JV/1ntOp+sCMcJ9QoGDxs6/7BLDh8Gb6kd2h3n+9JYhcLZO8wdHZb4d4GZgmRIwaAU72w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.0.tgz", + "integrity": "sha512-HYulCHr/3eMDxGubmbm+KIUxpOKPGtRxpaKBN6GpgPDQzREefdQ5bDlTuwHWhtqwyUG4RicKtZu8rhv5Sbg8jQ==", "dependencies": { - "tslib": "^2.0.0", - "xml2js": "^0.4.19" + "fast-xml-parser": "^4.0.8", + "tslib": "^2.2.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/cosmos": { @@ -343,42 +343,33 @@ } }, "node_modules/@azure/data-tables": { - "version": "12.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-12.0.0-beta.2.tgz", - "integrity": "sha512-0bxVa9pTyeKjuLOMx+PGGfEOeY+JH1e1j3GrB7PrrFE8H3yB0RhqCZi5CSqojidgWuhYNK0nh5RG68v3WqQgcg==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-13.2.0.tgz", + "integrity": "sha512-o16WVzcCYuZRh8M43R+twJyB9fZnhG2Y4ZfGmV2jX3HgV7TSBIXysuwgVYkdqYd3cyBVzpHW3pLY7IasOjvO7w==", "dependencies": { + "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.0.0", - "@azure/core-tracing": "1.0.0-preview.11", - "@azure/core-xml": "1.0.0-beta.1", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-xml": "^1.0.0", "@azure/logger": "^1.0.0", - "tslib": "^2.0.0", + "tslib": "^2.2.0", "uuid": "^8.3.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/data-tables/node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.11", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.11.tgz", - "integrity": "sha512-frF0pJc9HTmKncVokhBxCqipjbql02DThQ1ZJ9wLi7SDMLdPAFyDI5xZNzX5guLz+/DtPkY+SGK2li9FIXqshQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", "dependencies": { - "@opencensus/web-types": "0.0.7", - "@opentelemetry/api": "1.0.0-rc.0", - "tslib": "^2.0.0" + "tslib": "^2.2.0" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@azure/data-tables/node_modules/@opentelemetry/api": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.0-rc.0.tgz", - "integrity": "sha512-iXKByCMfrlO5S6Oh97BuM56tM2cIBB0XsL/vWF/AtJrJEKx4MC/Xdu0xDsGXMGcNWpqF7ujMsjjnp0+UHBwnDQ==", - "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/identity": { @@ -517,18 +508,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/service-bus/node_modules/@azure/core-xml": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.0.tgz", - "integrity": "sha512-HYulCHr/3eMDxGubmbm+KIUxpOKPGtRxpaKBN6GpgPDQzREefdQ5bDlTuwHWhtqwyUG4RicKtZu8rhv5Sbg8jQ==", - "dependencies": { - "fast-xml-parser": "^4.0.8", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/storage-blob": { "version": "12.8.0", "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.8.0.tgz", @@ -1813,14 +1792,6 @@ "@octokit/openapi-types": "^11.2.0" } }, - "node_modules/@opencensus/web-types": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@opencensus/web-types/-/web-types-0.0.7.tgz", - "integrity": "sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g==", - "engines": { - "node": ">=6.0" - } - }, "node_modules/@opentelemetry/api": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz", @@ -10880,12 +10851,12 @@ } }, "@azure/core-xml": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.0.0-beta.1.tgz", - "integrity": "sha512-7d2w0yd8pb1c9aj87JV/1ntOp+sCMcJ9QoGDxs6/7BLDh8Gb6kd2h3n+9JYhcLZO8wdHZb4d4GZgmRIwaAU72w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.0.tgz", + "integrity": "sha512-HYulCHr/3eMDxGubmbm+KIUxpOKPGtRxpaKBN6GpgPDQzREefdQ5bDlTuwHWhtqwyUG4RicKtZu8rhv5Sbg8jQ==", "requires": { - "tslib": "^2.0.0", - "xml2js": "^0.4.19" + "fast-xml-parser": "^4.0.8", + "tslib": "^2.2.0" } }, "@azure/cosmos": { @@ -10918,34 +10889,28 @@ } }, "@azure/data-tables": { - "version": "12.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-12.0.0-beta.2.tgz", - "integrity": "sha512-0bxVa9pTyeKjuLOMx+PGGfEOeY+JH1e1j3GrB7PrrFE8H3yB0RhqCZi5CSqojidgWuhYNK0nh5RG68v3WqQgcg==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-13.2.0.tgz", + "integrity": "sha512-o16WVzcCYuZRh8M43R+twJyB9fZnhG2Y4ZfGmV2jX3HgV7TSBIXysuwgVYkdqYd3cyBVzpHW3pLY7IasOjvO7w==", "requires": { + "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.0.0", - "@azure/core-tracing": "1.0.0-preview.11", - "@azure/core-xml": "1.0.0-beta.1", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-xml": "^1.0.0", "@azure/logger": "^1.0.0", - "tslib": "^2.0.0", + "tslib": "^2.2.0", "uuid": "^8.3.0" }, "dependencies": { "@azure/core-tracing": { - "version": "1.0.0-preview.11", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.11.tgz", - "integrity": "sha512-frF0pJc9HTmKncVokhBxCqipjbql02DThQ1ZJ9wLi7SDMLdPAFyDI5xZNzX5guLz+/DtPkY+SGK2li9FIXqshQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", "requires": { - "@opencensus/web-types": "0.0.7", - "@opentelemetry/api": "1.0.0-rc.0", - "tslib": "^2.0.0" + "tslib": "^2.2.0" } - }, - "@opentelemetry/api": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.0-rc.0.tgz", - "integrity": "sha512-iXKByCMfrlO5S6Oh97BuM56tM2cIBB0XsL/vWF/AtJrJEKx4MC/Xdu0xDsGXMGcNWpqF7ujMsjjnp0+UHBwnDQ==" } } }, @@ -11059,15 +11024,6 @@ "requires": { "tslib": "^2.2.0" } - }, - "@azure/core-xml": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.0.tgz", - "integrity": "sha512-HYulCHr/3eMDxGubmbm+KIUxpOKPGtRxpaKBN6GpgPDQzREefdQ5bDlTuwHWhtqwyUG4RicKtZu8rhv5Sbg8jQ==", - "requires": { - "fast-xml-parser": "^4.0.8", - "tslib": "^2.2.0" - } } } }, @@ -12106,11 +12062,6 @@ "@octokit/openapi-types": "^11.2.0" } }, - "@opencensus/web-types": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@opencensus/web-types/-/web-types-0.0.7.tgz", - "integrity": "sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g==" - }, "@opentelemetry/api": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz", diff --git a/package.json b/package.json index e41d33727..87026efd2 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "//...": "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ", "dependencies": { "@azure/cosmos": "3.17.1", - "@azure/data-tables": "12.0.0-beta.2", + "@azure/data-tables": "13.2.0", "@azure/identity": "3.0.0", "@azure/keyvault-secrets": "4.3.0", "@azure/service-bus": "7.7.1", From 1ef77de5b6d33ac83a857bd914909fbf856bb531 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:21:24 +0000 Subject: [PATCH 022/209] Bump moment from 2.29.1 to 2.29.4 Bumps [moment](https://github.com/moment/moment) from 2.29.1 to 2.29.4. - [Release notes](https://github.com/moment/moment/releases) - [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md) - [Commits](https://github.com/moment/moment/compare/2.29.1...2.29.4) --- updated-dependencies: - dependency-name: moment dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 341 +++++++++++++++++++++++++++++++++++----------- package.json | 4 +- 2 files changed, 261 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index add2f6267..828b30d11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,7 @@ "lodash": "4.17.21", "luxon": "2.3.1", "memory-cache": "0.2.0", - "moment": "2.29.1", + "moment": "2.29.4", "morgan": "1.10.0", "multer": "1.4.4", "node-jose": "2.1.0", @@ -114,7 +114,7 @@ "@types/validator": "13.7.2", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", @@ -1171,23 +1171,26 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@hapi/boom": { @@ -1227,9 +1230,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1240,6 +1243,29 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -2747,9 +2773,9 @@ } }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4690,13 +4716,15 @@ } }, "node_modules/eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4706,30 +4734,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -4826,6 +4856,67 @@ "node": ">=4.0" } }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4842,17 +4933,20 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -5611,9 +5705,9 @@ } }, "node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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, "dependencies": { "type-fest": "^0.20.2" @@ -5650,6 +5744,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -7069,6 +7169,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -7711,9 +7817,9 @@ } }, "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", "engines": { "node": "*" } @@ -10256,12 +10362,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -10640,6 +10740,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -11466,19 +11578,19 @@ } }, "@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, @@ -11519,9 +11631,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -11529,6 +11641,18 @@ "minimatch": "^3.0.4" } }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -12792,9 +12916,9 @@ } }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "acorn-globals": { @@ -14297,13 +14421,15 @@ } }, "eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -14313,30 +14439,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "cross-spawn": { @@ -14366,6 +14494,43 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -14411,13 +14576,13 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } }, @@ -14995,9 +15160,9 @@ } }, "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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" @@ -15022,6 +15187,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -16045,6 +16216,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -16580,9 +16757,9 @@ "dev": true }, "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "morgan": { "version": "1.10.0", @@ -18564,12 +18741,6 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -18860,6 +19031,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 2180b3474..69f86542d 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "lodash": "4.17.21", "luxon": "2.3.1", "memory-cache": "0.2.0", - "moment": "2.29.1", + "moment": "2.29.4", "morgan": "1.10.0", "multer": "1.4.4", "node-jose": "2.1.0", @@ -153,7 +153,7 @@ "@types/validator": "13.7.2", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", From c3421071f1806de4b4736863af009f43f0902f43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:22:14 +0000 Subject: [PATCH 023/209] Bump jwks-rsa from 2.0.4 to 2.1.4 Bumps [jwks-rsa](https://github.com/auth0/node-jwks-rsa) from 2.0.4 to 2.1.4. - [Release notes](https://github.com/auth0/node-jwks-rsa/releases) - [Changelog](https://github.com/auth0/node-jwks-rsa/blob/master/CHANGELOG.md) - [Commits](https://github.com/auth0/node-jwks-rsa/compare/2.0.4...v2.1.4) --- updated-dependencies: - dependency-name: jwks-rsa dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 58 +++++++++++------------------------------------ package.json | 2 +- 2 files changed, 14 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7765d7e8a..23994fe2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "js-yaml": "4.1.0", "jsonc": "2.0.0", "jsonwebtoken": "8.5.1", - "jwks-rsa": "2.0.5", + "jwks-rsa": "2.1.4", "language-map": "1.5.0", "lodash": "4.17.21", "luxon": "3.0.3", @@ -2048,15 +2048,6 @@ "@types/serve-static": "*" } }, - "node_modules/@types/express-jwt": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", - "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", - "dependencies": { - "@types/express": "*", - "@types/express-unless": "*" - } - }, "node_modules/@types/express-serve-static-core": { "version": "4.17.28", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", @@ -2076,14 +2067,6 @@ "@types/express": "*" } }, - "node_modules/@types/express-unless": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.3.tgz", - "integrity": "sha512-TyPLQaF6w8UlWdv4gj8i46B+INBVzURBNRahCozCSXfsK2VTlL1wNyTlMKw817VHygBtlcl5jfnPadlydr06Yw==", - "dependencies": { - "@types/express": "*" - } - }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -7408,12 +7391,13 @@ } }, "node_modules/jwks-rsa": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.5.tgz", - "integrity": "sha512-fliHfsiBRzEU0nXzSvwnh0hynzGB0WihF+CinKbSRlaqRxbqqKf2xbBPgwc8mzf18/WgwlG8e5eTpfSTBcU4DQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.1.4.tgz", + "integrity": "sha512-mpArfgPkUpX11lNtGxsF/szkasUcbWHGplZl/uFvFO2NuMHmt0dQXIihh0rkPU2yQd5niQtuUHbXnG/WKiXF6Q==", "dependencies": { - "@types/express-jwt": "0.0.42", - "debug": "^4.3.2", + "@types/express": "^4.17.13", + "@types/jsonwebtoken": "^8.5.8", + "debug": "^4.3.4", "jose": "^2.0.5", "limiter": "^1.1.5", "lru-memoizer": "^2.1.4" @@ -12290,15 +12274,6 @@ "@types/serve-static": "*" } }, - "@types/express-jwt": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", - "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", - "requires": { - "@types/express": "*", - "@types/express-unless": "*" - } - }, "@types/express-serve-static-core": { "version": "4.17.28", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", @@ -12318,14 +12293,6 @@ "@types/express": "*" } }, - "@types/express-unless": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.3.tgz", - "integrity": "sha512-TyPLQaF6w8UlWdv4gj8i46B+INBVzURBNRahCozCSXfsK2VTlL1wNyTlMKw817VHygBtlcl5jfnPadlydr06Yw==", - "requires": { - "@types/express": "*" - } - }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -16375,12 +16342,13 @@ } }, "jwks-rsa": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.5.tgz", - "integrity": "sha512-fliHfsiBRzEU0nXzSvwnh0hynzGB0WihF+CinKbSRlaqRxbqqKf2xbBPgwc8mzf18/WgwlG8e5eTpfSTBcU4DQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.1.4.tgz", + "integrity": "sha512-mpArfgPkUpX11lNtGxsF/szkasUcbWHGplZl/uFvFO2NuMHmt0dQXIihh0rkPU2yQd5niQtuUHbXnG/WKiXF6Q==", "requires": { - "@types/express-jwt": "0.0.42", - "debug": "^4.3.2", + "@types/express": "^4.17.13", + "@types/jsonwebtoken": "^8.5.8", + "debug": "^4.3.4", "jose": "^2.0.5", "limiter": "^1.1.5", "lru-memoizer": "^2.1.4" diff --git a/package.json b/package.json index b6b893ade..9fbe8d145 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "js-yaml": "4.1.0", "jsonc": "2.0.0", "jsonwebtoken": "8.5.1", - "jwks-rsa": "2.0.5", + "jwks-rsa": "2.1.4", "language-map": "1.5.0", "lodash": "4.17.21", "luxon": "3.0.3", From ec007c4a0fdcdeceddb85a50973eae318725b323 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:22:16 +0000 Subject: [PATCH 024/209] Bump ts-node from 10.7.0 to 10.9.1 Bumps [ts-node](https://github.com/TypeStrong/ts-node) from 10.7.0 to 10.9.1. - [Release notes](https://github.com/TypeStrong/ts-node/releases) - [Changelog](https://github.com/TypeStrong/ts-node/blob/main/development-docs/release-template.md) - [Commits](https://github.com/TypeStrong/ts-node/compare/v10.7.0...v10.9.1) --- updated-dependencies: - dependency-name: ts-node dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 77 +++++++++++++++++++---------------------------- package.json | 2 +- 2 files changed, 32 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7765d7e8a..df5202114 100644 --- a/package-lock.json +++ b/package-lock.json @@ -118,7 +118,7 @@ "jest": "27.5.1", "jest-junit": "14.0.1", "ts-jest": "27.1.4", - "ts-node": "10.7.0", + "ts-node": "10.9.1", "typescript": "4.8.4" } }, @@ -1121,22 +1121,13 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { "node": ">=12" @@ -1556,9 +1547,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -9975,12 +9966,12 @@ } }, "node_modules/ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "dependencies": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -9991,7 +9982,7 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "bin": { @@ -10319,9 +10310,9 @@ } }, "node_modules/v8-compile-cache-lib": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "node_modules/v8-to-istanbul": { @@ -11496,19 +11487,13 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "requires": { - "@cspotcode/source-map-consumer": "0.8.0" + "@jridgewell/trace-mapping": "0.3.9" } }, "@eslint/eslintrc": { @@ -11843,9 +11828,9 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", @@ -18388,12 +18373,12 @@ } }, "ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -18404,7 +18389,7 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "dependencies": { @@ -18663,9 +18648,9 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache-lib": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "v8-to-istanbul": { diff --git a/package.json b/package.json index b6b893ade..aeadce7ef 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,7 @@ "jest": "27.5.1", "jest-junit": "14.0.1", "ts-jest": "27.1.4", - "ts-node": "10.7.0", + "ts-node": "10.9.1", "typescript": "4.8.4" } } \ No newline at end of file From 128c9faa0e9f85b7fa88ee0770baa083d326a398 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:22:50 +0000 Subject: [PATCH 025/209] Bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/container.yml | 2 +- .github/workflows/main_nihgithubportal.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7d603d128..597f7d3a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Node uses: actions/setup-node@v3 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 13d66ad2c..3b2ee72a2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index a36751d0c..f800d71d5 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -12,5 +12,5 @@ jobs: runs-on: ubuntu-latest steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: docker/build-push-action@v3 diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 78f78da85..13e1e3520 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Node.js version uses: actions/setup-node@v3 From 19ca6fa0e243d0b1154c91a6fd51318eeddc794b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:23:00 +0000 Subject: [PATCH 026/209] Bump passport from 0.5.2 to 0.6.0 Bumps [passport](https://github.com/jaredhanson/passport) from 0.5.2 to 0.6.0. - [Release notes](https://github.com/jaredhanson/passport/releases) - [Changelog](https://github.com/jaredhanson/passport/blob/master/CHANGELOG.md) - [Commits](https://github.com/jaredhanson/passport/compare/v0.5.2...v0.6.0) --- updated-dependencies: - dependency-name: passport dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 347 +++++++++++++++++++++++++++++++++++----------- package.json | 4 +- 2 files changed, 265 insertions(+), 86 deletions(-) diff --git a/package-lock.json b/package-lock.json index add2f6267..7b2e694c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "octicons": "5.0.1", "package-lock.json": "1.0.0", "pascal-case": "3.1.2", - "passport": "0.5.2", + "passport": "0.6.0", "passport-azure-ad": "4.3.1", "passport-github": "1.1.0", "passport-strategy": "1.x.x", @@ -114,7 +114,7 @@ "@types/validator": "13.7.2", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", @@ -1171,23 +1171,26 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@hapi/boom": { @@ -1227,9 +1230,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1240,6 +1243,29 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -2747,9 +2773,9 @@ } }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4690,13 +4716,15 @@ } }, "node_modules/eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4706,30 +4734,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -4826,6 +4856,67 @@ "node": ">=4.0" } }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4842,17 +4933,20 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -5611,9 +5705,9 @@ } }, "node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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, "dependencies": { "type-fest": "^0.20.2" @@ -5650,6 +5744,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -7069,6 +7169,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -8311,12 +8417,13 @@ } }, "node_modules/passport": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.2.tgz", - "integrity": "sha512-w9n/Ot5I7orGD4y+7V3EFJCQEznE5RxHamUxcqLT2QoJY0f2JdN8GyHonYFvN0Vz+L6lUJfVhrk2aZz2LbuREw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", + "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", "dependencies": { "passport-strategy": "1.x.x", - "pause": "0.0.1" + "pause": "0.0.1", + "utils-merge": "^1.0.1" }, "engines": { "node": ">= 0.4.0" @@ -10256,12 +10363,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -10640,6 +10741,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -11466,19 +11579,19 @@ } }, "@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.4.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, @@ -11519,9 +11632,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", + "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -11529,6 +11642,18 @@ "minimatch": "^3.0.4" } }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -12792,9 +12917,9 @@ } }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "acorn-globals": { @@ -14297,13 +14422,15 @@ } }, "eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", - "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -14313,30 +14440,32 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", + "find-up": "^5.0.0", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "cross-spawn": { @@ -14366,6 +14495,43 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -14411,13 +14577,13 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } }, @@ -14995,9 +15161,9 @@ } }, "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "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" @@ -15022,6 +15188,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -16045,6 +16217,12 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -17059,12 +17237,13 @@ } }, "passport": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.2.tgz", - "integrity": "sha512-w9n/Ot5I7orGD4y+7V3EFJCQEznE5RxHamUxcqLT2QoJY0f2JdN8GyHonYFvN0Vz+L6lUJfVhrk2aZz2LbuREw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", + "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", "requires": { "passport-strategy": "1.x.x", - "pause": "0.0.1" + "pause": "0.0.1", + "utils-merge": "^1.0.1" } }, "passport-azure-ad": { @@ -18564,12 +18743,6 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", @@ -18860,6 +19033,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 2180b3474..625121fe8 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "octicons": "5.0.1", "package-lock.json": "1.0.0", "pascal-case": "3.1.2", - "passport": "0.5.2", + "passport": "0.6.0", "passport-azure-ad": "4.3.1", "passport-github": "1.1.0", "passport-strategy": "1.x.x", @@ -153,7 +153,7 @@ "@types/validator": "13.7.2", "@typescript-eslint/eslint-plugin": "5.17.0", "@typescript-eslint/parser": "5.36.2", - "eslint": "8.11.0", + "eslint": "8.24.0", "jest": "27.5.1", "jest-junit": "13.0.0", "ts-jest": "27.1.4", From a31a8f2b0593d86c644454c1ebfb144be3e4b357 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:23:15 +0000 Subject: [PATCH 027/209] Bump @azure/keyvault-secrets from 4.3.0 to 4.6.0 Bumps [@azure/keyvault-secrets](https://github.com/Azure/azure-sdk-for-js) from 4.3.0 to 4.6.0. - [Release notes](https://github.com/Azure/azure-sdk-for-js/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md) - [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/keyvault-secrets_4.3.0...@azure/keyvault-secrets_4.6.0) --- updated-dependencies: - dependency-name: "@azure/keyvault-secrets" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 78 +++++++++++++++++++++++++++++++++++++++-------- package.json | 2 +- 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1af5ea486..34ac21589 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@azure/cosmos": "3.17.1", "@azure/data-tables": "13.2.0", "@azure/identity": "3.0.0", - "@azure/keyvault-secrets": "4.3.0", + "@azure/keyvault-secrets": "4.6.0", "@azure/service-bus": "7.7.1", "@azure/storage-blob": "12.8.0", "@azure/storage-file-share": "12.8.0", @@ -229,6 +229,19 @@ "node": ">=12.0.0" } }, + "node_modules/@azure/core-http-compat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-1.3.0.tgz", + "integrity": "sha512-ZN9avruqbQ5TxopzG3ih3KRy52n8OAbitX3fnZT5go4hzu0J+KVPSzkL+Wt3hpJpdG8WIfg1sBD1tWkgUdEpBA==", + "dependencies": { + "@azure/abort-controller": "^1.0.4", + "@azure/core-client": "^1.3.0", + "@azure/core-rest-pipeline": "^1.3.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/core-lro": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.4.tgz", @@ -410,15 +423,19 @@ } }, "node_modules/@azure/keyvault-secrets": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.3.0.tgz", - "integrity": "sha512-bhdAr2Yjx+XpgfkClOufpTxcnKqDIwyOSKrbI9mJ2q5wQNb7Z1WPnPnIhjdsw1on/NRXzMaarYFNkf/MdS73FA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.6.0.tgz", + "integrity": "sha512-MDqsyODCGC2srqLKmO6MFw9WdgLrbPsfCNxgbekHXEd6XKM6KKyBlup5joj96EmdfZnXDFriecAIpj0Dtu81RQ==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-http": "^2.0.0", - "@azure/core-lro": "^2.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.5.0", + "@azure/core-http-compat": "^1.3.0", + "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.1.1", - "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-rest-pipeline": "^1.8.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", "tslib": "^2.2.0" }, @@ -426,6 +443,17 @@ "node": ">=12.0.0" } }, + "node_modules/@azure/keyvault-secrets/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/logger": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", @@ -10798,6 +10826,16 @@ "xml2js": "^0.4.19" } }, + "@azure/core-http-compat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-1.3.0.tgz", + "integrity": "sha512-ZN9avruqbQ5TxopzG3ih3KRy52n8OAbitX3fnZT5go4hzu0J+KVPSzkL+Wt3hpJpdG8WIfg1sBD1tWkgUdEpBA==", + "requires": { + "@azure/abort-controller": "^1.0.4", + "@azure/core-client": "^1.3.0", + "@azure/core-rest-pipeline": "^1.3.0" + } + }, "@azure/core-lro": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.4.tgz", @@ -10949,17 +10987,31 @@ } }, "@azure/keyvault-secrets": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.3.0.tgz", - "integrity": "sha512-bhdAr2Yjx+XpgfkClOufpTxcnKqDIwyOSKrbI9mJ2q5wQNb7Z1WPnPnIhjdsw1on/NRXzMaarYFNkf/MdS73FA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.6.0.tgz", + "integrity": "sha512-MDqsyODCGC2srqLKmO6MFw9WdgLrbPsfCNxgbekHXEd6XKM6KKyBlup5joj96EmdfZnXDFriecAIpj0Dtu81RQ==", "requires": { "@azure/abort-controller": "^1.0.0", - "@azure/core-http": "^2.0.0", - "@azure/core-lro": "^2.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.5.0", + "@azure/core-http-compat": "^1.3.0", + "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.1.1", - "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-rest-pipeline": "^1.8.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "requires": { + "tslib": "^2.2.0" + } + } } }, "@azure/logger": { diff --git a/package.json b/package.json index 3a22a3e0d..5c7a7938e 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@azure/cosmos": "3.17.1", "@azure/data-tables": "13.2.0", "@azure/identity": "3.0.0", - "@azure/keyvault-secrets": "4.3.0", + "@azure/keyvault-secrets": "4.6.0", "@azure/service-bus": "7.7.1", "@azure/storage-blob": "12.8.0", "@azure/storage-file-share": "12.8.0", From a05d887b3caee9dde3a544bad201de786c7ee64f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:23:48 +0000 Subject: [PATCH 028/209] Bump body-parser from 1.19.2 to 1.20.0 Bumps [body-parser](https://github.com/expressjs/body-parser) from 1.19.2 to 1.20.0. - [Release notes](https://github.com/expressjs/body-parser/releases) - [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/body-parser/compare/1.19.2...1.20.0) --- updated-dependencies: - dependency-name: body-parser dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 286 +++++++++++++++++++++++++++++++++++++++++----- package.json | 2 +- 2 files changed, 259 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index ee8b3b3f4..08e4af0fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "axios": "0.27.2", "bad-words": "3.0.4", "basic-auth": "2.0.1", - "body-parser": "1.19.2", + "body-parser": "1.20.0", "cheerio": "1.0.0-rc.10", "child-process-promise": "2.2.1", "color-contrast-checker": "2.1.0", @@ -3287,23 +3287,26 @@ "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" }, "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/body-parser/node_modules/debug": { @@ -3314,11 +3317,76 @@ "ms": "2.0.0" } }, + "node_modules/body-parser/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "node_modules/body-parser/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/body-parser/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -5170,6 +5238,26 @@ "resolved": "https://registry.npmjs.org/express-sslify/-/express-sslify-1.2.0.tgz", "integrity": "sha1-MOhLzu0VV+sYdnK74UMKCioQDZw=" }, + "node_modules/express/node_modules/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5183,6 +5271,20 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "node_modules/express/node_modules/raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -8975,12 +9077,12 @@ } }, "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -8988,6 +9090,37 @@ "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -13239,20 +13372,22 @@ "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" }, "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "dependencies": { "debug": { @@ -13263,10 +13398,53 @@ "ms": "2.0.0" } }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" } } }, @@ -14632,6 +14810,23 @@ "vary": "~1.1.2" }, "dependencies": { + "body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -14645,6 +14840,17 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "requires": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -17607,14 +17813,38 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "requires": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + } } }, "react-is": { diff --git a/package.json b/package.json index 5e07d0c0f..1e0b75d49 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "axios": "0.27.2", "bad-words": "3.0.4", "basic-auth": "2.0.1", - "body-parser": "1.19.2", + "body-parser": "1.20.0", "cheerio": "1.0.0-rc.10", "child-process-promise": "2.2.1", "color-contrast-checker": "2.1.0", From 9b8c7ec522891399837f67459df9fa6a6602117c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:23:48 +0000 Subject: [PATCH 029/209] Bump express-session and @types/express-session Bumps [express-session](https://github.com/expressjs/session) and [@types/express-session](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/express-session). These dependencies needed to be updated together. Updates `express-session` from 1.17.2 to 1.17.3 - [Release notes](https://github.com/expressjs/session/releases) - [Changelog](https://github.com/expressjs/session/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/session/compare/v1.17.2...v1.17.3) Updates `@types/express-session` from 1.17.4 to 1.17.5 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/express-session) --- updated-dependencies: - dependency-name: express-session dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: "@types/express-session" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 45 ++++++++++++++++----------------------------- package.json | 4 ++-- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1af5ea486..087894b5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "dotenv": "10.0.0", "express": "4.17.3", "express-async-handler": "1.2.0", - "express-session": "1.17.2", + "express-session": "1.17.3", "express-sslify": "1.2.0", "file-size": "1.0.0", "get-pixels": "3.3.3", @@ -90,7 +90,7 @@ "@types/core-js": "2.5.5", "@types/debug": "4.1.7", "@types/express": "4.17.13", - "@types/express-session": "1.17.4", + "@types/express-session": "1.17.5", "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", "@types/lodash": "4.14.180", @@ -2068,9 +2068,9 @@ } }, "node_modules/@types/express-session": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.4.tgz", - "integrity": "sha512-7cNlSI8+oOBUHTfPXMwDxF/Lchx5aJ3ho7+p9jJZYVg9dVDJFh3qdMXmJtRsysnvS+C6x46k9DRYmrmCkE+MVg==", + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.5.tgz", + "integrity": "sha512-l0DhkvNVfyUPEEis8fcwbd46VptfA/jmMwHfob2TfDMf3HyPLiB9mKD71LXhz5TMUobODXPD27zXSwtFQLHm+w==", "dev": true, "dependencies": { "@types/express": "*" @@ -5117,11 +5117,11 @@ "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" }, "node_modules/express-session": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", - "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", "dependencies": { - "cookie": "0.4.1", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", @@ -5134,14 +5134,6 @@ "node": ">= 0.8.0" } }, - "node_modules/express-session/node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/express-session/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -12311,9 +12303,9 @@ } }, "@types/express-session": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.4.tgz", - "integrity": "sha512-7cNlSI8+oOBUHTfPXMwDxF/Lchx5aJ3ho7+p9jJZYVg9dVDJFh3qdMXmJtRsysnvS+C6x46k9DRYmrmCkE+MVg==", + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.5.tgz", + "integrity": "sha512-l0DhkvNVfyUPEEis8fcwbd46VptfA/jmMwHfob2TfDMf3HyPLiB9mKD71LXhz5TMUobODXPD27zXSwtFQLHm+w==", "dev": true, "requires": { "@types/express": "*" @@ -14691,11 +14683,11 @@ "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" }, "express-session": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", - "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", "requires": { - "cookie": "0.4.1", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", @@ -14705,11 +14697,6 @@ "uid-safe": "~2.1.5" }, "dependencies": { - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", diff --git a/package.json b/package.json index 3a22a3e0d..a6acd3233 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "dotenv": "10.0.0", "express": "4.17.3", "express-async-handler": "1.2.0", - "express-session": "1.17.2", + "express-session": "1.17.3", "express-sslify": "1.2.0", "file-size": "1.0.0", "get-pixels": "3.3.3", @@ -129,7 +129,7 @@ "@types/core-js": "2.5.5", "@types/debug": "4.1.7", "@types/express": "4.17.13", - "@types/express-session": "1.17.4", + "@types/express-session": "1.17.5", "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", "@types/lodash": "4.14.180", From a782bee7d6efa0840a4fe9ae3ded3181b5071dc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:25:03 +0000 Subject: [PATCH 030/209] Bump @azure/storage-file-share from 12.8.0 to 12.11.0 Bumps [@azure/storage-file-share](https://github.com/Azure/azure-sdk-for-js) from 12.8.0 to 12.11.0. - [Release notes](https://github.com/Azure/azure-sdk-for-js/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md) - [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/storage-file-share_12.8.0...@azure/storage-file-share_12.11.0) --- updated-dependencies: - dependency-name: "@azure/storage-file-share" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index e9659bd3c..dea64de3d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@azure/keyvault-secrets": "4.6.0", "@azure/service-bus": "7.7.1", "@azure/storage-blob": "12.8.0", - "@azure/storage-file-share": "12.8.0", + "@azure/storage-file-share": "12.11.0", "@azure/storage-queue": "12.7.0", "@octokit/auth-app": "3.6.1", "@octokit/rest": "18.12.0", @@ -555,9 +555,9 @@ } }, "node_modules/@azure/storage-file-share": { - "version": "12.8.0", - "resolved": "https://registry.npmjs.org/@azure/storage-file-share/-/storage-file-share-12.8.0.tgz", - "integrity": "sha512-SAX8rsEiQYwRMe1D6fNN4TlOgpEVNCfbe201ewbLNsJjOrx/n2CSsRRg46MbOVdaJbuOontiQeJx4KcCS7CWBg==", + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@azure/storage-file-share/-/storage-file-share-12.11.0.tgz", + "integrity": "sha512-0gJkJF4nvIpDjDZubI7hRS7ACf3H7USr0oJhxa7PjMx+LSd6oIQIFMYjnDWasAgYivRPHqCNS6gbuXv3qzcfzA==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^2.0.0", @@ -11213,9 +11213,9 @@ } }, "@azure/storage-file-share": { - "version": "12.8.0", - "resolved": "https://registry.npmjs.org/@azure/storage-file-share/-/storage-file-share-12.8.0.tgz", - "integrity": "sha512-SAX8rsEiQYwRMe1D6fNN4TlOgpEVNCfbe201ewbLNsJjOrx/n2CSsRRg46MbOVdaJbuOontiQeJx4KcCS7CWBg==", + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@azure/storage-file-share/-/storage-file-share-12.11.0.tgz", + "integrity": "sha512-0gJkJF4nvIpDjDZubI7hRS7ACf3H7USr0oJhxa7PjMx+LSd6oIQIFMYjnDWasAgYivRPHqCNS6gbuXv3qzcfzA==", "requires": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^2.0.0", diff --git a/package.json b/package.json index 1f40a160e..22594088b 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@azure/keyvault-secrets": "4.6.0", "@azure/service-bus": "7.7.1", "@azure/storage-blob": "12.8.0", - "@azure/storage-file-share": "12.8.0", + "@azure/storage-file-share": "12.11.0", "@azure/storage-queue": "12.7.0", "@octokit/auth-app": "3.6.1", "@octokit/rest": "18.12.0", From e21c14acb2f4411105ba776911f59681b01efc0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 17:25:59 +0000 Subject: [PATCH 031/209] Bump express and @types/express Bumps [express](https://github.com/expressjs/express) and [@types/express](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/express). These dependencies needed to be updated together. Updates `express` from 4.17.3 to 4.18.1 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.17.3...4.18.1) Updates `@types/express` from 4.17.13 to 4.17.14 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/express) --- updated-dependencies: - dependency-name: express dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: "@types/express" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 529 ++++++++++++++++------------------------------ package.json | 4 +- 2 files changed, 184 insertions(+), 349 deletions(-) diff --git a/package-lock.json b/package-lock.json index 93334cb72..9f8bacb49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "debug": "4.3.4", "deepmerge": "4.2.2", "dotenv": "10.0.0", - "express": "4.17.3", + "express": "4.18.1", "express-async-handler": "1.2.0", "express-session": "1.17.3", "express-sslify": "1.2.0", @@ -89,7 +89,7 @@ "@types/connect-redis": "0.0.18", "@types/core-js": "2.5.5", "@types/debug": "4.1.7", - "@types/express": "4.17.13", + "@types/express": "4.17.14", "@types/express-session": "1.17.5", "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", @@ -2066,9 +2066,9 @@ } }, "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -3345,38 +3345,6 @@ "ms": "2.0.0" } }, - "node_modules/body-parser/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3393,28 +3361,6 @@ "node": ">= 0.8" } }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/body-parser/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -4274,11 +4220,11 @@ } }, "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/deprecation": { @@ -4287,9 +4233,13 @@ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" }, "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, "node_modules/detect-newline": { "version": "3.1.0", @@ -4568,7 +4518,7 @@ "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } @@ -4655,7 +4605,7 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -5151,37 +5101,38 @@ } }, "node_modules/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.2", + "body-parser": "1.20.0", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.2", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.7", + "qs": "6.10.3", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -5221,14 +5172,6 @@ "ms": "2.0.0" } }, - "node_modules/express-session/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express-session/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5258,24 +5201,12 @@ "resolved": "https://registry.npmjs.org/express-sslify/-/express-sslify-1.2.0.tgz", "integrity": "sha1-MOhLzu0VV+sYdnK74UMKCioQDZw=" }, - "node_modules/express/node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" - }, + "node_modules/express/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/express/node_modules/debug": { @@ -5289,17 +5220,14 @@ "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/express/node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "node_modules/express/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { - "bytes": "3.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" @@ -5449,16 +5377,16 @@ } }, "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { @@ -5476,7 +5404,18 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, "node_modules/find-up": { "version": "4.1.0", @@ -5897,14 +5836,6 @@ "node": ">=4.0.0" } }, - "node_modules/hsts/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -5942,18 +5873,18 @@ } }, "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/http-proxy-agent": { @@ -7910,14 +7841,6 @@ "ms": "2.0.0" } }, - "node_modules/morgan/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/morgan/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -9041,9 +8964,12 @@ } }, "node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" }, @@ -9110,37 +9036,6 @@ "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -9521,23 +9416,23 @@ } }, "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" @@ -9554,13 +9449,24 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/send/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/serve-favicon": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", @@ -9587,14 +9493,14 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" @@ -9765,11 +9671,11 @@ } }, "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/stoppable": { @@ -12442,9 +12348,9 @@ } }, "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", "requires": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -13442,28 +13348,6 @@ "ms": "2.0.0" } }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -13476,19 +13360,6 @@ "requires": { "ee-first": "1.1.1" } - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" } } }, @@ -14161,9 +14032,9 @@ "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "deprecation": { "version": "2.3.1", @@ -14171,9 +14042,9 @@ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "detect-newline": { "version": "3.1.0", @@ -14398,7 +14269,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "entities": { "version": "2.2.0", @@ -14464,7 +14335,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "4.0.0", @@ -14818,58 +14689,47 @@ } }, "express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.2", + "body-parser": "1.20.0", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.2", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.7", + "qs": "6.10.3", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { - "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" - } + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, "debug": { "version": "2.6.9", @@ -14882,17 +14742,14 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "requires": { - "bytes": "3.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "ee-first": "1.1.1" } }, "safe-buffer": { @@ -14930,11 +14787,6 @@ "ms": "2.0.0" } }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -15057,16 +14909,16 @@ } }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "dependencies": { @@ -15081,7 +14933,15 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } } } }, @@ -15380,13 +15240,6 @@ "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", "requires": { "depd": "2.0.0" - }, - "dependencies": { - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - } } }, "html-encoding-sniffer": { @@ -15416,14 +15269,14 @@ } }, "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "requires": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" } }, @@ -16917,11 +16770,6 @@ "ms": "2.0.0" } }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -17826,9 +17674,12 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "requires": { + "side-channel": "^1.0.4" + } }, "querystring": { "version": "0.2.0", @@ -17860,30 +17711,6 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" - }, - "dependencies": { - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - } } }, "react-is": { @@ -18174,23 +18001,23 @@ } }, "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { "debug": { @@ -18204,7 +18031,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -18212,6 +18039,14 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } } } }, @@ -18240,14 +18075,14 @@ } }, "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" } }, "setimmediate": { @@ -18385,9 +18220,9 @@ } }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "stoppable": { "version": "1.1.0", diff --git a/package.json b/package.json index 0f33bb657..0057c2b33 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "debug": "4.3.4", "deepmerge": "4.2.2", "dotenv": "10.0.0", - "express": "4.17.3", + "express": "4.18.1", "express-async-handler": "1.2.0", "express-session": "1.17.3", "express-sslify": "1.2.0", @@ -128,7 +128,7 @@ "@types/connect-redis": "0.0.18", "@types/core-js": "2.5.5", "@types/debug": "4.1.7", - "@types/express": "4.17.13", + "@types/express": "4.17.14", "@types/express-session": "1.17.5", "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", From 45f5c8d8fcd6f25766c6ca5480e4cfa865b50e70 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Tue, 4 Oct 2022 13:36:48 -0400 Subject: [PATCH 032/209] Revert problematic packages. * Revert "Merge pull request #61 from NIHGOV/dependabot/npm_and_yarn/azure/data-tables-13.2.0" This reverts commit f7163622aa9e24e636cad953405176c27a17ae64, reversing changes made to 6b4075dfedbcf94cdef5d57c7d24ed3e97928ec5. * Revert "Bump body-parser from 1.19.2 to 1.20.0" This reverts commit a05d887b3caee9dde3a544bad201de786c7ee64f. * Revert "Merge pull request #27 from NIHGOV/dependabot/github_actions/actions/setup-node-3.1.0" This reverts commit 0f96830ccad53f44cab6d01d03d1956c40ef1691, reversing changes made to 4347cd38ae40efbe1a981ebb18450d82fa7a36f2. * Revert "Merge pull request #4 from NIHGOV/dependabot/npm_and_yarn/express-async-handler-1.2.0" This reverts commit 8955bf9432cac80822925360e556d45cdb0982d0, reversing changes made to acf9d26f5fd4121ea8455c7397386129d17150f9. * revert express-session --- .github/workflows/codeql-analysis.yml | 6 +- .github/workflows/main_nihgithubportal.yml | 21 +- env-orgs.json | 14 - env-orgs.json.example | 7 + package-lock.json | 1458 +++++++------------- package.json | 34 +- 6 files changed, 551 insertions(+), 989 deletions(-) delete mode 100644 env-orgs.json create mode 100644 env-orgs.json.example diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3b2ee72a2..6edaa622d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,7 +23,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v1 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java @@ -31,7 +31,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v1 # โ„น๏ธ Command-line programs to run using the OS shell. # ๐Ÿ“š https://git.io/JvXDl @@ -45,4 +45,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 13e72d014..644c64fc8 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -25,27 +25,13 @@ jobs: run: | npm install npm run build --if-present - cd ./default-assets-package - npm install - npm run build - cd .. npm run test --if-present - - - name: zip application folders - run: | - echo $PWD - ls -lah - cd .. - echo $PWD - ls -lah - tar -czf output.tar.gz ./github-portal - ls -lah - name: Upload artifact for deployment job uses: actions/upload-artifact@v3 with: name: node-app - path: /home/runner/work/github-portal/output.tar.gz + path: . deploy: runs-on: ubuntu-latest @@ -59,11 +45,6 @@ jobs: uses: actions/download-artifact@v3 with: name: node-app - - - name: Unpack tar - run: | - tar -xf output.tar.gz - ls -lah - name: 'Deploy to Azure Web App' id: deploy-to-webapp diff --git a/env-orgs.json b/env-orgs.json deleted file mode 100644 index b263495de..000000000 --- a/env-orgs.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name" : "NIHGOV", - "id" : 2710462, - "type": ["public", "private"], - "description" : "NIHโ€ฆTurning Discovery Into Healthยฎ" - }, - { - "name" : "STRIDES", - "id" : 69810051, - "type": ["public", "private"], - "description" : "NIH Science and Technology Research Infrastructure for Discovery, Experimentation, and Sustainability (STRIDES) Initiative" - } -] diff --git a/env-orgs.json.example b/env-orgs.json.example new file mode 100644 index 000000000..b976ea538 --- /dev/null +++ b/env-orgs.json.example @@ -0,0 +1,7 @@ +[ + { + "name" : "contoso", + "id" : "your-github-user-id e.g. 123456789", + "ownerToken" : "your github owner token" + } +] diff --git a/package-lock.json b/package-lock.json index 823192ee9..4ac612db7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,11 @@ "version": "7.1.0", "license": "MIT", "dependencies": { - "@azure/cosmos": "3.17.1", - "@azure/data-tables": "13.2.0", - "@azure/identity": "3.0.0", - "@azure/keyvault-secrets": "4.6.0", - "@azure/service-bus": "7.7.1", + "@azure/cosmos": "3.11.5", + "@azure/data-tables": "12.0.0-beta.2", + "@azure/identity": "2.0.1", + "@azure/keyvault-secrets": "4.3.0", + "@azure/service-bus": "7.4.0", "@azure/storage-blob": "12.8.0", "@azure/storage-file-share": "12.11.0", "@azure/storage-queue": "12.7.0", @@ -26,7 +26,7 @@ "axios": "0.27.2", "bad-words": "3.0.4", "basic-auth": "2.0.1", - "body-parser": "1.20.0", + "body-parser": "1.19.2", "cheerio": "1.0.0-rc.10", "child-process-promise": "2.2.1", "color-contrast-checker": "2.1.0", @@ -37,9 +37,9 @@ "debug": "4.3.4", "deepmerge": "4.2.2", "dotenv": "10.0.0", - "express": "4.18.1", - "express-async-handler": "1.2.0", - "express-session": "1.17.3", + "express": "4.17.3", + "express-async-handler": "1.1.4", + "express-session": "1.17.2", "express-sslify": "1.2.0", "file-size": "1.0.0", "get-pixels": "3.3.3", @@ -51,7 +51,7 @@ "jwks-rsa": "2.1.4", "language-map": "1.5.0", "lodash": "4.17.21", - "luxon": "3.0.3", + "luxon": "2.3.1", "memory-cache": "0.2.0", "moment": "2.29.4", "morgan": "1.10.0", @@ -90,11 +90,11 @@ "@types/core-js": "2.5.5", "@types/debug": "4.1.7", "@types/express": "4.17.14", - "@types/express-session": "1.17.5", + "@types/express-session": "1.17.4", "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", "@types/lodash": "4.14.180", - "@types/luxon": "3.0.1", + "@types/luxon": "2.3.1", "@types/memory-cache": "0.2.2", "@types/morgan": "1.9.3", "@types/multer": "^1.4.7", @@ -113,13 +113,13 @@ "@types/unzipper": "0.10.5", "@types/validator": "13.7.7", "@typescript-eslint/eslint-plugin": "5.17.0", - "@typescript-eslint/parser": "5.36.2", - "eslint": "8.24.0", + "@typescript-eslint/parser": "5.17.0", + "eslint": "8.11.0", "jest": "27.5.1", - "jest-junit": "14.0.1", + "jest-junit": "13.0.0", "ts-jest": "27.1.4", - "ts-node": "10.9.1", - "typescript": "4.8.4" + "ts-node": "10.7.0", + "typescript": "4.6.3" } }, "node_modules/@ampproject/remapping": { @@ -229,19 +229,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/core-http-compat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-1.3.0.tgz", - "integrity": "sha512-ZN9avruqbQ5TxopzG3ih3KRy52n8OAbitX3fnZT5go4hzu0J+KVPSzkL+Wt3hpJpdG8WIfg1sBD1tWkgUdEpBA==", - "dependencies": { - "@azure/abort-controller": "^1.0.4", - "@azure/core-client": "^1.3.0", - "@azure/core-rest-pipeline": "^1.3.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/core-lro": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.4.tgz", @@ -311,95 +298,93 @@ } }, "node_modules/@azure/core-xml": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.0.tgz", - "integrity": "sha512-HYulCHr/3eMDxGubmbm+KIUxpOKPGtRxpaKBN6GpgPDQzREefdQ5bDlTuwHWhtqwyUG4RicKtZu8rhv5Sbg8jQ==", + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.0.0-beta.1.tgz", + "integrity": "sha512-7d2w0yd8pb1c9aj87JV/1ntOp+sCMcJ9QoGDxs6/7BLDh8Gb6kd2h3n+9JYhcLZO8wdHZb4d4GZgmRIwaAU72w==", "dependencies": { - "fast-xml-parser": "^4.0.8", - "tslib": "^2.2.0" + "tslib": "^2.0.0", + "xml2js": "^0.4.19" }, "engines": { - "node": ">=12.0.0" + "node": ">=8.0.0" } }, "node_modules/@azure/cosmos": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.17.1.tgz", - "integrity": "sha512-3pgPwNwAiTgiH/OgcntDLzrANy+roaaDFYoLOhC4bxoDC94nPCjpLYRRwueIpisZAdopPVrxQloNs9fEjVlL0A==", + "version": "3.11.5", + "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.11.5.tgz", + "integrity": "sha512-emKRLrrQLAzwVyOWo67THkPSWD646puwvUfr8oVhCYSs9OgfTCeNh29XB7uU4YZd3ufcumFrTupSCfH6AodZUA==", "dependencies": { "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.2.0", - "@azure/core-tracing": "^1.0.0", + "@azure/core-rest-pipeline": "^1.0.3", "debug": "^4.1.1", - "fast-json-stable-stringify": "^2.1.0", + "fast-json-stable-stringify": "^2.0.0", "jsbi": "^3.1.3", - "node-abort-controller": "^3.0.0", + "node-abort-controller": "^1.2.0", "priorityqueuejs": "^1.0.0", "semaphore": "^1.0.5", - "tslib": "^2.2.0", + "tslib": "^2.0.0", "universal-user-agent": "^6.0.0", "uuid": "^8.3.0" }, "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/cosmos/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" + "node": ">=8.0.0" } }, "node_modules/@azure/data-tables": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-13.2.0.tgz", - "integrity": "sha512-o16WVzcCYuZRh8M43R+twJyB9fZnhG2Y4ZfGmV2jX3HgV7TSBIXysuwgVYkdqYd3cyBVzpHW3pLY7IasOjvO7w==", + "version": "12.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-12.0.0-beta.2.tgz", + "integrity": "sha512-0bxVa9pTyeKjuLOMx+PGGfEOeY+JH1e1j3GrB7PrrFE8H3yB0RhqCZi5CSqojidgWuhYNK0nh5RG68v3WqQgcg==", "dependencies": { - "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-xml": "^1.0.0", + "@azure/core-rest-pipeline": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.11", + "@azure/core-xml": "1.0.0-beta.1", "@azure/logger": "^1.0.0", - "tslib": "^2.2.0", + "tslib": "^2.0.0", "uuid": "^8.3.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=8.0.0" } }, "node_modules/@azure/data-tables/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "version": "1.0.0-preview.11", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.11.tgz", + "integrity": "sha512-frF0pJc9HTmKncVokhBxCqipjbql02DThQ1ZJ9wLi7SDMLdPAFyDI5xZNzX5guLz+/DtPkY+SGK2li9FIXqshQ==", "dependencies": { - "tslib": "^2.2.0" + "@opencensus/web-types": "0.0.7", + "@opentelemetry/api": "1.0.0-rc.0", + "tslib": "^2.0.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=8.0.0" + } + }, + "node_modules/@azure/data-tables/node_modules/@opentelemetry/api": { + "version": "1.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.0-rc.0.tgz", + "integrity": "sha512-iXKByCMfrlO5S6Oh97BuM56tM2cIBB0XsL/vWF/AtJrJEKx4MC/Xdu0xDsGXMGcNWpqF7ujMsjjnp0+UHBwnDQ==", + "engines": { + "node": ">=8.0.0" } }, "node_modules/@azure/identity": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.0.0.tgz", - "integrity": "sha512-MAwrefZE6T15wJe/tOA6dffdTNCh+S6DOQe2otO6drEEVCHDF0zb+GItlK6kQzD5hPm/YueFCW6sN1q6F4XYuQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-2.0.1.tgz", + "integrity": "sha512-gdGGuLKlKIQaf2RefA84keoBfmWfiAntbW2SzcdKvwLSGzsio/qkyY3sYUpXRz/sqLDxguuimgZukp7TPgwIlg==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.4.0", + "@azure/core-client": "^1.0.0", "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.0.0-beta.1", "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^2.26.0", - "@azure/msal-common": "^7.0.0", - "@azure/msal-node": "^1.10.0", + "@azure/msal-browser": "^2.16.0", + "@azure/msal-common": "^4.5.1", + "@azure/msal-node": "^1.3.0", + "@types/stoppable": "^1.1.0", "events": "^3.0.0", "jws": "^4.0.0", "open": "^8.0.0", @@ -411,31 +396,27 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/identity/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "node_modules/@azure/identity/node_modules/@azure/msal-common": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-4.5.1.tgz", + "integrity": "sha512-/i5dXM+QAtO+6atYd5oHGBAx48EGSISkXNXViheliOQe+SIFMDo3gSq3lL54W0suOSAsVPws3XnTaIHlla0PIQ==", "dependencies": { - "tslib": "^2.2.0" + "debug": "^4.1.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=0.8.0" } }, "node_modules/@azure/keyvault-secrets": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.6.0.tgz", - "integrity": "sha512-MDqsyODCGC2srqLKmO6MFw9WdgLrbPsfCNxgbekHXEd6XKM6KKyBlup5joj96EmdfZnXDFriecAIpj0Dtu81RQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.3.0.tgz", + "integrity": "sha512-bhdAr2Yjx+XpgfkClOufpTxcnKqDIwyOSKrbI9mJ2q5wQNb7Z1WPnPnIhjdsw1on/NRXzMaarYFNkf/MdS73FA==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.5.0", - "@azure/core-http-compat": "^1.3.0", - "@azure/core-lro": "^2.2.0", + "@azure/core-http": "^2.0.0", + "@azure/core-lro": "^2.0.0", "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.8.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", "@azure/logger": "^1.0.0", "tslib": "^2.2.0" }, @@ -443,17 +424,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/keyvault-secrets/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/logger": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", @@ -498,25 +468,24 @@ } }, "node_modules/@azure/service-bus": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.7.1.tgz", - "integrity": "sha512-n04GNKZodxpUa5YGfW+LcIQvCzDQ9y8eY5SURv11cys+P67rVF4RNt5GVTE+FzoFFVS57y8Cb2IOmA4MClSI0g==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.4.0.tgz", + "integrity": "sha512-dznAohud/t7qT4KuQ9LsJ7ZKRpecXbunpCJi+kcfqA6aY1ffB2gYXg8odMJoIZPcxLBZiBvJIXp5P9y5IhEMgg==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-amqp": "^3.1.0", + "@azure/core-amqp": "^3.0.0", + "@azure/core-asynciterator-polyfill": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.0.0", + "@azure/core-http": "^2.0.0", "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.1.0", - "@azure/core-xml": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", "@azure/logger": "^1.0.0", "@types/is-buffer": "^2.0.0", + "@types/long": "^4.0.0", "buffer": "^6.0.0", "is-buffer": "^2.0.3", "jssha": "^3.1.0", - "long": "^5.2.0", + "long": "^4.0.0", "process": "^0.11.10", "rhea-promise": "^2.1.0", "tslib": "^2.2.0" @@ -525,16 +494,10 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/service-bus/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } + "node_modules/@azure/service-bus/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, "node_modules/@azure/storage-blob": { "version": "12.8.0", @@ -1149,13 +1112,22 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "@cspotcode/source-map-consumer": "0.8.0" }, "engines": { "node": ">=12" @@ -1221,9 +1193,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", - "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1234,29 +1206,6 @@ "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -1575,9 +1524,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -1811,6 +1760,14 @@ "@octokit/openapi-types": "^11.2.0" } }, + "node_modules/@opencensus/web-types": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@opencensus/web-types/-/web-types-0.0.7.tgz", + "integrity": "sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g==", + "engines": { + "node": ">=6.0" + } + }, "node_modules/@opentelemetry/api": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz", @@ -2078,9 +2035,9 @@ } }, "node_modules/@types/express-session": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.5.tgz", - "integrity": "sha512-l0DhkvNVfyUPEEis8fcwbd46VptfA/jmMwHfob2TfDMf3HyPLiB9mKD71LXhz5TMUobODXPD27zXSwtFQLHm+w==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.4.tgz", + "integrity": "sha512-7cNlSI8+oOBUHTfPXMwDxF/Lchx5aJ3ho7+p9jJZYVg9dVDJFh3qdMXmJtRsysnvS+C6x46k9DRYmrmCkE+MVg==", "dev": true, "dependencies": { "@types/express": "*" @@ -2172,15 +2129,20 @@ "integrity": "sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g==", "dev": true }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "node_modules/@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" }, "node_modules/@types/luxon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.0.1.tgz", - "integrity": "sha512-/LAvk1cMOJt0ghzMFrZEvByUhsiEfeeT2IF53Le+Ki3A538yEL9pRZ7a6MuCxdrYK+YNqNIDmrKU/r2nnw04zQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.1.tgz", + "integrity": "sha512-nAPUltOT28fal2eDZz8yyzNhBjHw1NEymFBP7Q9iCShqpflWPybxHbD7pw/46jQmT+HXOy1QN5hNTms8MOTlOQ==", "dev": true }, "node_modules/@types/memory-cache": { @@ -2393,6 +2355,14 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/stoppable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/stoppable/-/stoppable-1.1.1.tgz", + "integrity": "sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/tunnel": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", @@ -2465,15 +2435,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.2.tgz", - "integrity": "sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.17.0.tgz", + "integrity": "sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.2", - "@typescript-eslint/types": "5.36.2", - "@typescript-eslint/typescript-estree": "5.36.2", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "5.17.0", + "@typescript-eslint/types": "5.17.0", + "@typescript-eslint/typescript-estree": "5.17.0", + "debug": "^4.3.2" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2491,95 +2461,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.2.tgz", - "integrity": "sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.36.2", - "@typescript-eslint/visitor-keys": "5.36.2" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.2.tgz", - "integrity": "sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.2.tgz", - "integrity": "sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.36.2", - "@typescript-eslint/visitor-keys": "5.36.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.2.tgz", - "integrity": "sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.36.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.17.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz", @@ -3306,26 +3187,23 @@ "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" }, "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", + "depd": "~1.1.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">= 0.8" } }, "node_modules/body-parser/node_modules/debug": { @@ -3341,17 +3219,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node_modules/body-parser/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -4211,11 +4078,11 @@ } }, "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/deprecation": { @@ -4224,13 +4091,9 @@ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" }, "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" }, "node_modules/detect-newline": { "version": "3.1.0", @@ -4693,15 +4556,13 @@ } }, "node_modules/eslint": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", - "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", + "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", - "@humanwhocodes/module-importer": "^1.0.1", + "@eslint/eslintrc": "^1.2.1", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4711,32 +4572,30 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", + "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", + "globals": "^13.6.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "bin": { "eslint": "bin/eslint.js" @@ -4833,67 +4692,6 @@ "node": ">=4.0" } }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5092,38 +4890,37 @@ } }, "node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.19.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "2.0.0", + "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "~1.1.2", "fresh": "0.5.2", - "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.9.7", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.17.2", + "serve-static": "1.14.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -5133,16 +4930,16 @@ } }, "node_modules/express-async-handler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", - "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.1.4.tgz", + "integrity": "sha512-HdmbVF4V4w1q/iz++RV7bUxIeepTukWewiJGkoCKQMtvPF11MLTa7It9PRc/reysXXZSEyD4Pthchju+IUbMiQ==" }, "node_modules/express-session": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", - "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", "dependencies": { - "cookie": "0.4.2", + "cookie": "0.4.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", @@ -5155,6 +4952,14 @@ "node": ">= 0.8.0" } }, + "node_modules/express-session/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express-session/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5163,6 +4968,14 @@ "ms": "2.0.0" } }, + "node_modules/express-session/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express-session/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5192,14 +5005,6 @@ "resolved": "https://registry.npmjs.org/express-sslify/-/express-sslify-1.2.0.tgz", "integrity": "sha1-MOhLzu0VV+sYdnK74UMKCioQDZw=" }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5213,17 +5018,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/express/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5305,21 +5099,6 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, - "node_modules/fast-xml-parser": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.9.tgz", - "integrity": "sha512-4G8EzDg2Nb1Qurs3f7BpFV4+jpMVsdgLVuG1Uv8O2OHJfVCg7gcA53obuKbmVqzd4Y7YXVBK05oJG7hzGIdyzg==", - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -5368,16 +5147,16 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "engines": { @@ -5389,25 +5168,14 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/finalhandler/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" + "ms": "2.0.0" } }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -5736,12 +5504,6 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -5827,6 +5589,14 @@ "node": ">=4.0.0" } }, + "node_modules/hsts/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -5864,18 +5634,18 @@ } }, "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dependencies": { - "depd": "2.0.0", + "depd": "~1.1.2", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/http-proxy-agent": { @@ -6782,9 +6552,9 @@ } }, "node_modules/jest-junit": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-14.0.1.tgz", - "integrity": "sha512-h7/wwzPbllgpQhhVcRzRC76/cc89GlazThoV1fDxcALkf26IIlRsu/AcTG64f4nR2WPE3Cbd+i/sVf+NCUHrWQ==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.0.0.tgz", + "integrity": "sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==", "dev": true, "dependencies": { "mkdirp": "^1.0.4", @@ -7153,12 +6923,6 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, - "node_modules/js-sdsl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", - "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", - "dev": true - }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -7634,9 +7398,9 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "node_modules/luxon": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.0.3.tgz", - "integrity": "sha512-+EfHWnF+UT7GgTnq5zXg3ldnTKL2zdv7QJgsU5bjjpbH17E3qi/puMhQyJVYuCq+FRkogvB5WB6iVvUr+E4a7w==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.3.1.tgz", + "integrity": "sha512-I8vnjOmhXsMSlNMZlMkSOvgrxKJl0uOsEzdGgGNZuZPaS9KlefpE9KV95QFftlJSC+1UyCC9/I69R02cz/zcCA==", "engines": { "node": ">=12" } @@ -7832,6 +7596,14 @@ "ms": "2.0.0" } }, + "node_modules/morgan/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/morgan/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -7987,9 +7759,9 @@ } }, "node_modules/node-abort-controller": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", - "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-1.2.1.tgz", + "integrity": "sha512-79PYeJuj6S9+yOHirR0JBLFOgjB6sQCir10uN6xRx25iD+ZD4ULqgRn3MwWBRaQGB0vEgReJzWwJo42T1R6YbQ==" }, "node_modules/node-bitmap": { "version": "0.0.1", @@ -8956,12 +8728,9 @@ } }, "node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dependencies": { - "side-channel": "^1.0.4" - }, + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", "engines": { "node": ">=0.6" }, @@ -9015,12 +8784,12 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "dependencies": { "bytes": "3.1.2", - "http-errors": "2.0.0", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -9408,23 +9177,23 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "dependencies": { "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", + "depd": "~1.1.2", + "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "2.0.0", + "http-errors": "1.8.1", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "range-parser": "~1.2.1", - "statuses": "2.0.1" + "statuses": "~1.5.0" }, "engines": { "node": ">= 0.8.0" @@ -9448,17 +9217,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node_modules/send/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/serve-favicon": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", @@ -9485,14 +9243,14 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.17.2" }, "engines": { "node": ">= 0.8.0" @@ -9663,11 +9421,11 @@ } }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/stoppable": { @@ -9783,11 +9541,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10011,12 +9764,12 @@ } }, "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", "dev": true, "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", + "@cspotcode/source-map-support": "0.7.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -10027,7 +9780,7 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", + "v8-compile-cache-lib": "^3.0.0", "yn": "3.1.1" }, "bin": { @@ -10172,9 +9925,9 @@ } }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -10354,10 +10107,16 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", "dev": true }, "node_modules/v8-to-istanbul": { @@ -10732,18 +10491,6 @@ "engines": { "node": ">=6" } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } }, "dependencies": { @@ -10833,16 +10580,6 @@ "xml2js": "^0.4.19" } }, - "@azure/core-http-compat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-1.3.0.tgz", - "integrity": "sha512-ZN9avruqbQ5TxopzG3ih3KRy52n8OAbitX3fnZT5go4hzu0J+KVPSzkL+Wt3hpJpdG8WIfg1sBD1tWkgUdEpBA==", - "requires": { - "@azure/abort-controller": "^1.0.4", - "@azure/core-client": "^1.3.0", - "@azure/core-rest-pipeline": "^1.3.0" - } - }, "@azure/core-lro": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.4.tgz", @@ -10897,84 +10634,80 @@ } }, "@azure/core-xml": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.0.tgz", - "integrity": "sha512-HYulCHr/3eMDxGubmbm+KIUxpOKPGtRxpaKBN6GpgPDQzREefdQ5bDlTuwHWhtqwyUG4RicKtZu8rhv5Sbg8jQ==", + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.0.0-beta.1.tgz", + "integrity": "sha512-7d2w0yd8pb1c9aj87JV/1ntOp+sCMcJ9QoGDxs6/7BLDh8Gb6kd2h3n+9JYhcLZO8wdHZb4d4GZgmRIwaAU72w==", "requires": { - "fast-xml-parser": "^4.0.8", - "tslib": "^2.2.0" + "tslib": "^2.0.0", + "xml2js": "^0.4.19" } }, "@azure/cosmos": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.17.1.tgz", - "integrity": "sha512-3pgPwNwAiTgiH/OgcntDLzrANy+roaaDFYoLOhC4bxoDC94nPCjpLYRRwueIpisZAdopPVrxQloNs9fEjVlL0A==", + "version": "3.11.5", + "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.11.5.tgz", + "integrity": "sha512-emKRLrrQLAzwVyOWo67THkPSWD646puwvUfr8oVhCYSs9OgfTCeNh29XB7uU4YZd3ufcumFrTupSCfH6AodZUA==", "requires": { "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.2.0", - "@azure/core-tracing": "^1.0.0", + "@azure/core-rest-pipeline": "^1.0.3", "debug": "^4.1.1", - "fast-json-stable-stringify": "^2.1.0", + "fast-json-stable-stringify": "^2.0.0", "jsbi": "^3.1.3", - "node-abort-controller": "^3.0.0", + "node-abort-controller": "^1.2.0", "priorityqueuejs": "^1.0.0", "semaphore": "^1.0.5", - "tslib": "^2.2.0", + "tslib": "^2.0.0", "universal-user-agent": "^6.0.0", "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "requires": { - "tslib": "^2.2.0" - } - } } }, "@azure/data-tables": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-13.2.0.tgz", - "integrity": "sha512-o16WVzcCYuZRh8M43R+twJyB9fZnhG2Y4ZfGmV2jX3HgV7TSBIXysuwgVYkdqYd3cyBVzpHW3pLY7IasOjvO7w==", + "version": "12.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-12.0.0-beta.2.tgz", + "integrity": "sha512-0bxVa9pTyeKjuLOMx+PGGfEOeY+JH1e1j3GrB7PrrFE8H3yB0RhqCZi5CSqojidgWuhYNK0nh5RG68v3WqQgcg==", "requires": { - "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-xml": "^1.0.0", + "@azure/core-rest-pipeline": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.11", + "@azure/core-xml": "1.0.0-beta.1", "@azure/logger": "^1.0.0", - "tslib": "^2.2.0", + "tslib": "^2.0.0", "uuid": "^8.3.0" }, "dependencies": { "@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "version": "1.0.0-preview.11", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.11.tgz", + "integrity": "sha512-frF0pJc9HTmKncVokhBxCqipjbql02DThQ1ZJ9wLi7SDMLdPAFyDI5xZNzX5guLz+/DtPkY+SGK2li9FIXqshQ==", "requires": { - "tslib": "^2.2.0" + "@opencensus/web-types": "0.0.7", + "@opentelemetry/api": "1.0.0-rc.0", + "tslib": "^2.0.0" } + }, + "@opentelemetry/api": { + "version": "1.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.0-rc.0.tgz", + "integrity": "sha512-iXKByCMfrlO5S6Oh97BuM56tM2cIBB0XsL/vWF/AtJrJEKx4MC/Xdu0xDsGXMGcNWpqF7ujMsjjnp0+UHBwnDQ==" } } }, "@azure/identity": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.0.0.tgz", - "integrity": "sha512-MAwrefZE6T15wJe/tOA6dffdTNCh+S6DOQe2otO6drEEVCHDF0zb+GItlK6kQzD5hPm/YueFCW6sN1q6F4XYuQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-2.0.1.tgz", + "integrity": "sha512-gdGGuLKlKIQaf2RefA84keoBfmWfiAntbW2SzcdKvwLSGzsio/qkyY3sYUpXRz/sqLDxguuimgZukp7TPgwIlg==", "requires": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.4.0", + "@azure/core-client": "^1.0.0", "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.0.0-beta.1", "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^2.26.0", - "@azure/msal-common": "^7.0.0", - "@azure/msal-node": "^1.10.0", + "@azure/msal-browser": "^2.16.0", + "@azure/msal-common": "^4.5.1", + "@azure/msal-node": "^1.3.0", + "@types/stoppable": "^1.1.0", "events": "^3.0.0", "jws": "^4.0.0", "open": "^8.0.0", @@ -10983,42 +10716,28 @@ "uuid": "^8.3.0" }, "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "@azure/msal-common": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-4.5.1.tgz", + "integrity": "sha512-/i5dXM+QAtO+6atYd5oHGBAx48EGSISkXNXViheliOQe+SIFMDo3gSq3lL54W0suOSAsVPws3XnTaIHlla0PIQ==", "requires": { - "tslib": "^2.2.0" + "debug": "^4.1.1" } } } }, "@azure/keyvault-secrets": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.6.0.tgz", - "integrity": "sha512-MDqsyODCGC2srqLKmO6MFw9WdgLrbPsfCNxgbekHXEd6XKM6KKyBlup5joj96EmdfZnXDFriecAIpj0Dtu81RQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.3.0.tgz", + "integrity": "sha512-bhdAr2Yjx+XpgfkClOufpTxcnKqDIwyOSKrbI9mJ2q5wQNb7Z1WPnPnIhjdsw1on/NRXzMaarYFNkf/MdS73FA==", "requires": { "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.5.0", - "@azure/core-http-compat": "^1.3.0", - "@azure/core-lro": "^2.2.0", + "@azure/core-http": "^2.0.0", + "@azure/core-lro": "^2.0.0", "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.8.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", "@azure/logger": "^1.0.0", "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "requires": { - "tslib": "^2.2.0" - } - } } }, "@azure/logger": { @@ -11053,37 +10772,33 @@ } }, "@azure/service-bus": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.7.1.tgz", - "integrity": "sha512-n04GNKZodxpUa5YGfW+LcIQvCzDQ9y8eY5SURv11cys+P67rVF4RNt5GVTE+FzoFFVS57y8Cb2IOmA4MClSI0g==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.4.0.tgz", + "integrity": "sha512-dznAohud/t7qT4KuQ9LsJ7ZKRpecXbunpCJi+kcfqA6aY1ffB2gYXg8odMJoIZPcxLBZiBvJIXp5P9y5IhEMgg==", "requires": { "@azure/abort-controller": "^1.0.0", - "@azure/core-amqp": "^3.1.0", + "@azure/core-amqp": "^3.0.0", + "@azure/core-asynciterator-polyfill": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.0.0", + "@azure/core-http": "^2.0.0", "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.1.0", - "@azure/core-xml": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", "@azure/logger": "^1.0.0", "@types/is-buffer": "^2.0.0", + "@types/long": "^4.0.0", "buffer": "^6.0.0", "is-buffer": "^2.0.3", "jssha": "^3.1.0", - "long": "^5.2.0", + "long": "^4.0.0", "process": "^0.11.10", "rhea-promise": "^2.1.0", "tslib": "^2.2.0" }, "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "requires": { - "tslib": "^2.2.0" - } + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" } } }, @@ -11556,13 +11271,19 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "0.3.9" + "@cspotcode/source-map-consumer": "0.8.0" } }, "@eslint/eslintrc": { @@ -11619,9 +11340,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", - "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -11629,18 +11350,6 @@ "minimatch": "^3.0.4" } }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -11897,9 +11606,9 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", @@ -12116,6 +11825,11 @@ "@octokit/openapi-types": "^11.2.0" } }, + "@opencensus/web-types": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@opencensus/web-types/-/web-types-0.0.7.tgz", + "integrity": "sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g==" + }, "@opentelemetry/api": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz", @@ -12355,9 +12069,9 @@ } }, "@types/express-session": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.5.tgz", - "integrity": "sha512-l0DhkvNVfyUPEEis8fcwbd46VptfA/jmMwHfob2TfDMf3HyPLiB9mKD71LXhz5TMUobODXPD27zXSwtFQLHm+w==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.4.tgz", + "integrity": "sha512-7cNlSI8+oOBUHTfPXMwDxF/Lchx5aJ3ho7+p9jJZYVg9dVDJFh3qdMXmJtRsysnvS+C6x46k9DRYmrmCkE+MVg==", "dev": true, "requires": { "@types/express": "*" @@ -12449,15 +12163,20 @@ "integrity": "sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g==", "dev": true }, + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" }, "@types/luxon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.0.1.tgz", - "integrity": "sha512-/LAvk1cMOJt0ghzMFrZEvByUhsiEfeeT2IF53Le+Ki3A538yEL9pRZ7a6MuCxdrYK+YNqNIDmrKU/r2nnw04zQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.1.tgz", + "integrity": "sha512-nAPUltOT28fal2eDZz8yyzNhBjHw1NEymFBP7Q9iCShqpflWPybxHbD7pw/46jQmT+HXOy1QN5hNTms8MOTlOQ==", "dev": true }, "@types/memory-cache": { @@ -12668,6 +12387,14 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/stoppable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/stoppable/-/stoppable-1.1.1.tgz", + "integrity": "sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw==", + "requires": { + "@types/node": "*" + } + }, "@types/tunnel": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", @@ -12724,67 +12451,15 @@ } }, "@typescript-eslint/parser": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.2.tgz", - "integrity": "sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.17.0.tgz", + "integrity": "sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.36.2", - "@typescript-eslint/types": "5.36.2", - "@typescript-eslint/typescript-estree": "5.36.2", - "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.2.tgz", - "integrity": "sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.36.2", - "@typescript-eslint/visitor-keys": "5.36.2" - } - }, - "@typescript-eslint/types": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.2.tgz", - "integrity": "sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.2.tgz", - "integrity": "sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.36.2", - "@typescript-eslint/visitor-keys": "5.36.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.2.tgz", - "integrity": "sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.36.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "@typescript-eslint/scope-manager": "5.17.0", + "@typescript-eslint/types": "5.17.0", + "@typescript-eslint/typescript-estree": "5.17.0", + "debug": "^4.3.2" } }, "@typescript-eslint/scope-manager": { @@ -13308,22 +12983,20 @@ "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" }, "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", + "depd": "~1.1.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" }, "dependencies": { "debug": { @@ -13338,14 +13011,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } } } }, @@ -14018,9 +13683,9 @@ "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" }, "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, "deprecation": { "version": "2.3.1", @@ -14028,9 +13693,9 @@ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" }, "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" }, "detect-newline": { "version": "3.1.0", @@ -14390,15 +14055,13 @@ } }, "eslint": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", - "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", + "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", - "@humanwhocodes/module-importer": "^1.0.1", + "@eslint/eslintrc": "^1.2.1", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -14408,32 +14071,30 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", + "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", + "globals": "^13.6.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { "cross-spawn": { @@ -14463,43 +14124,6 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -14675,48 +14299,42 @@ } }, "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.19.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "2.0.0", + "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "~1.1.2", "fresh": "0.5.2", - "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.9.7", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.17.2", + "serve-static": "1.14.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -14730,14 +14348,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -14746,16 +14356,16 @@ } }, "express-async-handler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", - "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.1.4.tgz", + "integrity": "sha512-HdmbVF4V4w1q/iz++RV7bUxIeepTukWewiJGkoCKQMtvPF11MLTa7It9PRc/reysXXZSEyD4Pthchju+IUbMiQ==" }, "express-session": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", - "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", "requires": { - "cookie": "0.4.2", + "cookie": "0.4.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", @@ -14765,6 +14375,11 @@ "uid-safe": "~2.1.5" }, "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -14773,6 +14388,11 @@ "ms": "2.0.0" } }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -14845,14 +14465,6 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, - "fast-xml-parser": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.9.tgz", - "integrity": "sha512-4G8EzDg2Nb1Qurs3f7BpFV4+jpMVsdgLVuG1Uv8O2OHJfVCg7gcA53obuKbmVqzd4Y7YXVBK05oJG7hzGIdyzg==", - "requires": { - "strnum": "^1.0.5" - } - }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -14895,16 +14507,16 @@ } }, "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "dependencies": { @@ -14920,14 +14532,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } } } }, @@ -15168,12 +14772,6 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -15226,6 +14824,13 @@ "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", "requires": { "depd": "2.0.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } } }, "html-encoding-sniffer": { @@ -15255,14 +14860,14 @@ } }, "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "requires": { - "depd": "2.0.0", + "depd": "~1.1.2", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.1" } }, @@ -15891,9 +15496,9 @@ } }, "jest-junit": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-14.0.1.tgz", - "integrity": "sha512-h7/wwzPbllgpQhhVcRzRC76/cc89GlazThoV1fDxcALkf26IIlRsu/AcTG64f4nR2WPE3Cbd+i/sVf+NCUHrWQ==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.0.0.tgz", + "integrity": "sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==", "dev": true, "requires": { "mkdirp": "^1.0.4", @@ -16190,12 +15795,6 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, - "js-sdsl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", - "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", - "dev": true - }, "js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", @@ -16610,9 +16209,9 @@ } }, "luxon": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.0.3.tgz", - "integrity": "sha512-+EfHWnF+UT7GgTnq5zXg3ldnTKL2zdv7QJgsU5bjjpbH17E3qi/puMhQyJVYuCq+FRkogvB5WB6iVvUr+E4a7w==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.3.1.tgz", + "integrity": "sha512-I8vnjOmhXsMSlNMZlMkSOvgrxKJl0uOsEzdGgGNZuZPaS9KlefpE9KV95QFftlJSC+1UyCC9/I69R02cz/zcCA==" }, "make-dir": { "version": "3.1.0", @@ -16756,6 +16355,11 @@ "ms": "2.0.0" } }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -16895,9 +16499,9 @@ } }, "node-abort-controller": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", - "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-1.2.1.tgz", + "integrity": "sha512-79PYeJuj6S9+yOHirR0JBLFOgjB6sQCir10uN6xRx25iD+ZD4ULqgRn3MwWBRaQGB0vEgReJzWwJo42T1R6YbQ==" }, "node-bitmap": { "version": "0.0.1", @@ -17661,12 +17265,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "requires": { - "side-channel": "^1.0.4" - } + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" }, "querystring": { "version": "0.2.0", @@ -17690,12 +17291,12 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "requires": { "bytes": "3.1.2", - "http-errors": "2.0.0", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } @@ -17988,23 +17589,23 @@ } }, "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "requires": { "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", + "depd": "~1.1.2", + "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "2.0.0", + "http-errors": "1.8.1", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "range-parser": "~1.2.1", - "statuses": "2.0.1" + "statuses": "~1.5.0" }, "dependencies": { "debug": { @@ -18026,14 +17627,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } } } }, @@ -18062,14 +17655,14 @@ } }, "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.17.2" } }, "setimmediate": { @@ -18207,9 +17800,9 @@ } }, "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, "stoppable": { "version": "1.1.0", @@ -18290,11 +17883,6 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, - "strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -18449,12 +18037,12 @@ } }, "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", "dev": true, "requires": { - "@cspotcode/source-map-support": "^0.8.0", + "@cspotcode/source-map-support": "0.7.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -18465,7 +18053,7 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", + "v8-compile-cache-lib": "^3.0.0", "yn": "3.1.1" }, "dependencies": { @@ -18562,9 +18150,9 @@ } }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", "dev": true }, "uid-safe": { @@ -18723,10 +18311,16 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", "dev": true }, "v8-to-istanbul": { @@ -19013,12 +18607,6 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true } } } diff --git a/package.json b/package.json index 5909729f3..425bfcb5e 100644 --- a/package.json +++ b/package.json @@ -48,11 +48,11 @@ "_end_microsoft_internal_": 0, "//...": "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ", "dependencies": { - "@azure/cosmos": "3.17.1", - "@azure/data-tables": "13.2.0", - "@azure/identity": "3.0.0", - "@azure/keyvault-secrets": "4.6.0", - "@azure/service-bus": "7.7.1", + "@azure/cosmos": "3.11.5", + "@azure/data-tables": "12.0.0-beta.2", + "@azure/identity": "2.0.1", + "@azure/keyvault-secrets": "4.3.0", + "@azure/service-bus": "7.4.0", "@azure/storage-blob": "12.8.0", "@azure/storage-file-share": "12.11.0", "@azure/storage-queue": "12.7.0", @@ -65,7 +65,7 @@ "axios": "0.27.2", "bad-words": "3.0.4", "basic-auth": "2.0.1", - "body-parser": "1.20.0", + "body-parser": "1.19.2", "cheerio": "1.0.0-rc.10", "child-process-promise": "2.2.1", "color-contrast-checker": "2.1.0", @@ -76,9 +76,9 @@ "debug": "4.3.4", "deepmerge": "4.2.2", "dotenv": "10.0.0", - "express": "4.18.1", - "express-async-handler": "1.2.0", - "express-session": "1.17.3", + "express": "4.17.3", + "express-async-handler": "1.1.4", + "express-session": "1.17.2", "express-sslify": "1.2.0", "file-size": "1.0.0", "get-pixels": "3.3.3", @@ -90,7 +90,7 @@ "jwks-rsa": "2.1.4", "language-map": "1.5.0", "lodash": "4.17.21", - "luxon": "3.0.3", + "luxon": "2.3.1", "memory-cache": "0.2.0", "moment": "2.29.4", "morgan": "1.10.0", @@ -129,11 +129,11 @@ "@types/core-js": "2.5.5", "@types/debug": "4.1.7", "@types/express": "4.17.14", - "@types/express-session": "1.17.5", + "@types/express-session": "1.17.4", "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", "@types/lodash": "4.14.180", - "@types/luxon": "3.0.1", + "@types/luxon": "2.3.1", "@types/memory-cache": "0.2.2", "@types/morgan": "1.9.3", "@types/multer": "^1.4.7", @@ -152,12 +152,12 @@ "@types/unzipper": "0.10.5", "@types/validator": "13.7.7", "@typescript-eslint/eslint-plugin": "5.17.0", - "@typescript-eslint/parser": "5.36.2", - "eslint": "8.24.0", + "@typescript-eslint/parser": "5.17.0", + "eslint": "8.11.0", "jest": "27.5.1", - "jest-junit": "14.0.1", + "jest-junit": "13.0.0", "ts-jest": "27.1.4", - "ts-node": "10.9.1", - "typescript": "4.8.4" + "ts-node": "10.7.0", + "typescript": "4.6.3" } } \ No newline at end of file From a1e11ddbfdee467727cb884c4e584a9012ecfec3 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 5 Oct 2022 13:40:10 -0400 Subject: [PATCH 033/209] repair build/deploy repair unintentional rollback edits to build/deploy action --- .github/workflows/main_nihgithubportal.yml | 25 +++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 644c64fc8..8c2353f1d 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -20,18 +20,32 @@ jobs: uses: actions/setup-node@v3 with: node-version: '16.x' - + - name: npm install, build, and test run: | npm install npm run build --if-present + cd ./default-assets-package + npm install + npm run build + cd .. npm run test --if-present + + - name: zip application folders + run: | + echo $PWD + ls -lah + cd .. + echo $PWD + ls -lah + tar -czf output.tar.gz ./opensource-management-portal + ls -lah - name: Upload artifact for deployment job - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v2 with: name: node-app - path: . + path: /home/runner/work/opensource-management-portal/output.tar.gz deploy: runs-on: ubuntu-latest @@ -45,6 +59,11 @@ jobs: uses: actions/download-artifact@v3 with: name: node-app + + - name: Unpack tar + run: | + tar -xf output.tar.gz + ls -lah - name: 'Deploy to Azure Web App' id: deploy-to-webapp From a5fa96e8093e12d4af1976063738414a2aa39407 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 5 Oct 2022 13:52:05 -0400 Subject: [PATCH 034/209] Update main_nihgithubportal.yml fix path names --- .github/workflows/main_nihgithubportal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 8c2353f1d..fe8d4e9f1 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -38,14 +38,14 @@ jobs: cd .. echo $PWD ls -lah - tar -czf output.tar.gz ./opensource-management-portal + tar -czf output.tar.gz ./github-portal ls -lah - name: Upload artifact for deployment job uses: actions/upload-artifact@v2 with: name: node-app - path: /home/runner/work/opensource-management-portal/output.tar.gz + path: /home/runner/work/github-portal/output.tar.gz deploy: runs-on: ubuntu-latest From 0127a64386c90bb25cab12042e0e42a71ef0ee29 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 5 Oct 2022 15:48:28 -0400 Subject: [PATCH 035/209] Reapplying Org Config --- env-orgs.json | 14 ++++++++++++++ env-orgs.json.example | 7 ------- 2 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 env-orgs.json delete mode 100644 env-orgs.json.example diff --git a/env-orgs.json b/env-orgs.json new file mode 100644 index 000000000..b263495de --- /dev/null +++ b/env-orgs.json @@ -0,0 +1,14 @@ +[ + { + "name" : "NIHGOV", + "id" : 2710462, + "type": ["public", "private"], + "description" : "NIHโ€ฆTurning Discovery Into Healthยฎ" + }, + { + "name" : "STRIDES", + "id" : 69810051, + "type": ["public", "private"], + "description" : "NIH Science and Technology Research Infrastructure for Discovery, Experimentation, and Sustainability (STRIDES) Initiative" + } +] diff --git a/env-orgs.json.example b/env-orgs.json.example deleted file mode 100644 index b976ea538..000000000 --- a/env-orgs.json.example +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "name" : "contoso", - "id" : "your-github-user-id e.g. 123456789", - "ownerToken" : "your github owner token" - } -] From 65520ea4dfe9f17c2151240165f184649aecd645 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sat, 8 Oct 2022 20:19:34 -0700 Subject: [PATCH 036/209] Add or update the Azure App Service build and deployment workflow config --- .../workflows/staging_nihdevgithubportal.yml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/staging_nihdevgithubportal.yml diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml new file mode 100644 index 000000000..4e3545aff --- /dev/null +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -0,0 +1,56 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy Node.js app to Azure Web App - nihdevgithubportal + +on: + push: + branches: + - staging + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Node.js version + uses: actions/setup-node@v1 + with: + node-version: '16.x' + + - name: npm install, build, and test + run: | + npm install + npm run build --if-present + npm run test --if-present + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v2 + with: + name: node-app + path: . + + deploy: + runs-on: ubuntu-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v2 + with: + name: node-app + + - name: 'Deploy to Azure Web App' + id: deploy-to-webapp + uses: azure/webapps-deploy@v2 + with: + app-name: 'nihdevgithubportal' + slot-name: 'Production' + publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_34824FEBDA0F4C8CACF5CB97111CBFFB }} + package: . From 706bb85818877084857d6aaff36a3cfb3004ccca Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Tue, 11 Oct 2022 08:29:36 -0400 Subject: [PATCH 037/209] Update staging_nihdevgithubportal.yml add additional build commands and tar steps to staging build/deploy yaml --- .../workflows/staging_nihdevgithubportal.yml | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index 4e3545aff..bc81ed203 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -25,13 +25,27 @@ jobs: run: | npm install npm run build --if-present + cd ./default-assets-package + npm install + npm run build + cd .. npm run test --if-present + + - name: zip application folders + run: | + echo $PWD + ls -lah + cd .. + echo $PWD + ls -lah + tar -czf output.tar.gz ./github-portal + ls -lah - name: Upload artifact for deployment job uses: actions/upload-artifact@v2 with: name: node-app - path: . + path: /home/runner/work/github-portal/output.tar.gz deploy: runs-on: ubuntu-latest @@ -45,6 +59,11 @@ jobs: uses: actions/download-artifact@v2 with: name: node-app + + - name: Unpack tar + run: | + tar -xf output.tar.gz + ls -lah - name: 'Deploy to Azure Web App' id: deploy-to-webapp From 4e36e856e5af1ffe9982209bef9289ed83e6534b Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Oct 2022 16:37:21 -0400 Subject: [PATCH 038/209] Update brand.json --- config/brand.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/config/brand.json b/config/brand.json index 482014050..98cc6ea10 100644 --- a/config/brand.json +++ b/config/brand.json @@ -1,11 +1,11 @@ { - "companyName": "env://COMPANY_NAME?default=your enterprise", - "companyLink": "env://COMPANY_LINK?default=about:blank", - "companyPortalName": "env://COMPANY_PORTAL_NAME?default=GitHub Management Portal", - "appName": "env://APP_NAME?default=Self-service GitHub Management", - "supportMail": "env://PORTAL_ADMIN_EMAIL", - "operationsMail": "env://GITHUB_OPERATIONS_EMAIL", - "forkApprovalMail": "env://GITHUB_FORK_APPROVAL_EMAIL", - "electionMail": "env://FOSSFUND_ELECTION_MAIL", - "infrastructureNotificationsMail": "env://GITHUB_INFRASTRUCTURE_NOTIFICATIONS_MAIL" -} \ No newline at end of file + "companyName": "env://COMPANY_NAME?default=National Institutes of Health", + "companyLink": "env://COMPANY_LINK?default=https://github.nih.gov", + "companyPortalName": "env://COMPANY_PORTAL_NAME?default=NIH GitHub Management Portal", + "appName": "env://APP_NAME?default=Self-service GitHub management", + "supportMail": "env://PORTAL_ADMIN_EMAIL?default=GitHub@nih.gov", + "operationsMail": "env://GITHUB_OPERATIONS_EMAIL?default=GitHub@nih.gov", + "forkApprovalMail": "env://GITHUB_FORK_APPROVAL_EMAIL?default=GitHub@nih.gov", + "electionMail": "env://FOSSFUND_ELECTION_MAIL?default=GitHub@nih.gov", + "infrastructureNotificationsMail": "env://GITHUB_INFRASTRUCTURE_NOTIFICATIONS_MAIL?default=GitHub@nih.gov" +} From be18a3c90ed4b813a92cfd5eb4f9f2e76abaa749 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Oct 2022 13:41:33 -0700 Subject: [PATCH 039/209] Add files via upload --- default-assets-package/resources/favicon.ico | Bin 318 -> 6518 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/default-assets-package/resources/favicon.ico b/default-assets-package/resources/favicon.ico index 25518e0cb437af643ce03bfbfd6d11a08367b8f8..a59308e2e7ef39c9aa77eb03d70fa1c02c738429 100644 GIT binary patch literal 6518 zcmeHKOK4nG7``(#F-UJFcjmrkGEJv3HpTdY_(DMjK}3)WLN-!CT_}P(LpOp<2i&Sv zV^wq`U5FcTrMntXi3QPiAx0%w3w5EXO`1MJ$By4ObN`uh&zw7xPU>z34(FWzeBbx~ z_dn0Etdy0u#>OnvC2QZ1W$m>rt5k~mu4V0qZ69oa0MWFgvMktp{TwHEFqg}HGden& z6>KJxaU93}9QGH*W~yD+eK(hLYbdK2&nuYF^MX1H^j}l#t)}B-7r{FVM-yZCwFa6E z8)FyR8t!N6IQ+iPvEgCoHpG1Z@h+lF3I^@FA=&UR8sNOaaoF$5*qJ(-o2gW4HJwh^ zQ7%H~e&LUdjFe&fOSn=a*4tgz`w*oLZVhR=V%yGx!qaQp&OU(e_*3}VZ1w}>bXodn zKcREJ_Yu>?x<{!O{dQpPz7^eGHL>9B5VB~fxk%C=#=vb! zAwLg6{|L%5Vqa%rn>LQMfP+RO13V{7C}k9$r;Q)Z(0+fOH?wnMV#4XgA0HntPEAdX z_QGv--1m3g90cK8ST}3FADl0j%Qtl6`hK`d9O{K)v3N^2Y_~Cd!;R3WpfvWhtlLtl zG}4U++*QGXyNOcm#nJVcLwv)JqNCO`Gc&_FUhM<>uZm|IS|&!I&8rb1Xc)o}8S_1VQjH=IIsie{J(S z=K^QS+vHDAPusw)Ct$C_Z*_Kdb_*}ecr?rrxbx6W+7Ix_9Os`*@Qr;N&c{`+y@%XA zldMnQ`NQV%@OZsmZ@ew8-D{kI@A$&(BYzlU-!F#(P%rLH`%9PtL2hD6W<5dyFe!9UkxW zL*HTRe}ar7u8r%p_9O~u8s?e4&1V+RUg2)H#{7@Tx5ex57~)!p+nQ$;><72&SNQnG zXA^uZblDpl`Fwu2X!Kj-9?RidVt1ItLf?GPpx^l4CU&VY{&c^7g~vC9=xOzuyrmG| z5pAq-XX5*3MW^4I?=F)zeTruE#@Ntti2WYHu;zUM+pVVim-_{|-mAaSagOcLb>SPn zN};L^TUE#Ly+aJ&+|YRrXGP;bKF7;rFL#R?>G8VeX||C zx0m8Egg-&+6X5@j+dJ=b!}veoev0zFItHyJ)BB4tFekvDR`J)jP3?Hz=~w;ve({d~ zCx-AewN+n9?Pxt}bFrnIcf2*3KjysGck8i4>!Av6$G+I=oREuBO`31rr>P(1g6D(r zj7o?F|5bUWbf0UJza$&?6VFTN;=bUW6)s2nFuFsVcZr;-Njd}jAOnL83^E`Y_zzV~ B;@1EG literal 318 zcmZQzU<5(|0RbS%!l1#(z#zuJz@P!d0zj+)#2|4HXaJKC0wf0l(UB1l#t0<=o)7|X From a97d7edfb0c14cc6279a21eba26c6c2cc0d479e4 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Oct 2022 13:46:46 -0700 Subject: [PATCH 040/209] Add files via upload --- .../resources/favicon-144.png | Bin 534 -> 11511 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/default-assets-package/resources/favicon-144.png b/default-assets-package/resources/favicon-144.png index 05a3c2ee450d2f30b4b4391058e0f6d4af71ca61..5048fb00929ec42379c7d0a25788c7c90aa331b9 100644 GIT binary patch literal 11511 zcmY*<1yCK$67D&;1$TG%gF6Iw4(@)?;O_1a2=4A0B)Ej&8r(u4xVr{>{P*5>?|ZW~ z+daKse?2`_yHz_q(W=TaACL%<006)TIax{YyG;D2Bf!1i_ocVm-UZMVEF%G^n<74Z zAB0)z$U&5p0F3WC0st0>34s0w@_qq;gaFuo=>UK{km$cU7)bvg3={wmX#;@y4@U1@ z{?nG<`@8plBy<7re~blC|3xPjK>ttw$IS)K(eYg%I?3v~0ss_z|8$^K8i&a{o34$9 zj+>5>qJX*MCstDnM>9)SuTM_@cmagG1m4w8mTsoxUZ3n8Tm`&@DgT8Kc-Q|ivr&@& z3*u%cOsS)!O8(K&#gd$dm7SHHQUr;doLtDo0wMsGl>U$V`$(A5+Re>LfQ`-5)05Q` z#Oml`#m2$U&(Frr$;Qda@{V9}^>%PG^ z-A$O1@}EHeZU3I9n+@cDksMtAlh%8JZ2vrA<6vcH`!DyqtI$7I0TmY;%lF9t@QZK= z{R{d3+5Qtpi0z-?|IcLpo$0@<@2QF)39aVVmgCw6^3I^P5jp)Yh0c-DolA+xvqQ z-h^B;Fp-j>@|z5B{vpsn$;{B7DDks~3z`cbgmE<8Bd-HC-0yn)JO64ekW97TYuy{> z3%F0MSmk#w86CGS8Ts-((RQFZ%C~K~vWh~InMaW?R9S^A6_4oIn2^{c z4GuKIg<_BdOTKHe&PVO8%&Vp6}}u%Ljbb0<8Q@l_h2)C#F+Q(EOu))TKC#;bUYr zRX28aDvnNUA}^NGe}AxC82d@UamM#Evh8Oilh22j>cz#yzNhOiZ(uq%_fk^CU^m$y zo8I|5JeMAW@12fWs&Gi$0!J0aX*jO!+Kij6*iKa`J|RI(dgQ^($`yeimOl!HhCS^- z0tp3%_KWu4bJ<-dXjfW|rarHV9Rd&cHKa&PhWGSCxuc4Eziahd&o)V9x@4PVq(vO> ztzUEcXQ#;m{>(3J<Iv1!u#1+FbGn|Iu&BwCJ5$c$@L|MUyicUB%tmmN>f zxXMIBMeWg9?G?N4E#Gdo;AD8tfF(y7V>vJ`kN_*AqTw12Nt0?Uv*)++F9*dG>o8;P zvy$-QhHTPuyQ_FPXbjbiMQy;*ujTDQ2dN4m^=-NRc{p2XIS!HJ^p4Jo2Ek_4z{gMV zGgJ`MpMpgI=6x;&V=2Kl@)aE{^tg^X%WJ-KX)OA*^yT!$(6K9vVzzids)oZ958(Vz z-RtXX>Y>FI*sw>x-?$jm16R)Q0?$3*xPR4GO~*GKtBaJV6ywXPk;fw7&u`3ZB+A3X zQ(|`j;13f&z3wG}%}WtYOcOOxTDaOBUy2z;lkYfBD)7xMs7wWnKgZu;SQ+Mc^)lDS z6jJJ8wW?@tDGZW7%#VzWB$qH|TF@kavs+#LAeQmTu1c%U;IXJcwM{;#ohwxlvcs#Y z;A)mZTT9S`;$ugv#_N<2!)Pw81nR+Te2}0_{cHU3oOiErLP!``RFa-0}M-HuI@kAjr!c=I-2(``Jt zTCB`RqsybOQ>%&|3RzLxKV~MwZ_`7)>K*kpU}DI8qq-nZ)Y2b@9GiW6cB-4v6yIbR zp))9Vc*E%y7H;?7-WJvLni-v6eOkec`K#N+f?lvWGQPyG)z>cG@8zDE|51IRu$@M1 z&fzs_wM}rryi>AgMjfemYo=@Fgf~13vEWN4j@R$XyJs@Z>JGt4&2=9*YS_`l;CVTQ ztL~3fRL1U=sTPKwN18p$DG;b@#(;^9B&>(P6b9Ja%|iXvn6hShjFwMa7HOqWN55Fe z{b5%G9Ilo3zJka)VO?AW)vL8?kJ$FE-&kcX+;9lllRV-1W-68=#HiPrEuQj6-Tpp* zTKg8yaS9sOE0uLgz!4)A%DNGf)7sZs_=1z6?;OAve<)d0!HD_&KC_=CF)ngfsaLId z8Og2H7*GJS6_6HY-xilp6S{sy}i)WhzAn#{mtVq7v`!h3h zerWj%hRCj(rqFh4=nwQM{PgDLpy4PrtZe%?!tuF6FB*VXMFm5x&cm6!8#-#HY9SRb zzSM?iZ=`ddN&ffi^w8m6V-<7ASUJb1VrV!9R{>*L#czTSFHx(;0=I~-F4 zlh`WceG6BIzMYTdC5DFb!z(h29>@T_zGVPH@HR4bJg*RQYdxC@U$D(3DjNapNK3df zrL*;Fpak}y2qo>#IN6}}!Z@h`k~F?}%@y_ZPy`?BD{F`GDkeRMEv|vl#Gu2@(Pfr8 zA;{x%K$RbiwtPUh0s?f9K;Y+ugVgruGZ$@zW(iVF8vSHbh9uG zd<@ui(+L4G>SUrf9d^{|5rCaxd@UCJZ(lRy*Xsv5EIo8?7MwGPX5{_O8{>Fb^tmcm zp3_0u8}w0xK=iV&4Q_|CRE>u>p|HId={i${NjKvVG zVo22zJe1d7n0xsg@7N@~P(WBagm%oR&v7fNCS5h{&aYRJ)<`5iCEU44PRW-z^vpma zsGQXtT%W9frK#chf@QXY>20l(C!J1g;uKx*5$XavhsDdW>Ga)zao&xIYS}j z=U_!&o95wZ5xKl*Z4!Hr7T^F;*vhGfRb9d7I_L__Yzf26pzXo7W;i0viSN97Ay(C@ z<5xi*DBzsx=G}ui%JHaYXV$`L8t|EuSP?t6cUJWg6Q>HJoZzCN43@&*&-&>OjYYT7 z!kH)AQo^Z}Q&8=|FE{TK=Ij!asM7gzdby5J-+6fTxVMr9QcC8+OzA>Ivt~AqM<j!4S*F71Ub*Ww)q!5c5aOw%t+u!iw)7%B&_<0{POvTd-80tJi6X>~+OQ%Sd{b%ajd+vrCn<>uoH-#K zd>V@RtiDwfIp-B5X)ppov6;^n6~yugQ@NRTXYbBC|QcYWprJX`G=N z6HbVL4%%3bk1nU?jBCZ_tADp*+kM9j4V-w#i+T9U-y_?(utHmUmNM7BU0$h)flWvo zr;6GOfE;AM-g^nJ9j@7)R3dhJ7gGBjU_6>EK}j;aH*|fNhiS=%@}>R z*dkTjM{rvX%v-w~k8ck8CB}Mh5W^w?027VUyY4Z7G&UMi+DUC3&`2*_O;nS?j&Hj$ zxV_zNhrIp~Xs#F+lO@`7D7NXSzPQ(G%BEK*`p9 ztge<0Y3(t$K*EA^T!JMytfaV%-|gXpDiX*_+mx3vUR2$Cv{%8>L=X=UCR9Z+7rAC1 za^8=7TwpR%hd~+ml{QwNIS<4o;B(Am!4UX|@wXykb;&}~kRSdhkr}44j#fxK&K)3R zQ+%O684}O`^s%>vguBOXVRI9<>L`#dxlz8WQSN*3?9R0NFDfUYoRhNvpW|S`@X0)% z4=SImnny>?OT*I{H`G)1D+S2d+HaBgeqi1`-Rusu%FY7es|VDOQyDXtqGxG8GzGL! zYf#jYm9j1&;%8#~YJwWUagmRE<<0!vtFC0@ob1ZAeOy-VIVq>?w>6aQcngK0V5nf-F~iF_!0{~9%ZJoS+RoIav6B3 z%zzpGrIx>V6m&DM`7PR-+FEo75~}EmVR$pIyvQY}@E!2b%4s<9!-@b-OV$yK-^iG- z9sdZ-_qT~f) zGlh|OpN_r0YJaImt>+#83jkE+A~PVce*N=+e)yHWJnm+VZn<#asIszh+h7WweZOCz zoD(r6XT>0aEP-EO-q8<7g|LX=7ztb{8Ws+WqRnTC4dp2A9FHh$ zf7pHIqIh~t5C40rRk)DWC5;;bMLb_4smr+AXEobwg=cb`12U{S*hRWtazr;DMp)ru zD2-C%)Xc-3h#plya7~V(O}*mFJ^ljoC2rc8j^rg68CJ}B48=ILl(G8u$=WKZoY4mn zkCZDc8;ePq)oBDW&!s#xGB+201{IKH@$9#Febm(phX39=Zh>n>p%XjRLDyl@s~}x< zK=acFaM{&|)`a-Us@9OJnt4IChGNQB0*<61$37==j-8lAE@r~w`{n-{*T>OeMh+>jat|xQ`JgUqh1@3e_vz5;P)yTcHAiLYn zj>KHZB$;Y#lBNmuwLQo}B{H%_q8fI2&VYDs2?zk2dw#R)0jL^Ce%RXPF?o)(D9R+E zC8|Z-?fK{`571qKDYtlFwP5(PiawF!xQGYLX-I)@a)o$fl8XIVO_4Oinus#9>q!wX zrr3lr8YT@uN%kFX$oV>Tn}a#RG0sLHLZ9o8l6gd|Kd8ORH+M6{!#{-r%An{2J1Iy! zYJ|BD7SJcq!a9mn9wvRtwD(wVnihEqxdIN598*!ui zJdkB}F0LDt`p6Cr+i8w9XI1$?L%^tx+DsMyBvUII#Zlr~XFI!?76#Oa||a^+lh z5`^+CSK~pEmLuzi;UPm<@fP>LChAsG=FA{L6D#<>*#*xujoNcK<=c3;m*{Wx{srAA zz4YTE)FiWy(c?vHlXn+q zW}Y-po^opZ$1zK(?Zwox3<`x76B~fC`z=U)nGs2R0E=j(yjCWE`YDcB_Q)T{qTCzz zT>(1)>`0ith}#lN`^BVSpzMb=fpi;Ut>FF@x{0xqa*L`wV`g%i(;pd%>6j4O=Q1OZK<062s5Wud5Q7l^}+`|Ay5%{_hMT%b- z5J6DHBu;H}iZi14v8D4OJ32e_-Mt5R%m~#9_C7Y2iB0m_<23!KlZuwAOtVI>k*0?u zhpmaCDOWuaIi%pdQoP>%(T|_|rY75GaTFoDd`Ih`Ck`jq%J!SnVL+U?M-Cy4{KEGM zxQZHt?$sQoI7wc?O%Ts>h*W8#Lfep>laX<-uuT<3c_WERp32xDi50z1LS#y@uC$L` z38OfFMPQ#iE35uHKVx_VgRSdA!k81E?0lvv4}Um_*$yZ-?k$L24AUT1W^h|Y*Oj(C zGHnVwaYNk_jhR2s97R>EoK>3?1ZTT-;{PaN*;!WR(;PSOE!=zp5c8ppkoN-G&{X+- z?g|AZf`;s=7|$UiBlNZiv9)lEMlMLi-J^1wnvpM1T%4g5V&P_)9JLF*!oH?;)`NwP zojBrLLnpT=f-bNbi`rbY7+YnvAQAU*rBO?K0u55rZG-OGYo-<>rfwne(?1rT8B?;p z0`DEH*uP3sXkn}as6&6&w<)aaC=ufNye+nc<=BhKev+WS_L!S=(marSz@FA^hgPJq1 z3-wqdc67(t!H(2#O((?`^s+i&IAmq)VsCGs&)MkB2s>aJOdmEGdALR0TzxC%{MW$3 zneWT!yah2~Xqx~NDb;i+i5~`MW2OtmxM-XPklI!TJ?8|o%){-u;Gjg2riELp5lA;| z4qwJW1Y?ebh_|57zBa+E6pOV`E5A>2m|m6MFjl$-RMmj;P)fDv1UCj`LaWxO%k+=) zETg63!%RCB$BDZTONzj@Ovc_4DV+2!7h2Pp_{=-1@Bj#8F%f^nS=I#6 ziPv)OizGnegdRC@5_{y9REZzM7{~(Nl*+Rlh0q9Mw{AElr{DKu5IL^^K1CBJgQYqF zeW8vLQ_f_igO49XECme^26mQ-6q-QSv-h_a+SoiSM8*RUKk@m@{Sqk#xAJf}SL9YivEIrtS@Taw-vRHP?Z-KK+A zyFmysYgggz#Ds53T7NlqRE{HKm#7qQm~Je$nezF6N*t`89czmbKithGR%f5j4IK`h zX!v#MjM?)^sow$Pk-H5k+PUo(-Ee~6C_H124*1J@LTWvG@M}E{yfo_0!?rKF?5p_ zKC~~?|nJ9>I2<_kdd?! zHdHk|{@df_#mI;wlkp8X&k0{a^hJxIf78wqp-F=*#Y>?Z0MJK0r#rg97;ghtL*moh zQTe%s7~iYds8O#1WU@yO-{XLWSfrQ|KW4V5o%ZnD-Rb$3-f`@RFJuVz3mF`Fyw^Xo zWMt{}?mq783Zg;e0Y!jaZ1(oYgMk4rW8)1D!UI9gQx;l#pROy|B&*Pq$c$y zE&|e7*Rm$Y_>9_ls*6CDqa#~6ofWP3pf7X7)Z^|Nd^oK2QMCZH5at*9%_c$50GWFY zJueoF@C;>0_&kw-csHe}Mf?}W!Q1nQQw!}Sk}G|lN3p;?J30RgkC>W~NSG2{gcR}$ zJ(9K2DHN~B2F9L>tr>N{Kh6vcJFj3*F9@o3Z_76O@>S^+P5#M&T%EM zS=!dmr+%7=u^MID2-=TPc9x6YJndM*tXGdspqJ>ZN&s?1{1u9o87s`p=4L$jAso!N zZW}OaMO(BqM1AMn$M18tuS?(~sbKUFZF`Q5f;#h(EBR6VUYvB{4+9>DZRr?@fbRQH!Ro}Sj z`hfIPKCN8Cw5h6OOCdggpZ8tdBn-KtW}Z8(OGRK&h#D0i#LlCu_0>OkWYxh3 z9We5!A(+xbK_K8*jEg} zR|C2Bo8rO!C@!;3;?gwb<&%YEeDas~-!l;xTU&X%U&+G<O-I|#b|~hy;UIJg*oRJ6fE(=1{*K?6V$k%j`M>fKo+8yh>)tvfmW&OH(SA$z&a=& zbYbc>r)WDPfT3DhhxX($Cj$m@u=fdgRq=P89$J)_aTp>es08%*b1a-Ezc8plOWm4r zpatsAxYO&EWL;W50$B+?Pz&#zE|A0G=O&?x)!2Ekz2Dl8yGJXZ6j9%7#%EnKWYRxN z*9KcD@Tv6ZTPVz&O=MId*rAxH@+Pa}Ht@|@sTVI$Biud?V_+fyii>AGF#)4L-XG!& zS;Kqeq5S1-tZ*DV0@+y(V_GlJjES{mOSMg=%2esCSL%4OQRaFA#Z^A17Mn57!0HVu zSaE90J={Y>a)32ALNv~ z-)@CYBG{KHkodr@#13w=& zVa|b|Mx;=Yvt^%4!^B51B&4X*=n|mZ>tnQY=HVnA)8*c@&)lhXJewQJtqeJHMdCdt zI?+OyoT;T;p;BZQ&`s!+F8x^&ZV4wXs_D3j$*bg=#`wN5OYQpTU5Yvgwb6Et-Rl#? zBPHT^S-aGPOb?~vK^nE8n$_E^sHrU ztaN!_@8k*ldR%5+7fHoVsS5gjbW}kTc)Ya#C3Epu!`LUv;CsVf{cEpL4EsB# z7e#ufG_GZ5ilS!^u7Y^7R^ra9!Rxd)v$0`^Tjl8=y7IrZD;h_F@AZziaSM?*4~Cp) zTcv!@GIgWS&td+9wRzQJF3Kt;!B0ZnX~yTPw>h&9+Qc@g_F7V0iP{?VoY-?LhVd43 zv~`s{GqwN=SBommIC^8vv<92blYlY>KRR178BBBhNU7yyb za(k0R-7@XQDk^W0h-h-oE(=UEJ6N0(n#gS1*X;jTm<%;+>)jTp#Ahzqh?=eb_$)wd z({I7kORn0ja*56Zoy`5j`~}KT)s%bri*ornouL|i&P9jrTP+k!<$U)Q!}1G^?vg&k z)*ityL2f{xm)p(wSX{k3D&ckI01S7xUXk#GUGYTmW0J2S+kCKCRjuy4?6>*xO5bna z`7^m#NU0H(C|{L%vR|YeT&@&@M|>QiG!iIyIAWmq7%x%8Wb;8{mXi~;P(t}19v^A} z7|*!e_LqhX2gE?cQg(|Oq^BKJ=XnAS{Oa|@+n zMt^M*G^Fv!-0ER&657%No23^IMX%J=1uc@!7FO5dq1HkNmR#V1qzgyTXq-0f=bnLL zed71REK;|ODD%I{*rV?CfTUMKEE}3{^^egpUHu>Sh{JM(M4w9CX-)6eaw9QKT8RB?{lvO6lLY6TR%!Go1+_R z*PovI`uHw9o$1whE}B4We#2lx#{y~X&+Pph#I74`AMqCM4BJ1s-K-6{eIoa)m-K)V z8|=x;yLCC5)?D%b^qDyn4r{E^1)|B+TbOqdnW{B**mh)be8yVd*||Ywcge_bsgp&J z`xVm_V^Yp&RkSg2{H3Q(l*yRB^pO*WsAAN6IOg@WsdM(w*FZv?F}>5cubnwvc|T?P zICa|D#p$nQDS*{g-#7I@9sH9mA|kT2?fyCXS7P8MvgF!7p8%tWS2t!-LO3~&Z~L_yI!iM6P^nUJ z4;Kf_j_{kiJ#MlT}@ z7<26bk9~dIT_aFTxk3PjC|zla;~ulZ3uxPVOd}No*>l6}2?$v#jgNHCoG+sJ%a=AU z!5&?L7CkizrazozoZs|(Yy>!SVZV0*KOZ+fO(`l(a5HW;M0`LEkcjD&@9S%a1-O>l znW(uAEdN|tla_w{!S+JGO-h|11)i=qPKz)Uzg$7mDo!4?qlsRRxd8T7C|)LDpp8dH zMh2eE2BTqRbUNNulCYo`PjVUNr;J}%VIl}+A*+3M+5_Jh*c4e{V_Wwe6G`0a58`7* zEjDFsTRKY9SxOrhXF0KPi*KWaxr)JMT+E8e8KsJ;ZT%SB)nG7M*)B7P01)EyX^Rjl z_%Yyh@i5-|WLiaq&g>Dv=EWLNmd5C*6m|VVc!ZQIDClm`4h2xc0nt#;3%-U>;mhEx)@F3Z#cUsoWkNMg@BYnyU}(J2M%Y-)3;hICzq!e$?P2 zAl~jg#dV`l6)O2a66cwsHdbH`5jNL*Wr3xfK0L0`mAOEL4)Y!X9R+4_HfPj}W+4kF zAB^|Xp-6j;qp$61G6TR8O23XTWe^?PAU9%S!H^#_H`HGaQyN=3Nkb3dP95(aoBWtn zHwLSD?v9N+vY-1Sa%L~q7k9^{d>m7lab9~phXI3yhM7IDSxeC{KRaucIrfI2)<8&K zop{`kR)@yXvVn{ES9%tET2u`ou}~}nUO03f{dmRBQ335KNHrMLBs4o%kE^Jhhw9aE z5u>gBxmw~c{QQpmv>mGX0vU4a1SU;#>v&ZTb2WIJ7(FNvLw+PNb&>lVyqx@ATjHq6 zTVs{lysxVG;~&$iSOzIQ`#hWS-FCNKR^mxGp2&avy4b6>KueGO+Pk^xJbOkS-0TO6(32#(#ogtf1Tp$L1abodj#QivDe-=U;{$8Ms?)O z9nhr=*Qi%fR;{BvmyWS8&&n`kB?J%!rHX&N*MwGVJ0i!~l%Gyx_5%hXk@wVa_#S@c`6_8+ayYk8XIaNF zO;F5>BbI=Cj`y|wQE9c!I<#g+R4tj08au05x~8YzJD$;2x^UsL?|Ptmcd3OsRffk% z`OC_OmC?};F339Ga;1{#@gudkM)J=3KyuF3uSgRtokpXCFG;quL^K7%I?%QI2m{lR z7`+hNa-)n4Hh9-ZckW#%rxD6{d+OrhUHW{c%x=5YecqAg!+A!4u6S2RSGG^Uu+UzSGo=;)WUp(#@yXQ`O)&-qhW7_giXm8Ic1wwVA z_Z24zncj;XjQ=t@>~8GVSkxXfWu;+ut11W>dGLV#EJyov^Zidl&sZCn$Gg}E-&i$_ zfnRoUJJAW_SB{n(5fA0F2L)rFeMy?!T5pB@mGf-M!WnWnTNUT0dA(}Uh54U}*$9>x zK5Hoc%^!kt++u557hAaP^s4@r_~578Y~6SvUO7_FbM#;&Cj#LGD9&!aiOy?&9dWQc zm3T6NNl`RM_+866vbucl7}NMMbx%D-H}wFlSw@FVXJ5yd?y2`>vb%P%nJ2yar5)(h zXThD&GUJCz4d~V%9(RB6$Mm0r5W&bI`j!UaRj2b7d13_2`O=MHg}fEvKBGm=&<&nb zUJem5h)S3KRb3^!6cK)E?2&j}{pR$-d#>M9=Q^Ivm{BQtib_5WA`e>na<~Y$Q?Chf z{|dE1IrwlZF@J>^-rZE=yT*8tay^w`-^+A;&9>Dt-yE}as+Z-`MERTC?%Mn+iLjDh8{)u=1 literal 534 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$a>cv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F#`j)5C}6~x?A^$fq}8g)5S5Q;?~+UhOKfBKOXLh3pk4ut*5c5Qdjw22#Y)Xa#oufjOgoL!P7qhmI`Qr>w6nVP(xvX Date: Fri, 14 Oct 2022 13:52:06 -0700 Subject: [PATCH 041/209] Add files via upload --- default-assets-package/resources/img/logo.png | Bin 267 -> 13525 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/default-assets-package/resources/img/logo.png b/default-assets-package/resources/img/logo.png index ab5b790746cadb8d86931c73e318747b0d1c3542..ff9172a84c388bb3bfb49a6bd89227a8b128e393 100644 GIT binary patch literal 13525 zcmY*=1ymi&((cCH-QC@7;~w1I-Q8V+TObhJgR=?2ZQ~H!ArLgUyW8X3d;b5uH?yX@ zrn>5@s;)Jwd)Cy%sw&H(AQB=1000zuIVp7j0D|#@W`&3SXbV;~6F)j=8*wFZ0H8h@ z>BS7@->0RZ5|4gegP0sw-U005qAZo3-rV<6H>SKeAl z3GfdnJOBm)69Dx=L42G52tvR=Xde{d69m!!(&`ZO|H?oD0MT{;=znGOKl*=2=6{<1 z?V$=G{x4!7W8)Y!d@T zqb#p7L9|&pV6y21=1o=8q#@(9`tCEMa>MJJ)w4>j@EUxj8`^`GuCf*4SB4+A8a?~E z%jeQ1^=6ftj0o+v1b-4}ch#1LqiaqZSPHC6ycY-Ys2o|UM<+t)z9|nl6_C}Aj_h+) zCPeL_4O%DV@jpvBj2u2f5$?kXlkeVh!i-}7_Gjq1^6vhsNIPA!ia5QhJ>DgP4RbHX zn>O-UVk?L;Zv+`ClC~nCR%EyCm@6Cj-dm}*)MqwvJzS1q=|Q2ryXW~8LLzb zd&fpBO#F=j+fkbp5cEJ5LfD7c#8CI5P_EqNTOooxvEw{;H=t9f`T5I0W~leCk?$Uv zktK-;a(Pde@%>c>|3;}UW}TKh`lnMntOjw{y^S=`NoXf`$B*)H>RbSguHB=S&D0WO zdp;ymUu2B#`AVh0Pxf|p5X=84rvSAgSRkE2wXA1R9s;4t$yn}|(uq7z*+C3X*|FVJ zXZL(@?N0QeDt{OnnWAh~jTX&7crs*v+5v zOB`Yd>#NdC;7IBoa^Impvm_+mg@zt3*^cqlm(zS9@7Zx9V+x1N2?K`YQQLHe z3o@0kT*9aQ}*G5VJ4@QN0`|3RmY=)@EO0zea9m*27WUMuYUUO)73I5 z4&NDH@M17LL;1Sk)rV#>^gn5B)J>GR~s*;%Te&8<4Twx;fwj~d;>2mOx0zr4Np z)qi)C29HC3GuR;#q6+z4wD`NB~%O$(1}Emi$p8uK<9T>=9h!A68paC)JZ$09ti zf~wWTCC3>Azm%(Em%tWlFnI4^co&*+{~XOJdA_?m}79e_Qi z`39`>ny}s&2{i5P%!q+5>AYh1YWv7^K*CKH?2CsUClDFEJy=97}#0TaY)(89arx6 z`xn24q-D40BD%=}zGpG${-37oHMbiZj$BUY*nVSf<;{)bZznGq%fseUuYkc3N|Tba z8@;x=$pX=R{B()|XW1C~4LOdT4bR<{SzHW{^wEP~T>F}JnX884em_^-zx0fd0_Q6_ z)P^;OGb^(9Zf9;?brFe*IseR<{^7nb%K)p3ye z?9QlRdR){a7G4#ThX%3D7jAyK(zFN37B}|0Zs~@gm-KQtrlXUf^Z^&PtQehYB$}SLG%><$WL?rM7L|Wj++fE$N z+Os`MiYm^fPFQU~*HK_hH4l-v_OyuR&*4O(eHYdO3FoiA#S?Hdve#;!mXv|?Z}4Ed z?wOHRwVO8@7&7j+5Clwv^^xf8KRM`{zJ1rr>W(uB1YCWYDj^crZHfFeMN3m{#;I6c ztWWLV>9AGpu>_36Z92RQY+ad~Z>^d~KV3YfN<>k}U-WHxR-!N(RkGEIi&rxm))u|d zBqo|{7+VRot+il5Kk8!_ z^-^spKV`l*Y~CGP=e*h_EztZ4?UAB9G>(Zi@j=2zB) zgxMky?@p+~3crKkUe3R;cVABmd400yh=n`{w;aiSJ%{mq{1sdWG=81fyX`@W@TODF z)!n_9=9lb9eZpAC231zy6#5l%2jEJ&A3~TC$wYIM4vj7l-zjtn4(*w`rkjopWN( z-1&>G{tY}7TBYpfjwu&mM7Fmr{x4j(%&lH)50`UM+r>4su)Y)FFi49|45%n5C{(Uo znvoJkEyCbn&zpA!bYvDHqVfW$JfcwkR2XhFzKL5xs=x~zn3~UMPq=&cdc;gYCEu;I zt9dmsqh&q|q9o3NV17#-G{f_arjr(kB4(@u0U0iX0ZvGI8nO>TZyNiPUDux*CIy*r z6J>mUSx3ZvMzR5`h@O?oYuwkrf}>T%gE!XKdF7ACBDS{b<;4eSOfaP6ktoZD8f>PL zu2;+B*^$oqSjiFKw^122S5LZMz1r6OGn2n>-gZKW&9tfFPg?WoSDSEoG{MGSg^#3_ zv*n70ENw4)df%>yAlt?niN@oFx9&qeapLa0j*I++W zeR!je(gf^Y6ScEwB*TA|6G@%8H1%O@e4N@dah~zG`d|&y%RObS$j3UXniA18 zFf!_}@$u1FOQEo9u=se6hss2&Yn_n2GSJihqJnBcBnt}*Z4E~0e7RPRIGLM%x5Gfh zxFpiaS2uhy#4YrlW37EO*u9yxgk!n^89-=HpM`n}( zsO0iZJKj+SjWRN1=lCGt`+y;l#~OvSFK9UV@BM2O%Aeqis`P5_g?k53+Yqt;p%Ku6 zGns(f_g9j`VsoNe+g|OuG@38=jc;k^TWiFAl!xDr9Guv!6wDZ?mdIVz$Y_mjWvQ0S zfgH0^fD#=Uc+{FzzBMf0vhL6H6jj$;*6h5LlypbzMU(dP%P&?8+gyV-cXUEs59_&b zMpbl8&&+7{VN)6wD7l|r>nCK&`Lj10nV|*e6cp7LKfdj?58Zshl=Vhc*~UiZ{;^J* zuE!)WE~WGqm`xuwaq`Qswz48d#$UaX$<||X_WMLzea9p?DVP+p3NTXdYzE0WSW^~3 zxYr`$vA@IT)g+_i*crUYH95)Y`E!l5k2>nEG%>{CYBZf`LMm!g{c`a#vrb&(kIhO; z%P_jsgg!Ct?0iI}53aksrsNoOtG+GBdbVQqd@tYLq~!<;Vy76)gae%u))JPn=%AL4 z8%?_*mX_EKNvAYu5JS{MB;;Ll^2)65EtAY@;dsj2Cvro^xubQxwy$rO??RjD5OLTz zB1!M->k#(!pz;&79Gl1=Qq2PF|i7Z?^d#OPz;5={7Sit>(_5MWPvWO+9s9wDB1Z*@sa)NX5}fN%6G zPx7NRb#-XWM(y0PdAC1|suf;lbJa;qV}@9LGX;}&z3Fc01&5Ec1tcc7b|)fIVM;l- zl(SZZp2j;y`7+1)G5+rCYx)cZR10zA8Fp_ZL=Q7J$x>=*3#P@&$sw@D$>vWOV;|BA z%CoO^oP(D)tKDy#Yz7* z*oTNv<=0S$Bzy(-nNr^j1?hU`b{N8Ru}Cxgo2vrh5A73amWH>7zCJtAT{pI5n7(wn z&4$@hiRw|S*DYNmUXt#w=Sq9_6Zo{G;~3~{Z6Gvif#LDp@uaWxWKJe$!j=r2UT zfcrAt;TO$D8NW9-^Kwl}kQ59?=ty3SD#pn`x`gcxcRn!apW>r(D?^FYG{14Xte*^r zI)=p$eRXgI`milcE^(cm7O5fPZ0fBDGeGcp9nIH2<^~~45M!^gHv-fBT?*Y^CcIt) zHnUS=_swxn6(2#dk+?-di0kupy7hPO>=;y1_ar+HwK@mK-=B(I^V!W-lxv0?$GJ`PIE|+P}y$n zQY4(uDdq|ewIp?*ck8qJoFUn(VAeh{<6nw}qbd~(rjG<+EO+HRL^j>+llTx{(Ytyu zLY=L13md{2h*f4(=Ao^eGiUM~vm96z1V0^?L0u0wL$WK9O~_O{7Aj$%;!dkW2a1n# zwx^olFEloARk+DnD1N^x*A;Q##@SBV2&(d$%-!D%gCWf)Z=fyec_8*-{-elqyAn(P z#3S({(3>hYTm@ehB2*Afm)H?@fgt0muTA6ecMRXD&a&39nG(MVesFcHTsMBE2>pi{*}nE)9y zLg3B5AKg;1auzdc@X!7Rf#X|U=@Vm9BdppOV;zjd*V1O^3lEJl#YgOg)$Hso$ymXF zl%=k;a>b5HO2Su*#^T~E|0OudA`|6&&R4?TIcsWBUG}ejdKVQQEGq*G>00UWvjq2E z(0!Lx`-w0C-BXkr%VG>);3YH$QmsS*Go*lMz1-+db%JU~P|P3*1zJ*cSjD|##a@xQ zT>;|N->Sx6nVPt*iWB#lmG%y6XWPCoWXVUzOKC!>Emtkbr|ysQMFex1&~J<8y2{!h z$Wl^Mtj7e=&37pMrPxDH6-15gM)4*u6@#~zEpTYSk#|JYs>S}vHMGl8%LXr;aE9)%>lVyu>G9;Y)?4;QP|3 z?d}?Bfv@LG|HmfxsVx?3YAvkFANY$4r~bfqQ9PB$Rd>xhBG|$Pi4`*PD~23w#T)r< zJPAcTN&y#URKCnFY#u@k!f#vUk=WNqX~Ksu3R(+V**ZEh7WG8^Zx;>lxLMPEc@w1^ zh$O*r+V_?zfvepSHyvV zyxV!zJOprNUaO@HT;RedHs;JH2h-JIu7z8zc}ny3L-8?0{^ob0QEt@RV!^uePZf}~ z-U+x6V62X%>TPQXftk`Xhk)86t zu@AfO($Z~{=6uV&Hh-e&QY+tMe~exwH8`GTH`fUWIMDKIad1@H5P3jOKtfoG5+)AG zP^ZR{^+mtO-FuQng@#~?1R-wSlQ#~;@d|n&PL#nKmaElqV5lTYtaWRse|-aG`-1cU zzl=8`BBGHAdP&_vIKKchm%=X32J$}klakYA@qsM?k>?qudwUMlGfVZAmjFoz%)LA5 z5vk#`5#QAwWLU_3r7TX1^QfrnXtz!GlFi|c?X*;c3&nvcDO(>@65bak+uLvG>wKVw z>gzwfrefBc2B*g>bdOH^fd^O|H(@Nc3L#VN%T)fel^ZchZGm?-B&QB4w{2~7nXDXk zz0BTky12X6pMR+O0%}I~_x#WDd7PY-u)CQis21ktazD{3%MkhFh;x3dHFuPIGgneT zzfX)%XdNB<+FCm2NoY4V;g9P9)gmSY)r18jmO7p^f9dY11MU(+GwwU&=+K{uOZk8#SUQKbgWj;h5 zk|8^6^Qhtta#v2OZ}HK||8|z|p5I+QbiQkkU~AnSv1&2SM10OY&cvp}fF4CqGX__o ztH64_giYH$t7HfCT_cr=@SZJnozlGiFmr>~)H;4y)LLPv9}IzTwbK%{w`;p~@+K~E zHxnb;3g`d(!~Ry~TEGO0j`VjFZC7Ll55krJV}VDNzP>eUKlciWb$*1ZUy0S5VTnAq zVip*#l^|WB);*~X0nO6NMs^sh_Sz<-2{8I1jO!axTT`0wm~4628Zyyj zr(gVx$4bNl>6Q5bzko@zx5MSg zRDtr?ziFS)7M)twsC|7ns|%HX=0097hGz&QS3(|kjDHceoE3%(E4hU815>X;XVWRK z-zv$HONYLr2bX&&GQAZ#1!eGtNHz$UA7*K}0fav1Xh-GEZmis@%h7anZR&DCyJyp$Gg!_X1PmrVRu- zlj)0(4 zu;&X8?dR$Qo&t&z!~}HJr%2cPQ?CXT@2d*vUv01MjC0s3(BaH~;LDb`Kpv>(@oy0a zTe@4!y*e72SjmnF1#hQmi;^+Ax$lf;asZJpj}E5H?zy0DLub1GKrP(zPmy^4HY1UW z@HWWS^>)lzjFadfM*Dn8j_qe#;gC71e4Kt8%*JEt#gH3n`!c*-bSCYaJF`6V7<7~b zm0`z1Tgfuqk9C`Lcfmk=Cw~ww#IBRndqOdtqy2AhQ9t7T~1dSs*!RP++v>R#< z78?5d)$T&T^*huv{0r;zrs->B-Ut~MyzEXq7j5{8i=Fwlo9+!pBf6u*MuRak)<8{5E?fd&ZXGT%v>y|D03Rzq83|PszAjF;@KGV!8*_*Yyev6uCpE zCrWO$d6S|EJb>!xOktNW>$-P(?HH49xMJW1vX=+@>D;T$#MFvcWhq+UNfO}aDwS_s zKK5btst|hMD|<~hrowz;@gXkT$06pX#t@9=B+UZ?C3?x+0Ki$nfXT%0!A_J5&J`7f zG2ptvz`3Me4e^EZFAeC;*Dco_PVTK&yChfd5?HMz9*@YxA&)+!K!z}#C~s}rH7^rj z)&qpw;*eLwMxVC_u4wRI<55Ea%%XFrGFd{DF&;3R9vsg!^B{sPJepg$lGVUyx&!Kv zjqi8CUMr4l`p^aevE|q-Px=UcLK6*fBNnsX##^9TcvaAtv@;@F+@^_bm7~VYzjh`5)ur zJr8I1R`UatpP8?bl=@mGuRed`wk1NgK$+3Fp3%Ee4T*v$r_-*FE_*z3>&4Y^al+q^K z#?R8*yV*djCKvZA{``IQk|zC)Lg})K*rQ{6CD^y6@SHO)%6nCw@Xs2CSp=Bc^Vjj^ zDeKJm-u=~t<%-=vxf4~9Z?cmJNw>jn!z`ELB!Rzo#_(ReFss5LUOg$1ELbc8sA@!) zmY3ZaBo3tZmg{XXhQr6SPTJ2^&mFyYzsI1tB()K?Y(gX9%7jg4^--Yrc*$x7`Q9S! z9xbtsN1UBi=!s4Dc1kknZwe<3a()3(`xT=NwaA~D`qKDHj)0SxPnl1~o0XB)RWdD?% z2l*a(Y(yuQC5_7E_8>0w4K1v%gE$!bd;WH%_+B)BMS^_`Jnqy>_FrBX>bt`Ztd*6Z zP^l$M7-5t%DeC5;fJ=+2{Yng|J5Cx7AQmDUPWA%O{te1>C}F>E9X@vNUV0OPuMww5 zxwDeahQR#P#&Rm~aEh`Hgl zPH+f9vX(n$g`n_0x+R1->iBC*1P$5I|G;7d9I%nXrg;Aa z=`lM%vy0%76opbgQiNJ5l}t=)O1*?N^*ea!BzW(PjPX{iHLi6tXR*|PJ>c%$E%C`; zi9B*1h23R8a6OFHIgW%a&dP)DHF-1jhNe~S?!eZBD^=(#9Fz}>MLPfC_lnAv+Y<)# zg^Tt1EscO4;*}LDO{@Y5-vg8)==c8_>@NGp}QY|F(MTc>yREr=uqQ}xiL+Lm+PAzJJak|xBYLG+M+zO|S zzR1$`h@#+YB`68hfED{d##CM99ezJ_m_*h2qarl2VAc^+Z*1HT>gN<$;*Z}ES2S|m z)~SbV*rP-n37m+H^qV^Aint80;&IUw#D-0eO$RK;E}%4m*ly3r;|Ey}&mKr@32@n?-gE?1l;H# z$m}V82@b*-u+tyK%hMdKBnv@WPH5wXU4$+`x^}$AdwTLCFpXAf*o-QcHc~-Lo7a<- z{Zrf2BsmPxdY;vU*uu_%Gy@8-6tWQ8_usND)=hkQPhX%Oxh;)o2+vp{ygd;@Xx-@Z0#N zvt0hSJz8 zxq3<3&~=)gxRCVwzQgnYKjG6izk3YzY;oLrlh(Q#D*iulW>M8JnbuT!9c?8#wfP478>X7>dI_ zMszPmy!UzAmk;*54GNkd>T4|BRt|2bQ{`O*$=-X+n(dCQE&s$%omjAC?K*P-OF$-F zHsi@XaC|{9zFqH+Sm^L|A(!=F zP0L>nL+j^GurVB878e(@rV!SDBY3DFLH7@ne~siyc1YpHLB`Z*T09pVqU$>%A2*eR z`{@na&|}IzY0^MK|CfNDA=6C+(k*LwMBAUQGCu znLtlQ+L3nv!u3Yt&n;zBMO=#~Cx~nu=Ijy+*UXKmd4J?zE;%A?EwLGv4-iT4E_-d; z!32c2t_JoPosYG=OeW+PenWmdW19%Ro~YZ7%n5TgF9z^Ko=Qfg(E=dWIzYjOHRp(5 zE-&U!H6Ensd-d@AI++(RDu;-P9)XYva7T3yhHQz5KMHMddu>UAOL-uuJIYB&{oXw3 zoJF}QA9MQeWe}-JwH{ZnkSJ0yqAA^)zWuU@ z-1Vz~>fcse$m)T4$$)L|frZTUB{8Z%g6ViW`*ke_ysNe0-;=eKAYrHtk7=*Kct3n~ z5`%u6{wP$kF8hViEGik~fGpQoW#)>ac|XA3nzV+d=RJ|Ssg%j${}?TTs*`7jqKppnI59L4A)!0@2@|o~Z;ecxUm{(62Wvb z5n$=eH-ZBoNnw?xBCZ`Kv1&egvd?Rlx9l)uF&fr&W2A`a^1|{XG?pSE0v5DNmBaB} zDELlgwzMKG`H($yuq|>#M{<0sDShT(TPn{GMTr!m`&;aO71REsqTZFjUz>Imp!Y7fGcVF(!1#>dgO4n?_9L{L z%zngm&So%u$0lQ5ABKb*%LTD{Joq#1t8aoY_XSDB4?CKg;c;$N|U;-~FAW!5^ z2=fo)#7L&3Xt-qbxjRW;!E6z-!GV|2zk~4;MX+n-@@f#Te=&r%r;m8lC+#<4AmjwZw3Bq_lhT zeTb43`(_807*sxbtou~93;K3@PKAZBHpN9Ytqd0m|2Td)}L?M26y=Qfqk?7ZrVd)8<{O)ev$RDD)z-jgHIJ%9@%G>96A= zn}mG9R94yk8Xd+O4N*1`LlPCt^=*O__Czw*ajI?}mgtQ!a!l8}f|gEw1a>^8|E7~I zki=vM-&=-pjSEy(X5JR5N=?k4Vlpb=zLw21Onwa3(ZG5QkoCD&Q>4rr(7oBElG?#Z zdb(Gz;v7cznZs8ZB09K6$DMN{q*H8`O~7x&q<9t39-w%5TGuh4VZm%{Zm{)%#`95X zwNlq__{rrfw8!=|}m@5>=U)7LS>8rs=@E%BgLWWX{eORZo8eXR}hK3N- zT_!lg}60+VY^p5-zq%m^icHx0oFOLG>GX;1qm5x7i zO!NEx^bm*MXLP&i=2stNhxf65iTrWC!?g9}rhS%J(AenYP(kYK+jd1E`lB|G&r@x9 z@fm8W@DCc8*kn^2(tr03qK@EaZY15q_`dT{{=f>x`OvBY&24U5eaIiP1BMaJVutjX zg1jj>vi|(mR;Dlfqa#v@I1LZYe*}9Dp*KlZX255-4)bLzx7S2pj+U33Yb zBFL35`~)w&DztB9-i+R7JnUxx+T}lu8mnX6n-k_XU#I(bywNgf)#-DBIjuys<%Bm- zw$n}IoM8_^2az}@?9cIjqx+h2U*>g+dF+Nc2=gkZg4n8}U7xz3JkV5M`?IZ=w!Zk| z^fq>lZ5yEr-E6s2v_Xoe=U%<^*|AW$DYEUmSB1@-C(~xh&9eo(>L~RE?@G5HraN?BToZ4!S&xVaf)>lbzj|||7m!MnH~Q{1 zs7vGMIQW5$RS5cEb*@lbGqZWM4(@oa&2-zYf7k ztmOcUqUbx=Rn^+Ml<&mUlI=zw!?yq{^9q>i_VFp4ZZtuH%)wt$FnilD$RxO?OSvZV z)Ypu6XIYyRREHH6^ZxqM88d1aD24V-yn5?o!}_)Pvu0i`PfPLbllg8!*z`prn2m=9 zx^d`M4UcVZ-LhnUd&xDZ??58g_u5+R>)qUl5gnM&wJyaH}(A9$o zdZ543+rGjc58{KoST1WN*Wd%QSA4=XkeQ7cG>$k6@cWBjdr( zwk|Fy>{WEH&p5G`Xs>B2Mu561;~P&@zN_@Y-9K2-oz09XmO5nY&dwCLtayg4d0*h0 z#m`i?qs`ddei`9v!NZ40nK=jGuDY~UiU%el;slU+grp4dA0&Tvyvx^7ktU<{rYy^e!6DQk!X))ZfjQ8tTK?7<&V;IoMXSeGSHN0;!I4zfUK~ONv=ykSOIipBU4k8+sg8C;2Cn#>bXV$ zX(nF*nTIXA=vg7rHfW(gO*l5^6HwfB->pX+;L=xvmGV&^S*REm!T|GWZxPVtZcHqQ zI?<2KV4krgCh=((o&kjO{1P!!11|1|Z<;$)txp7RgAnsJd((hh_zlp>-m;XriYBu? z)8U$nCURNe=_*a_u%9;qX!#dVWszw%knS$bks06Kl#X8nWaLP=-Oj@Fmhv*E@R!n( zu=%-~`cc2NA)Ix7>bdpMvuzm~n7;qlAyF7!nhH-N8KlK)J9=7M^4_h)zUac9Y<;p) zIq?Es{^2m4S?#B<6pjA((mFW_Xljn31_O2T-A~uxgNCy{3gNoTEB1>zv7D02$YXG45e#E%LY328r={#y(kM?W24h8CI8h=st_B~k%uq^&eDeuY@U-`Y;U zk6!9vQ(=N!m6*-z{cDR`Bj7vakeqEhstjDVK7`K$KH9*bG8}Wn-0H|R?Y4{ zG$ASZ;O8^DiifKdq@-h&!MmhT{jYzc^cVG5n)F_X5({eUHH(XXyzs{S5Ap=c;ljUA zaXeDTc*bRJm;Y>K#4<^&9*6b;TX#j_>MWK?)qTvQsY6N6u#&2q*3gtzmL*^C6Optd zX_8LZLz{YmTGLL>Z02S2NV})Y`?ZnMIWB1QCjN7A<41Wm{YTMkVJL3xKJ$hk`;)Ei zPTMr2)6tN0ymdE~YF1L*NSNHhdRtAKK*FibZV-fr)*jh{^5<|(xK75Bm;Yw4HUd(n z1CZ`ytb2%_f*#H8^YabkzN0~U{b?u%Zab$vTueC*R&;HIuod$^eu!bG6n?szMObOh#fG-e*B+U3cJBPPVL4~o?lBWTQx??@>>)5v znHrTpu0j^&fBK7rl#N@3+Gk&)W2I^QpCayy^YTzqrzbDlsMJ5~ z$2)g9D&RVsE9vL`=<@LEAz^hPjg)K~^~%TC5cnz`pL5^YEM4RXYxt&7))PVq^G5ci XnbZs|dt~OHpLOJ=m8C!urs4kw>UJXA literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^H-K1=gAGV}y}teuNHG=%xjQkeJ0}C;u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS24TkI`72U@f(txd978JN-d;9jJfI+O;K1^Ktq=GaOAb11 z+pWsADQ&*B!=q|eCbs4Y2NhBbI3#(T=*l!Qw*S`2^lh7j&j+Ae89ZJ6T-G@yGywoK Ce@%q| From 7e493e4e7ee44947bde473b6f4564281f6380235 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Oct 2022 17:00:28 -0400 Subject: [PATCH 042/209] Update oss.css --- .../resources/repos-css/oss.css | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/default-assets-package/resources/repos-css/oss.css b/default-assets-package/resources/repos-css/oss.css index 5eac548d1..5ad11c076 100644 --- a/default-assets-package/resources/repos-css/oss.css +++ b/default-assets-package/resources/repos-css/oss.css @@ -206,7 +206,7 @@ div.alerts { /* 1px solid border in primary */ .border-1px-primary { - border:1px solid #0072C6 !important; + border:1px solid #20558a !important; } /* theme colors and components */ @@ -264,27 +264,27 @@ div.link-box { /* Brand box coloring v1 */ .metro-blue { - background:#0072C6; + background:#20558a; } .metro-purple { - background:#68217A; + background:#6c3a77; } .metro-gray { - background:#666; + background:#616265; } .metro-orange { - background:#fa6800; + background:#e57200; } /* Top Line Borders */ .ms-red-border-top { border-style: solid; - border-top-color:#e81123; + border-top-color:#c0143c; border-width:4px 0 0 0; } .ms-blue-border-top { border-style: solid; - border-top-color:#0078d7; + border-top-color:#20558a; border-width:4px 0 0 0; } .transparent-border { @@ -296,25 +296,25 @@ div.link-box { background:#ffb900; } .ms-orange { - background:#d83b01; + background:#e57200; } .ms-red { - background:#e81123; + background:#c0143c; } .ms-magenta { background:#b4009e; } .ms-purple { - background:#5c2d91; + background:#6c3a77; } .ms-blue { - background:#0078d7; + background:#20558a; } .ms-teal { background:#008272; } .ms-green { - background:#107c10; + background:#719500; } /* Additional brand colors */ .ms-light-orange { @@ -429,19 +429,19 @@ td.w-10, th.w-10 { .wiki-sidebar .nav > li > a:hover, .wiki-sidebar .nav > li > a:focus { padding-left: 19px; - color: #0072C6; + color: #20558a; text-decoration: none; background-color: transparent; - border-left: 1px solid #0072C6; + border-left: 1px solid #20558a; } .wiki-sidebar .nav > .active > a, .wiki-sidebar .nav > .active:hover > a, .wiki-sidebar .nav > .active:focus > a { padding-left: 18px; font-weight: bold; - color: #0072C6; + color: #20558a; background-color: transparent; - border-left: 2px solid #0072C6; + border-left: 2px solid #20558a; } /* Nav: second level (shown on .active) */ @@ -478,7 +478,7 @@ td.w-10, th.w-10 { color: #999; } .back-to-top:hover { - color: #0072C6; + color: #20558a; text-decoration: none; } @@ -524,4 +524,4 @@ td.w-10, th.w-10 { @-moz-viewport { width: device-width; } @-ms-viewport { width: device-width; } @-o-viewport { width: device-width; } -@viewport { width: device-width; } \ No newline at end of file +@viewport { width: device-width; } From 8db3e49a04bdeffadbb593ab92935c5654fff41d Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Oct 2022 17:21:44 -0400 Subject: [PATCH 043/209] Change ms-teal to NIH Blue --- default-assets-package/resources/repos-css/oss.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default-assets-package/resources/repos-css/oss.css b/default-assets-package/resources/repos-css/oss.css index 5ad11c076..1581a63fe 100644 --- a/default-assets-package/resources/repos-css/oss.css +++ b/default-assets-package/resources/repos-css/oss.css @@ -311,7 +311,7 @@ div.link-box { background:#20558a; } .ms-teal { - background:#008272; + background:#20558a; } .ms-green { background:#719500; From 550c311b3bad210fbed691f9293e61cd7279b36d Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 19 Oct 2022 16:16:54 -0400 Subject: [PATCH 044/209] adds script and workflow steps to create env-orgs --- .github/scripts/Create-Env | 22 +++++++++ .../workflows/staging_nihdevgithubportal.yml | 48 ++++++++++++++++--- 2 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 .github/scripts/Create-Env diff --git a/.github/scripts/Create-Env b/.github/scripts/Create-Env new file mode 100644 index 000000000..9d0614f66 --- /dev/null +++ b/.github/scripts/Create-Env @@ -0,0 +1,22 @@ +$output = Get-Content ./raw.json | ConvertFrom-Json + +Write-Output $output.data.enterprise.organizations.nodes + + +$orgsArry = @() + +foreach ($org in $output.data.enterprise.organizations.nodes) { + $envObj = [PSCustomObject]@{ + name = "$($org.name)" + id = "$($org.databaseId)" + type = "public" + description = "$($org.description)" + } + Write-Output "This is the object: " + Write-Output $envObj + $orgsArry += $envObj + Write-Output "This is the array inside the loop" + Write-Output $orgsArry +} + +$orgsArry | ConvertTo-Json -Depth 10 | Out-File -FilePath "orgs.json" \ No newline at end of file diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index bc81ed203..cd2721370 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Node.js version uses: actions/setup-node@v1 with: - node-version: '16.x' + node-version: "16.x" - name: npm install, build, and test run: | @@ -30,7 +30,41 @@ jobs: npm run build cd .. npm run test --if-present - + + - name: get orgs from graphql + run: | + gh api graphql -f ent=NIHGOV -f query='query($ent: String!) { + enterprise(slug: $ent) { + organizations(first: 100) { + nodes { + description + databaseId + id + name + } + } + } + }' >> raw.json + cat raw.json + + env: + GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} + + - name: run powershell script to create env orgs json + run: | + ./.github/scripts/Create-EnvOrgs.ps1 + cat orgs.json + ls + shell: pwsh + + - name: check file + run: | + cat orgs.json + ls -lah + rm env-orgs.json + cat orgs.json >> env-orgs.json + cat env-orgs.json + - name: zip application folders run: | echo $PWD @@ -51,7 +85,7 @@ jobs: runs-on: ubuntu-latest needs: build environment: - name: 'Production' + name: "Production" url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} steps: @@ -59,17 +93,17 @@ jobs: uses: actions/download-artifact@v2 with: name: node-app - + - name: Unpack tar run: | tar -xf output.tar.gz ls -lah - - name: 'Deploy to Azure Web App' + - name: "Deploy to Azure Web App" id: deploy-to-webapp uses: azure/webapps-deploy@v2 with: - app-name: 'nihdevgithubportal' - slot-name: 'Production' + app-name: "nihdevgithubportal" + slot-name: "Production" publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_34824FEBDA0F4C8CACF5CB97111CBFFB }} package: . From ed07a13b2ef634ae8990523f014b730e17d73c38 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Mon, 24 Oct 2022 12:25:52 -0400 Subject: [PATCH 045/209] Fix Enterprise Name --- .github/workflows/staging_nihdevgithubportal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index cd2721370..29871f878 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -33,7 +33,7 @@ jobs: - name: get orgs from graphql run: | - gh api graphql -f ent=NIHGOV -f query='query($ent: String!) { + gh api graphql -f ent=nih -f query='query($ent: String!) { enterprise(slug: $ent) { organizations(first: 100) { nodes { From 06d1b92a694c11bf501e228e57cdffcc32a459d8 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Mon, 24 Oct 2022 12:30:24 -0400 Subject: [PATCH 046/209] Adding extension to script --- .github/scripts/{Create-Env => Create-Env.ps1} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/scripts/{Create-Env => Create-Env.ps1} (99%) diff --git a/.github/scripts/Create-Env b/.github/scripts/Create-Env.ps1 similarity index 99% rename from .github/scripts/Create-Env rename to .github/scripts/Create-Env.ps1 index 9d0614f66..1d190350e 100644 --- a/.github/scripts/Create-Env +++ b/.github/scripts/Create-Env.ps1 @@ -19,4 +19,4 @@ foreach ($org in $output.data.enterprise.organizations.nodes) { Write-Output $orgsArry } -$orgsArry | ConvertTo-Json -Depth 10 | Out-File -FilePath "orgs.json" \ No newline at end of file +$orgsArry | ConvertTo-Json -Depth 10 | Out-File -FilePath "orgs.json" From 615e4c9b386ba6d762b0e177ad1200a85c79d175 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Mon, 24 Oct 2022 12:33:08 -0400 Subject: [PATCH 047/209] Fix Filename --- .github/scripts/{Create-Env.ps1 => Create-EnvOrgs.ps1} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/scripts/{Create-Env.ps1 => Create-EnvOrgs.ps1} (100%) diff --git a/.github/scripts/Create-Env.ps1 b/.github/scripts/Create-EnvOrgs.ps1 similarity index 100% rename from .github/scripts/Create-Env.ps1 rename to .github/scripts/Create-EnvOrgs.ps1 From 04d0164f211cd1abe793a71781ed899c9d6092ef Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Mon, 31 Oct 2022 13:38:19 -0400 Subject: [PATCH 048/209] fix quoting for id field --- .github/scripts/Create-EnvOrgs.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/Create-EnvOrgs.ps1 b/.github/scripts/Create-EnvOrgs.ps1 index 1d190350e..67a807a6e 100644 --- a/.github/scripts/Create-EnvOrgs.ps1 +++ b/.github/scripts/Create-EnvOrgs.ps1 @@ -8,7 +8,7 @@ $orgsArry = @() foreach ($org in $output.data.enterprise.organizations.nodes) { $envObj = [PSCustomObject]@{ name = "$($org.name)" - id = "$($org.databaseId)" + id = $($org.databaseId) type = "public" description = "$($org.description)" } From 3100eeecf6acfbff42cbbab1c85564c5c14f1911 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Mon, 31 Oct 2022 14:14:02 -0400 Subject: [PATCH 049/209] adds workflow file to build and push acr image --- .github/workflows/create_acr_image | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/create_acr_image diff --git a/.github/workflows/create_acr_image b/.github/workflows/create_acr_image new file mode 100644 index 000000000..2900c1d12 --- /dev/null +++ b/.github/workflows/create_acr_image @@ -0,0 +1,19 @@ +name: Linux Container Node Workflow + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: azure/docker-login@v1 + with: + login-server: + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + - run: | + docker build . -t + docker push From dc5ca2d61dcce1d1003c955190ad388f22125e5a Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 2 Nov 2022 09:33:16 -0700 Subject: [PATCH 050/209] Updated secrets and paths --- .github/workflows/create_acr_image | 19 ------------------- .../workflows/staging_create_acr_image.yml | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) delete mode 100644 .github/workflows/create_acr_image create mode 100644 .github/workflows/staging_create_acr_image.yml diff --git a/.github/workflows/create_acr_image b/.github/workflows/create_acr_image deleted file mode 100644 index 2900c1d12..000000000 --- a/.github/workflows/create_acr_image +++ /dev/null @@ -1,19 +0,0 @@ -name: Linux Container Node Workflow - -on: - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - uses: azure/docker-login@v1 - with: - login-server: - username: ${{ secrets.REGISTRY_USERNAME }} - password: ${{ secrets.REGISTRY_PASSWORD }} - - run: | - docker build . -t - docker push diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml new file mode 100644 index 000000000..567ab6b8a --- /dev/null +++ b/.github/workflows/staging_create_acr_image.yml @@ -0,0 +1,19 @@ +name: Linux Container Node Workflow + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: azure/docker-login@v1 + with: + login-server: ${{ secrets.DEV_REGISTRY_SERVER }} + username: ${{ secrets.DEV_REGISTRY_USER }} + password: ${{ secrets.DEV_REGISTRY_PASS }} + - run: | + docker build . -t ${{ secrets.DEV_REGISTRY_SERVER }}/portal + docker push ${{ secrets.DEV_REGISTRY_SERVER }}/portal From 16285f2677d3b70fd0522a2ed0b7e91ff5231ed5 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 2 Nov 2022 09:54:45 -0700 Subject: [PATCH 051/209] Added env-orgs.json to Docker build --- .../workflows/staging_create_acr_image.yml | 30 +++++++++++++++++++ Dockerfile | 3 ++ 2 files changed, 33 insertions(+) diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index 567ab6b8a..5c43d0224 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -9,6 +9,36 @@ jobs: steps: - uses: actions/checkout@v2 + - name: get orgs from graphql + run: | + gh api graphql -f ent=nih -f query='query($ent: String!) { + enterprise(slug: $ent) { + organizations(first: 100) { + nodes { + description + databaseId + id + name + } + } + } + }' >> raw.json + cat raw.json + env: + GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} + - name: run powershell script to create env orgs json + run: | + ./.github/scripts/Create-EnvOrgs.ps1 + cat orgs.json + ls + shell: pwsh + - name: check file + run: | + cat orgs.json + ls -lah + rm env-orgs.json + cat orgs.json >> env-orgs.json + cat env-orgs.json - uses: azure/docker-login@v1 with: login-server: ${{ secrets.DEV_REGISTRY_SERVER }} diff --git a/Dockerfile b/Dockerfile index 8f8f08ad2..bd4a21e54 100644 --- a/Dockerfile +++ b/Dockerfile @@ -66,6 +66,9 @@ COPY --from=build --chown=oss:oss /build/views ./views COPY --from=build --chown=oss:oss /build/package.json ./package.json COPY --from=build --chown=oss:oss /build/jobs/reports/views ./jobs/reports/views +#Do stuff for GitHub Environment Orgs +COPY --from=build --chown=oss:oss /build/env-orgs.json ./env-orgs.json + # Reports are not actively working in the project, but keeping these files ready COPY --from=build --chown=oss:oss /build/jobs/reports/exemptRepositories.json \ /build/jobs/reports/organizationDefinitions.json \ From 27b1553c91a2f6ba56fc511e21d790bb884723b5 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 2 Nov 2022 09:54:45 -0700 Subject: [PATCH 052/209] Add workflow to create ACR image. --- .../workflows/staging_create_acr_image.yml | 49 +++++++++++++++++++ Dockerfile | 3 ++ 2 files changed, 52 insertions(+) create mode 100644 .github/workflows/staging_create_acr_image.yml diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml new file mode 100644 index 000000000..5c43d0224 --- /dev/null +++ b/.github/workflows/staging_create_acr_image.yml @@ -0,0 +1,49 @@ +name: Linux Container Node Workflow + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: get orgs from graphql + run: | + gh api graphql -f ent=nih -f query='query($ent: String!) { + enterprise(slug: $ent) { + organizations(first: 100) { + nodes { + description + databaseId + id + name + } + } + } + }' >> raw.json + cat raw.json + env: + GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} + - name: run powershell script to create env orgs json + run: | + ./.github/scripts/Create-EnvOrgs.ps1 + cat orgs.json + ls + shell: pwsh + - name: check file + run: | + cat orgs.json + ls -lah + rm env-orgs.json + cat orgs.json >> env-orgs.json + cat env-orgs.json + - uses: azure/docker-login@v1 + with: + login-server: ${{ secrets.DEV_REGISTRY_SERVER }} + username: ${{ secrets.DEV_REGISTRY_USER }} + password: ${{ secrets.DEV_REGISTRY_PASS }} + - run: | + docker build . -t ${{ secrets.DEV_REGISTRY_SERVER }}/portal + docker push ${{ secrets.DEV_REGISTRY_SERVER }}/portal diff --git a/Dockerfile b/Dockerfile index 8f8f08ad2..bd4a21e54 100644 --- a/Dockerfile +++ b/Dockerfile @@ -66,6 +66,9 @@ COPY --from=build --chown=oss:oss /build/views ./views COPY --from=build --chown=oss:oss /build/package.json ./package.json COPY --from=build --chown=oss:oss /build/jobs/reports/views ./jobs/reports/views +#Do stuff for GitHub Environment Orgs +COPY --from=build --chown=oss:oss /build/env-orgs.json ./env-orgs.json + # Reports are not actively working in the project, but keeping these files ready COPY --from=build --chown=oss:oss /build/jobs/reports/exemptRepositories.json \ /build/jobs/reports/organizationDefinitions.json \ From ba37d39f5201355979144c1edad0446da9b9d3b2 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 2 Nov 2022 14:28:44 -0400 Subject: [PATCH 053/209] fixing typo in Dockerfile --- Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8f8f08ad2..f2a68ca82 100644 --- a/Dockerfile +++ b/Dockerfile @@ -59,7 +59,7 @@ COPY --from=build --chown=oss:oss /build/data ./data COPY --from=build --chown=oss:oss /build/dist ./ # The open source project build needs: default assets should be placed -COPY --from=build --chown=oss:oss /build/default-assets-package ../default-assets-package +COPY --from=build --chown=oss:oss /build/default-assets-package ./default-assets-package COPY --from=build --chown=oss:oss /build/config ./config COPY --from=build --chown=oss:oss /build/views ./views @@ -68,10 +68,10 @@ COPY --from=build --chown=oss:oss /build/jobs/reports/views ./jobs/reports/views # Reports are not actively working in the project, but keeping these files ready COPY --from=build --chown=oss:oss /build/jobs/reports/exemptRepositories.json \ - /build/jobs/reports/organizationDefinitions.json \ - /build/jobs/reports/repositoryDefinitions.json \ - /build/jobs/reports/teamDefinitions.json \ - ./jobs/reports/ + /build/jobs/reports/organizationDefinitions.json \ + /build/jobs/reports/repositoryDefinitions.json \ + /build/jobs/reports/teamDefinitions.json \ + ./jobs/reports/ # Host the app USER oss From b16196951da720f08b4d711641f618b3801f4d04 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 2 Nov 2022 15:21:37 -0400 Subject: [PATCH 054/209] fixes org login slug string --- .github/scripts/Create-EnvOrgs.ps1 | 8 +++----- .github/workflows/staging_nihdevgithubportal.yml | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/scripts/Create-EnvOrgs.ps1 b/.github/scripts/Create-EnvOrgs.ps1 index 67a807a6e..4a7954ec3 100644 --- a/.github/scripts/Create-EnvOrgs.ps1 +++ b/.github/scripts/Create-EnvOrgs.ps1 @@ -7,15 +7,13 @@ $orgsArry = @() foreach ($org in $output.data.enterprise.organizations.nodes) { $envObj = [PSCustomObject]@{ - name = "$($org.name)" + name = "$($org.login)" id = $($org.databaseId) - type = "public" + type = @("public", "private") description = "$($org.description)" } - Write-Output "This is the object: " - Write-Output $envObj + $orgsArry += $envObj - Write-Output "This is the array inside the loop" Write-Output $orgsArry } diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index 29871f878..934700f54 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -38,6 +38,7 @@ jobs: organizations(first: 100) { nodes { description + login databaseId id name From 1431e99cce5760147f59a82ff4b0da4f7203c028 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Thu, 3 Nov 2022 16:59:58 -0400 Subject: [PATCH 055/209] Update staging_create_acr_image.yml --- .github/workflows/staging_create_acr_image.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index 5c43d0224..e87c41704 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -16,6 +16,7 @@ jobs: organizations(first: 100) { nodes { description + login databaseId id name From 95c4e326ed85f477e06e81ed1777262cda40ebf9 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Thu, 3 Nov 2022 17:17:31 -0400 Subject: [PATCH 056/209] Update staging_create_acr_image.yml --- .github/workflows/staging_create_acr_image.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index 5c43d0224..e87c41704 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -16,6 +16,7 @@ jobs: organizations(first: 100) { nodes { description + login databaseId id name From 466b28ec5b138599b56f3e37a94e7be49551d75b Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 9 Nov 2022 15:23:48 -0500 Subject: [PATCH 057/209] add env var to pug file to surface company name --- views/repos/index.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/repos/index.pug b/views/repos/index.pug index 7b02081b2..8ffce2683 100644 --- a/views/repos/index.pug +++ b/views/repos/index.pug @@ -200,7 +200,7 @@ block content if organization p.lead This organization doesn't have any repositories that match. else - p.lead No repositories match across all Microsoft organizations. + p.lead No repositories match across all #{config.brand.companyName} organizations. else - var previous_possible = search.page > 1 //check for a previous page From 4d8e933a1c04546f2708f42512bc21242fefde02 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 9 Nov 2022 15:26:17 -0500 Subject: [PATCH 058/209] fix inline color of top nav --- views/nav2.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/nav2.pug b/views/nav2.pug index d59d2a6a1..716b72ee7 100644 --- a/views/nav2.pug +++ b/views/nav2.pug @@ -79,7 +79,7 @@ div.navbar.navbar-default(style=reposContext ? 'margin-bottom:0' : undefined) li(class={ active: (reposContext && reposContext.releaseTab) || site === 'release' }): a(href=config.urls.release) Release li(class={ active: (reposContext && !reposContext.releaseTab) && site === 'github' }) a( - style=((reposContext && !reposContext.releaseTab) && site === 'github' && ossLink && reposContext) ? 'color:#fff;background-color:#0072C6' : undefined, + style=((reposContext && !reposContext.releaseTab) && site === 'github' && ossLink && reposContext) ? 'color:#fff;background-color:#20558a' : undefined, href='/') GitHub ul.nav.navbar-nav.navbar-right if sudoMode From 6e7e9178e17e7c86179a8ef5e8aeb95d82fc048b Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 9 Nov 2022 15:30:54 -0500 Subject: [PATCH 059/209] add styling overrides to css --- .../resources/repos-css/oss.css | 419 ++++++++++++------ 1 file changed, 293 insertions(+), 126 deletions(-) diff --git a/default-assets-package/resources/repos-css/oss.css b/default-assets-package/resources/repos-css/oss.css index 1581a63fe..47a6cda00 100644 --- a/default-assets-package/resources/repos-css/oss.css +++ b/default-assets-package/resources/repos-css/oss.css @@ -5,6 +5,34 @@ // */ + +/* BEGIN NIH OVERRIDE */ +.navbar-default .navbar-nav>.active>a { + color: #fff; + background-color: #20558a; +} + +.navbar-inverse { + background-color: #20558a; + border-color: #333; +} + +.navbar-inverse .navbar-nav>.active>a { + color: #fff; + background-color: #456483; +} + +.nav-pills>li.active>a { + color: #fff; + background-color: #20558a; +} + +.nav>li>a { + color: #20558a; +} + +/* END NIH OVERRIDE */ + .override-white { color: #fff !important } @@ -23,7 +51,7 @@ body { } div#content { - margin-top:24px; + margin-top: 24px; } div.flex-center { @@ -39,19 +67,34 @@ div.flex-center { } .capitalize { - text-transform:capitalize; + text-transform: capitalize; } .breadcrumb { - background-color: #fff; - padding-left: 0; + background-color: #fff; + padding-left: 0; +} + +.a-unstyled { + color: #333; } -.a-unstyled { color: #333; } -.a-unstyled:link { color: #333; } -.a-unstyled:visited { color: #333; } -.a-unstyled:hover { color: #000; text-decoration: none; } -.a-unstyled:active { color: #333; } +.a-unstyled:link { + color: #333; +} + +.a-unstyled:visited { + color: #333; +} + +.a-unstyled:hover { + color: #000; + text-decoration: none; +} + +.a-unstyled:active { + color: #333; +} /* .navbar.second-row-nav { @@ -66,7 +109,7 @@ div.flex-center { } h1.huge { - font-size: 68px; + font-size: 68px; } .shrink66 { @@ -78,8 +121,8 @@ h1.huge { } h2 strong { - font-family: "Segoe UI Semibold", Segoe, "Segoe WP", Calibri, Candara, Tahoma, Verdana, Arial, sans-serif; - font-weight: normal; + font-family: "Segoe UI Semibold", Segoe, "Segoe WP", Calibri, Candara, Tahoma, Verdana, Arial, sans-serif; + font-weight: normal; } .full-width { @@ -87,7 +130,7 @@ h2 strong { } /* extra wide inline spacing */ -.list-horizontal-space > li { +.list-horizontal-space>li { margin-right: 16px; } @@ -105,27 +148,37 @@ footer { bottom: 0; } -.vertical-space, .vertical-space-top { +.vertical-space, +.vertical-space-top { margin-top: 16px; } -.vertical-space, .vertical-space-bottom { +.vertical-space, +.vertical-space-bottom { margin-bottom: 16px; } -.pad, vertical-pad, .vertical-pad-top { +.pad, +vertical-pad, +.vertical-pad-top { padding-top: 16px; } -.pad, vertical-pad, .vertical-pad-bottom { +.pad, +vertical-pad, +.vertical-pad-bottom { padding-bottom: 16px; } -.pad, .horizontal-pad, .horizontal-pad-left { +.pad, +.horizontal-pad, +.horizontal-pad-left { padding-left: 16px; } -.pad, .horizontal-pad, .horizontal-pad-right { +.pad, +.horizontal-pad, +.horizontal-pad-right { padding-right: 16px; } @@ -137,19 +190,20 @@ footer { margin-bottom: 0; } -ul.list-vspace > li, ul.list-vertical-space { +ul.list-vspace>li, +ul.list-vertical-space { padding-bottom: 8px; } code { - color: #333; + color: #333; } -.button:hover{ +.button:hover { color: lightgray; } -.invisible{ +.invisible { visibility: hidden; } @@ -158,9 +212,11 @@ code { border-color: #ddd; color: #777; } + .alert-gray hr { border-top-color: #999; } + .alert-gray .alert-link { color: #999; } @@ -170,242 +226,324 @@ input#search-box { padding-bottom: 1px; height: 36px; margin-top: 4px; - max-width:160px; + max-width: 160px; } .sevenpercent { - width:7%; + width: 7%; } + .fivepercent { - width:5%; + width: 5%; } + .tenpercent { - width:10%; + width: 10%; } + .fifteenpercent { - width:15%; + width: 15%; } + .twentypercent { - width:20%; + width: 20%; } + .twentyfivepercent { - width:25%; + width: 25%; } + .thirtypercent { - width:30%; + width: 30%; } div.alert { - margin-bottom: 0; - padding-bottom: 24px; + margin-bottom: 0; + padding-bottom: 24px; } div.alerts { - margin: 0; + margin: 0; } /* 1px solid border in primary */ .border-1px-primary { - border:1px solid #20558a !important; + border: 1px solid #20558a !important; } /* theme colors and components */ div.metro-box { - position:relative; - margin:0px; - width:100%; + position: relative; + margin: 0px; + width: 100%; } + .metro-box a { - padding:1.4em 25px; + padding: 1.4em 25px; display: inline-block; - color:#fff; + color: #fff; font-size: .9em; - position:relative; - width:100%; + position: relative; + width: 100%; } + .metro-box a h3 { color: #fff; } + .metro-box a p { color: #fff; } + .metro-box a:hover { text-decoration: none; } div.link-box { - position:relative; - margin:0px; - width:100%; + position: relative; + margin: 0px; + width: 100%; } + .link-box a { - padding:.4em 5px; + padding: .4em 5px; display: inline-block; - position:relative; - width:100%; + position: relative; + width: 100%; } + .right .link-box a { - padding-left:0; - padding-right:0; + padding-left: 0; + padding-right: 0; } + .link-box a:hover { text-decoration: none; background-color: #efefef; } + .link-box p.lead { color: #444; } + .text-mute { color: #777; } + .label-muted { background-color: #777; } /* Brand box coloring v1 */ .metro-blue { - background:#20558a; + background: #20558a; } + .metro-purple { - background:#6c3a77; + background: #6c3a77; } + .metro-gray { - background:#616265; + background: #616265; } + .metro-orange { - background:#e57200; + background: #e57200; } /* Top Line Borders */ .ms-red-border-top { border-style: solid; - border-top-color:#c0143c; - border-width:4px 0 0 0; + border-top-color: #c0143c; + border-width: 4px 0 0 0; } + .ms-blue-border-top { border-style: solid; - border-top-color:#20558a; - border-width:4px 0 0 0; + border-top-color: #20558a; + border-width: 4px 0 0 0; } + .transparent-border { - border:0px solid transparent; + border: 0px solid transparent; } /* Core brand-related colors */ .ms-yellow { - background:#ffb900; + background: #ffb900; } + .ms-orange { - background:#e57200; + background: #e57200; } + .ms-red { - background:#c0143c; + background: #c0143c; } + .ms-magenta { - background:#b4009e; + background: #b4009e; } + .ms-purple { - background:#6c3a77; + background: #6c3a77; } + .ms-blue { - background:#20558a; + background: #20558a; } + .ms-teal { - background:#20558a; + background: #20558a; } + .ms-green { - background:#719500; + background: #719500; } + /* Additional brand colors */ .ms-light-orange { - background:#ff8c00; + background: #ff8c00; } + .ms-light-magenta { - background:#e3008c; + background: #e3008c; } + .ms-light-purple { - background:#b4a0ff; + background: #b4a0ff; } + .ms-light-blue { - background:#00bcf2; + background: #00bcf2; } + .ms-light-teal { - background:#00b294; + background: #00b294; } + .ms-light-green { - background:#bad80a; + background: #bad80a; } + .ms-light-yellow { - background:#fff100; + background: #fff100; } + .ms-dark-red { - background:#a80000; + background: #a80000; } + .ms-dark-magenta { - background:#5c005c; + background: #5c005c; } + .ms-dark-purple { - background:#32145a; + background: #32145a; } + .ms-mid-blue { - background:#002050; + background: #002050; } + .ms-dark-blue { - background:#002050; + background: #002050; } + .ms-dark-teal { - background:#004b50; + background: #004b50; } + .ms-dark-green { - background:#004b1c; + background: #004b1c; } + .ms-white { - background:#fff; + background: #fff; } + .ms-light-gray { - background:#d2d2d2; + background: #d2d2d2; } + .ms-mid-gray { - background:#737373; + background: #737373; } + .ms-dark-gray { - background:#505050; + background: #505050; } + .ms-rich-black { - background:#000; + background: #000; } + /* lighter boxes need dark foreground colors */ -.ms-yellow a, .ms-light-orange a, .ms-light-magenta a, .ms-light-purple a, .ms-light-blue a, -.ms-light-teal a, .ms-light-green a, .ms-light-yellow a, .ms-white a, .ms-light-gray a { - color:#000; -} -.ms-yellow a h3, .ms-light-orange a h3, .ms-light-magenta a h3, .ms-light-purple a h3, .ms-light-blue a h3, -.ms-light-teal a h3, .ms-light-green a h3, .ms-light-yellow a h3, .ms-white a h3, .ms-light-gray a h3 { - color:#000; -} -.ms-yellow a p, .ms-light-orange a p, .ms-light-magenta a p, .ms-light-purple a p, .ms-light-blue a p, -.ms-light-teal a p, .ms-light-green a p, .ms-light-yellow a p, .ms-white a p, .ms-light-gray a p { - color:#000; +.ms-yellow a, +.ms-light-orange a, +.ms-light-magenta a, +.ms-light-purple a, +.ms-light-blue a, +.ms-light-teal a, +.ms-light-green a, +.ms-light-yellow a, +.ms-white a, +.ms-light-gray a { + color: #000; +} + +.ms-yellow a h3, +.ms-light-orange a h3, +.ms-light-magenta a h3, +.ms-light-purple a h3, +.ms-light-blue a h3, +.ms-light-teal a h3, +.ms-light-green a h3, +.ms-light-yellow a h3, +.ms-white a h3, +.ms-light-gray a h3 { + color: #000; +} + +.ms-yellow a p, +.ms-light-orange a p, +.ms-light-magenta a p, +.ms-light-purple a p, +.ms-light-blue a p, +.ms-light-teal a p, +.ms-light-green a p, +.ms-light-yellow a p, +.ms-white a p, +.ms-light-gray a p { + color: #000; } /* table width modifiers */ -th.w-25, td.w-25 { - width:30%; +th.w-25, +td.w-25 { + width: 30%; } -th.w-20, td.w-20 { - width:20%; + +th.w-20, +td.w-20 { + width: 20%; } -td.w-15, th.w-15 { - width:15%; + +td.w-15, +th.w-15 { + width: 15%; } -td.w-10, th.w-10 { - width:10%; + +td.w-10, +th.w-10 { + width: 10%; } /* By default it's not affixed in mobile views, so undo that */ .wiki-sidebar.affix { position: static; } + @media (min-width: 768px) { .wiki-sidebar { padding-left: 20px; @@ -419,24 +557,26 @@ td.w-10, th.w-10 { } /* All levels of nav */ -.wiki-sidebar .nav > li > a { +.wiki-sidebar .nav>li>a { display: block; padding: 4px 20px; font-size: 13px; font-weight: 500; color: #999; } -.wiki-sidebar .nav > li > a:hover, -.wiki-sidebar .nav > li > a:focus { + +.wiki-sidebar .nav>li>a:hover, +.wiki-sidebar .nav>li>a:focus { padding-left: 19px; color: #20558a; text-decoration: none; background-color: transparent; border-left: 1px solid #20558a; } -.wiki-sidebar .nav > .active > a, -.wiki-sidebar .nav > .active:hover > a, -.wiki-sidebar .nav > .active:focus > a { + +.wiki-sidebar .nav>.active>a, +.wiki-sidebar .nav>.active:hover>a, +.wiki-sidebar .nav>.active:focus>a { padding-left: 18px; font-weight: bold; color: #20558a; @@ -446,23 +586,27 @@ td.w-10, th.w-10 { /* Nav: second level (shown on .active) */ .wiki-sidebar .nav .nav { - display: none; /* Hide by default, but at >768px, show it */ + display: none; + /* Hide by default, but at >768px, show it */ padding-bottom: 10px; } -.wiki-sidebar .nav .nav > li > a { + +.wiki-sidebar .nav .nav>li>a { padding-top: 1px; padding-bottom: 1px; padding-left: 30px; font-size: 12px; font-weight: normal; } -.wiki-sidebar .nav .nav > li > a:hover, -.wiki-sidebar .nav .nav > li > a:focus { + +.wiki-sidebar .nav .nav>li>a:hover, +.wiki-sidebar .nav .nav>li>a:focus { padding-left: 29px; } -.wiki-sidebar .nav .nav > .active > a, -.wiki-sidebar .nav .nav > .active:hover > a, -.wiki-sidebar .nav .nav > .active:focus > a { + +.wiki-sidebar .nav .nav>.active>a, +.wiki-sidebar .nav .nav>.active:hover>a, +.wiki-sidebar .nav .nav>.active:focus>a { padding-left: 28px; font-weight: 500; } @@ -477,6 +621,7 @@ td.w-10, th.w-10 { font-weight: 500; color: #999; } + .back-to-top:hover { color: #20558a; text-decoration: none; @@ -490,28 +635,36 @@ td.w-10, th.w-10 { /* Show and affix the side nav when space allows it */ @media (min-width: 992px) { - .wiki-sidebar .nav > .active > ul { + .wiki-sidebar .nav>.active>ul { display: block; } + /* Widen the fixed sidebar */ .wiki-sidebar.affix, .wiki-sidebar.affix-bottom { width: 213px; } + .wiki-sidebar.affix { - position: fixed; /* Undo the static from mobile first approach */ + position: fixed; + /* Undo the static from mobile first approach */ top: 20px; } + .wiki-sidebar.affix-bottom { - position: absolute; /* Undo the static from mobile first approach */ + position: absolute; + /* Undo the static from mobile first approach */ } + .wiki-sidebar.affix-bottom .wiki-sidenav, .wiki-sidebar.affix .wiki-sidenav { margin-top: 0; margin-bottom: 0; } } + @media (min-width: 1200px) { + /* Widen the fixed sidebar again */ .wiki-sidebar.affix-bottom, .wiki-sidebar.affix { @@ -520,8 +673,22 @@ td.w-10, th.w-10 { } /* IE10 bugs */ -@-webkit-viewport { width: device-width; } -@-moz-viewport { width: device-width; } -@-ms-viewport { width: device-width; } -@-o-viewport { width: device-width; } -@viewport { width: device-width; } +@-webkit-viewport { + width: device-width; +} + +@-moz-viewport { + width: device-width; +} + +@-ms-viewport { + width: device-width; +} + +@-o-viewport { + width: device-width; +} + +@viewport { + width: device-width; +} \ No newline at end of file From 045a082317433161dc430a512212e7852fc498ed Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Thu, 10 Nov 2022 16:56:58 -0500 Subject: [PATCH 060/209] add new language and links to top nav --- views/nav2.pug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/nav2.pug b/views/nav2.pug index 716b72ee7..4434fa1f7 100644 --- a/views/nav2.pug +++ b/views/nav2.pug @@ -70,7 +70,7 @@ div.navbar.navbar-default(style=reposContext ? 'margin-bottom:0' : undefined) div.collapse.navbar-collapse#bs-example-navbar-collapse-1 ul.nav.navbar-nav if config && config.urls - li(class={ active: site === 'explore' }): a(href=config.urls.explore) Explore + li(class={ active: site === 'explore' }): a(href='https://github.nih.gov/') NIH GitHub if config.urls.docs li: a(href=config.urls.docs) Docs if config.urls.use @@ -80,7 +80,7 @@ div.navbar.navbar-default(style=reposContext ? 'margin-bottom:0' : undefined) li(class={ active: (reposContext && !reposContext.releaseTab) && site === 'github' }) a( style=((reposContext && !reposContext.releaseTab) && site === 'github' && ossLink && reposContext) ? 'color:#fff;background-color:#20558a' : undefined, - href='/') GitHub + href='/') Enterprise ul.nav.navbar-nav.navbar-right if sudoMode li From 494f3405d239bcb02c3b3fa96012b8ee7913c195 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Thu, 10 Nov 2022 16:58:12 -0500 Subject: [PATCH 061/209] add padding to top nav --- views/nav2.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/nav2.pug b/views/nav2.pug index 4434fa1f7..004b014f9 100644 --- a/views/nav2.pug +++ b/views/nav2.pug @@ -68,7 +68,7 @@ div.navbar.navbar-default(style=reposContext ? 'margin-bottom:0' : undefined) = config.brand && config.brand.companyPortalName ? config.brand.companyPortalName : 'GitHub Management Portal' // Collect the nav links, forms, and other content for toggling div.collapse.navbar-collapse#bs-example-navbar-collapse-1 - ul.nav.navbar-nav + ul.nav.navbar-nav(style='margin-left:-15px') if config && config.urls li(class={ active: site === 'explore' }): a(href='https://github.nih.gov/') NIH GitHub if config.urls.docs From a0f5030d4fa65c6fad226404c32bcd9ca80fb78d Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Thu, 10 Nov 2022 17:02:07 -0500 Subject: [PATCH 062/209] remove text from footer --- views/footer.pug | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/views/footer.pug b/views/footer.pug index 7147024f2..01f450ca7 100644 --- a/views/footer.pug +++ b/views/footer.pug @@ -115,7 +115,6 @@ footer .pull-right.text-right a#microsoftFooterLogo(href=(config && config.brand ? config.brand.companyLink : 'about:blank'), title=(config && config.brand ? config.brand.companyName : '')) img(src='/img/logo.png', alt=(config && config.brand ? config.brand.companyName : ''), style='max-height:23px') - br - span © #{config && config.brand.companyName ? config.brand.companyName : ''} + |   .row div(style='margin-bottom: 30px') From 2292d59c31f21ee55ab014c60174f1d436677abc Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 15 Nov 2022 13:51:58 -0500 Subject: [PATCH 063/209] add serviceBus email feature --- config/mail.json | 8 +++-- lib/mailProvider/azureServiceBus.ts | 52 +++++++++++++++++++++++++++++ routes/org/team/index.ts | 2 +- 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 lib/mailProvider/azureServiceBus.ts diff --git a/config/mail.json b/config/mail.json index c196059f0..93bea8a2a 100644 --- a/config/mail.json +++ b/config/mail.json @@ -6,7 +6,11 @@ "url": "env://MAIL_CUSTOMSERVICE_URL", "apiKey": "env://MAIL_CUSTOMSERVICE_KEY", "version": "env://MAIL_CUSTOMSERVICE_VERSION" - }, + }, + "azureServiceBus": { + "connectionString": "env://MAIL_AZURESERVICEBUS_CONNECTIONSTRING", + "queueName": "env://MAIL_AZURESERVICEBUS_QUEUENAME" + }, "smtpMailService": { "host": "env://MAIL_SMTP_HOST", "port": "env://MAIL_SMTP_PORT", @@ -26,4 +30,4 @@ "replyTo": "env://DIRECTORY_MAIL_SERVICE_REPLYTO", "appName": "env://DIRECTORY_MAIL_SERVICE_APPNAME" } -} +} \ No newline at end of file diff --git a/lib/mailProvider/azureServiceBus.ts b/lib/mailProvider/azureServiceBus.ts new file mode 100644 index 000000000..21a06c7ac --- /dev/null +++ b/lib/mailProvider/azureServiceBus.ts @@ -0,0 +1,52 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { IMailProvider, IMail } from '.'; +import { ServiceBusClient, ServiceBusMessage } from '@azure/service-bus'; + +export default class AzureServiceBus implements IMailProvider { + private _config: any; + + html: true; + info: 'Azure Service Bus'; + + constructor(mailConfig: any) { + this._config = mailConfig; + } + + getSentMessages() { + return []; // this provider does not support mocks + } + + async initialize() { } + + async sendMail(mail: IMail): Promise { + if (!this._config.azureServiceBus) { + throw new Error('Azure Service bus configuration not provided, mail sending failed'); + } + + if (!mail.to) { + throw new Error('No email recipient provided'); + } + + const client = new ServiceBusClient(this._config.azureServiceBus.connectionString); + const sender = client.createSender(this._config.azureServiceBus.queueName); + + const message: ServiceBusMessage = { + contentType: 'application/json', + subject: mail.subject, + correlationId: mail.correlationId, + body: mail, + }; + + await sender.sendMessages(message); + await sender.close(); + + return null; + } + catch(err) { + throw err; + } +} \ No newline at end of file diff --git a/routes/org/team/index.ts b/routes/org/team/index.ts index 77988519a..3bf66cd3d 100644 --- a/routes/org/team/index.ts +++ b/routes/org/team/index.ts @@ -230,7 +230,7 @@ export async function submitTeamJoinRequest( return { message: `You have joined ${team.name} broad access team successfully`, redirect: `${organization.baseUrl}teams` }; } const justification = optionalJustification || 'N/A'; - const approvalTypesValues = config.github.approvalTypes.repo; + const approvalTypesValues = config.github.approvalTypes.teamJoin; if (approvalTypesValues.length === 0) { return { error: new Error('No team join approval providers configured.') }; } From db39bfe254af178eac847679349d81416e419e31 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 15 Nov 2022 13:54:39 -0500 Subject: [PATCH 064/209] fix missing file --- lib/mailProvider/index.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/mailProvider/index.ts b/lib/mailProvider/index.ts index 43d9cf56b..c9842295c 100644 --- a/lib/mailProvider/index.ts +++ b/lib/mailProvider/index.ts @@ -5,6 +5,7 @@ import MockMailService from './mockMailService'; import SmtpMailService from './smtpMailService'; +import AzureServiceBus from './azureServiceBus'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; export interface IMail { @@ -73,7 +74,7 @@ export function createMailProviderInstance(config): IMailProvider { if (mailProvider) { if (mailConfig.overrideRecipient) { patchOverride(mailProvider, mailConfig.overrideRecipient, mailProvider.html); - } + } return mailProvider; } } @@ -85,6 +86,10 @@ export function createMailProviderInstance(config): IMailProvider { return; } switch (provider) { + case 'azureServiceBus': { + mailProvider = new AzureServiceBus(mailConfig); + break; + } case 'smtpMailService': { mailProvider = new SmtpMailService(config); break; From a87c2ac7f983e29264e6322da2ab8565cffac4b4 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 16 Nov 2022 12:25:20 -0500 Subject: [PATCH 065/209] Update main_nihgithubportal.yml --- .github/workflows/main_nihgithubportal.yml | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index fe8d4e9f1..dcee2ccb1 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -31,6 +31,40 @@ jobs: cd .. npm run test --if-present + - name: get orgs from graphql + run: | + gh api graphql -f ent=nih -f query='query($ent: String!) { + enterprise(slug: $ent) { + organizations(first: 100) { + nodes { + description + login + databaseId + id + name + } + } + } + }' >> raw.json + cat raw.json + env: + GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} + + - name: run powershell script to create env orgs json + run: | + ./.github/scripts/Create-EnvOrgs.ps1 + cat orgs.json + ls + shell: pwsh + + - name: check file + run: | + cat orgs.json + ls -lah + rm env-orgs.json + cat orgs.json >> env-orgs.json + cat env-orgs.json + - name: zip application folders run: | echo $PWD From 6eb8bc2d9bfeedb73678fdf16c045b5594d2f310 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 16 Nov 2022 12:30:14 -0500 Subject: [PATCH 066/209] Create main_create_acr_image.yaml --- .github/workflows/main_create_acr_image.yaml | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/main_create_acr_image.yaml diff --git a/.github/workflows/main_create_acr_image.yaml b/.github/workflows/main_create_acr_image.yaml new file mode 100644 index 000000000..627bfdbbc --- /dev/null +++ b/.github/workflows/main_create_acr_image.yaml @@ -0,0 +1,50 @@ +name: Linux Container Node Workflow + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: get orgs from graphql + run: | + gh api graphql -f ent=nih -f query='query($ent: String!) { + enterprise(slug: $ent) { + organizations(first: 100) { + nodes { + description + login + databaseId + id + name + } + } + } + }' >> raw.json + cat raw.json + env: + GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} + - name: run powershell script to create env orgs json + run: | + ./.github/scripts/Create-EnvOrgs.ps1 + cat orgs.json + ls + shell: pwsh + - name: check file + run: | + cat orgs.json + ls -lah + rm env-orgs.json + cat orgs.json >> env-orgs.json + cat env-orgs.json + - uses: azure/docker-login@v1 + with: + login-server: ${{ secrets.PROD_REGISTRY_SERVER }} + username: ${{ secrets.PROD_REGISTRY_USER }} + password: ${{ secrets.PROD_REGISTRY_PASS }} + - run: | + docker build . -t ${{ secrets.PROD_REGISTRY_SERVER }}/portal + docker push ${{ secrets.PROD_REGISTRY_SERVER }}/portal From 13a960715580701b40c3a8e61e52e5a180aee4d9 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 17 Nov 2022 00:20:14 -0500 Subject: [PATCH 067/209] Initial email styling changes --- views/email/email.pug | 6 +++--- views/email/footer.pug | 10 ++++------ views/email/header.pug | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/views/email/email.pug b/views/email/email.pug index 25627f5fe..05443c662 100644 --- a/views/email/email.pug +++ b/views/email/email.pug @@ -15,13 +15,13 @@ //- The assets are stored in the storage account 'ospomail', public blob container 'opensource' //- An Akamai CDN is used to serve the images, https://ospomail.azureedge.net points to the container -- var logoBase = 'https://ospomail.azureedge.net/'; -- var logoImage = 'opensource.png' +- var logoBase = 'https://github.nih.gov/assets/img/logo/'; +- var logoImage = 'cover.png' - var orgIdSize = 42 - var iconSize = 60 - var logo = logoBase + logoImage - var useIcon = notification === 'action' || notification === 'warning' || notification === 'information' -- var icon = useIcon ? logoBase + 'inverted-' + notification + '.png' : null +- var icon = useIcon ? logoBase + logoImage : null doctype html html(lang="en") diff --git a/views/email/footer.pug b/views/email/footer.pug index 8fe05c22e..def155cf4 100644 --- a/views/email/footer.pug +++ b/views/email/footer.pug @@ -40,14 +40,12 @@ tr td p.footer - | #{companyName} Open Source Programs Office + | #{companyName} NIH GitHub br - a(href='https://aka.ms/opensource') aka.ms/opensource + a(href='https://github.nih.gov') github.nih.gov |  •  - a(href='https://stackoverflow.microsoft.com/tags/opensource') StackOverflow@Microsoft - |  •  - a(href='mailto:opensource@microsoft.com') opensource@microsoft.com + a(href='mailto:GitHub@nih.gov') GitHub@nih.gov td(width='120', valign='middle') - img(align='right', valign='middle', src='https://ospomail.azureedge.net/microsoft.png', width='108', height='23', alt='Microsoft') + img(align='right', valign='middle', src='https://github.nih.gov/assets/img/nih_long.png', width='108', height='17', alt='National Institutes of Health') diff --git a/views/email/header.pug b/views/email/header.pug index 6b9dce513..4694b33e8 100644 --- a/views/email/header.pug +++ b/views/email/header.pug @@ -6,8 +6,8 @@ table(style='width:100%;border:0', cellspacing=0, cellpadding=0) tbody tr td(width=orgIdSize, height=orgIdSize) - img(src=logo, width=orgIdSize, height=orgIdSize, alt='Microsoft Open Source') + img(src=logo, width=orgIdSize, height=orgIdSize, alt='NIH GitHub') td(valign='bottom', nowrap='nowrap') h2(style='vertical-align:bottom') |   - = app || 'Microsoft Open Source' + = app || 'NIH GitHub' From 245b0d22025743e958102dc7f459226b0fdc637c Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Thu, 17 Nov 2022 08:52:47 -0500 Subject: [PATCH 068/209] Update staging_create_acr_image.yml Removes dynamic env-orgs.json creation so that staging always uses a smaller set of orgs --- .../workflows/staging_create_acr_image.yml | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index e87c41704..567ab6b8a 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -9,37 +9,6 @@ jobs: steps: - uses: actions/checkout@v2 - - name: get orgs from graphql - run: | - gh api graphql -f ent=nih -f query='query($ent: String!) { - enterprise(slug: $ent) { - organizations(first: 100) { - nodes { - description - login - databaseId - id - name - } - } - } - }' >> raw.json - cat raw.json - env: - GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} - - name: run powershell script to create env orgs json - run: | - ./.github/scripts/Create-EnvOrgs.ps1 - cat orgs.json - ls - shell: pwsh - - name: check file - run: | - cat orgs.json - ls -lah - rm env-orgs.json - cat orgs.json >> env-orgs.json - cat env-orgs.json - uses: azure/docker-login@v1 with: login-server: ${{ secrets.DEV_REGISTRY_SERVER }} From 96ea100adf0a0a90717212810a01d5cec730d628 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Thu, 17 Nov 2022 08:55:03 -0500 Subject: [PATCH 069/209] Update staging_nihdevgithubportal.yml --- .../workflows/staging_nihdevgithubportal.yml | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index 934700f54..3b7048f24 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -31,41 +31,6 @@ jobs: cd .. npm run test --if-present - - name: get orgs from graphql - run: | - gh api graphql -f ent=nih -f query='query($ent: String!) { - enterprise(slug: $ent) { - organizations(first: 100) { - nodes { - description - login - databaseId - id - name - } - } - } - }' >> raw.json - cat raw.json - - env: - GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} - - - name: run powershell script to create env orgs json - run: | - ./.github/scripts/Create-EnvOrgs.ps1 - cat orgs.json - ls - shell: pwsh - - - name: check file - run: | - cat orgs.json - ls -lah - rm env-orgs.json - cat orgs.json >> env-orgs.json - cat env-orgs.json - - name: zip application folders run: | echo $PWD From d18415cf00f43d701e05f4d99198251bbb8e779d Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 17 Nov 2022 11:55:42 -0500 Subject: [PATCH 070/209] Styled Email CSS for NIH --- views/email/email.css | 139 ++++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 52 deletions(-) diff --git a/views/email/email.css b/views/email/email.css index 6d1b9d37e..5ed8e4b86 100644 --- a/views/email/email.css +++ b/views/email/email.css @@ -1,131 +1,166 @@ body { - font-family: "Segoe UI","Segoe WP",Segoe,"Helvetica Neue","Helvetica","Arial","sans-serif"; + font-family: "Segoe UI", "Segoe WP", Segoe, "Helvetica Neue", "Helvetica", "Arial", "sans-serif"; font-weight: normal; font-size: 11pt; line-height: 16pt; } + h1 { - font-size:36pt; - font-family:"Segoe UI Light","Segoe WP Light",Segoe,"Helvetica Neue","Helvetica","Arial","sans-serif"; + font-size: 36pt; + font-family: "Segoe UI Light", "Segoe WP Light", Segoe, "Helvetica Neue", "Helvetica", "Arial", "sans-serif"; color: #787878; } + h1.blue { - color:#0078d7; + color: #20558a; } + h2 { - font-size:24pt; - font-family:"Segoe UI Light","Segoe WP Light",Segoe,"Helvetica Neue","Helvetica","Arial","sans-serif"; + font-size: 24pt; + font-family: "Segoe UI Light", "Segoe WP Light", Segoe, "Helvetica Neue", "Helvetica", "Arial", "sans-serif"; font-weight: normal; color: #787878; } + h3 { - font-size:16pt; - font-family:"Segoe UI","Segoe WP",Segoe,"Helvetica Neue","Helvetica","Arial","sans-serif"; - color:#787878; - font-weight:normal; + font-size: 16pt; + font-family: "Segoe UI", "Segoe WP", Segoe, "Helvetica Neue", "Helvetica", "Arial", "sans-serif"; + color: #787878; + font-weight: normal; } + p { margin-bottom: 5pt; margin-left: 0; margin-right: 0; margin-top: 0; } -a, a:link { - color: #0078d7; + +a, +a:link { + color: #20558a; } + a:visited { - color: #32145a; + color: #32145a; } + pre { font-family: Consolas, "Courier New", Courier, monospace; } + pre.body-font { - font-family: "Segoe UI","Segoe WP",Segoe,"Helvetica Neue","Helvetica","Arial","sans-serif"; + font-family: "Segoe UI", "Segoe WP", Segoe, "Helvetica Neue", "Helvetica", "Arial", "sans-serif"; font-weight: normal; } + table.technical { - font-size:10pt; - border:1px solid #ddd; + font-size: 10pt; + border: 1px solid #ddd; border-collapse: collapse; } + table.technical tbody tr { - border-top:1px solid #ddd; + border-top: 1px solid #ddd; } -table.technical thead tr th, table.technical tbody tr td { - border:1px solid #ddd; - padding:4px; - margin:0; + +table.technical thead tr th, +table.technical tbody tr td { + border: 1px solid #ddd; + padding: 4px; + margin: 0; } + table.notification-action { background-color: #ff8c00; color: white; border: 0; min-height: 64px; - width:100%; - margin-bottom:16px; + width: 100%; + margin-bottom: 16px; } + table.notification-information { - background-color: #0078d7; + background-color: #20558a; color: white; border: 0; min-height: 64px; - width:100%; - margin-bottom:16px; + width: 100%; + margin-bottom: 16px; } + table.notification-warning { border: 0; - background-color:#e81123; + background-color: #e81123; color: white; border: 0; min-height: 64px; - width:100%; - margin-bottom:16px; + width: 100%; + margin-bottom: 16px; } + table.notification-success { border: 0; - background-color:#107c10; + background-color: #107c10; color: white; border: 0; min-height: 64px; - width:100%; - margin-bottom:16px; + width: 100%; + margin-bottom: 16px; } + table.notification-action tbody tr td h1, table.notification-warning tbody tr td h1, table.notification-success tbody tr td h1, table.notification-information tbody tr td h1 { color: white; - font-size:36pt; - padding-left:16px; - margin-left:16px; - padding-right:12px; - padding-top:8px; - margin-top:8px; - padding-bottom:8px; - margin-bottom:8px; -} + font-size: 36pt; + padding-left: 16px; + margin-left: 16px; + padding-right: 12px; + padding-top: 8px; + margin-top: 8px; + padding-bottom: 8px; + margin-bottom: 8px; +} + p.footer { - font-size:10pt; - color:#787878; + font-size: 10pt; + color: #787878; } + .footer p small { - font-size:9pt; - color:#787878; + font-size: 9pt; + color: #787878; } + p.footer a { text-decoration: none; - color: #0078d7; + color: #20558a; } + th { text-align: left; } + #container { - max-width:480px; + max-width: 480px; } -@media only screen and (min-width: 480px){ - table[id="container"]{width:600px;} + +@media only screen and (min-width: 480px) { + table[id="container"] { + width: 600px; + } } + @media only screen and (max-width: 480px) { - body{width:100% !important; min-width:100% !important;} - table[id="container"]{width:100% !important; max-width:480px !important;} -} + body { + width: 100% !important; + min-width: 100% !important; + } + + table[id="container"] { + width: 100% !important; + max-width: 480px !important; + } +} \ No newline at end of file From c6483884e7d38fae8d9002c9dfdeaab3e8bedcae Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 17 Nov 2022 16:05:02 -0500 Subject: [PATCH 071/209] Bump action dependencies. --- .github/workflows/main_nihgithubportal.yml | 2 +- .github/workflows/staging_create_acr_image.yml | 2 +- .github/workflows/staging_nihdevgithubportal.yml | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index fe8d4e9f1..98bcad96e 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -42,7 +42,7 @@ jobs: ls -lah - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: node-app path: /home/runner/work/github-portal/output.tar.gz diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index e87c41704..3382d6e72 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: get orgs from graphql run: | gh api graphql -f ent=nih -f query='query($ent: String!) { diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index 934700f54..654e647bc 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -14,10 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Node.js version - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: "16.x" @@ -77,7 +77,7 @@ jobs: ls -lah - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: node-app path: /home/runner/work/github-portal/output.tar.gz @@ -91,7 +91,7 @@ jobs: steps: - name: Download artifact from build job - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: node-app From 41d463c5af756171f4f8e4ab223e434cf91dd2b1 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 18 Nov 2022 15:24:05 -0500 Subject: [PATCH 072/209] add flattening to email to field --- lib/mailProvider/azureServiceBus.ts | 39 ++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/mailProvider/azureServiceBus.ts b/lib/mailProvider/azureServiceBus.ts index 21a06c7ac..2821abb82 100644 --- a/lib/mailProvider/azureServiceBus.ts +++ b/lib/mailProvider/azureServiceBus.ts @@ -12,23 +12,56 @@ export default class AzureServiceBus implements IMailProvider { html: true; info: 'Azure Service Bus'; - constructor(mailConfig: any) { - this._config = mailConfig; + constructor(config: any) { + this._config = config; } getSentMessages() { return []; // this provider does not support mocks } + flatten(stringOrArray) { + // the logic app expects a string of emails separated by ';' + if (typeof stringOrArray === 'string' && stringOrArray.length) { + return stringOrArray; + } + + if (Array.isArray(stringOrArray)) { + // replace empty arrays with undefined + return stringOrArray.length ? stringOrArray.join('; ') : undefined; + } + + return undefined; + } + + transform(mail: IMail): IMail { + mail.to = this.flatten(mail.to); + mail.cc = this.flatten(mail.cc); + mail.bcc = this.flatten(mail.bcc); + + return mail; + } + async initialize() { } async sendMail(mail: IMail): Promise { + const { + mail: { azureServiceBus: config }, + brand: { supportMail }, + } = this._config; + if (!this._config.azureServiceBus) { throw new Error('Azure Service bus configuration not provided, mail sending failed'); } + mail = this.transform(mail); + if (!mail.to) { - throw new Error('No email recipient provided'); + if (supportMail) { + mail.to = supportMail; + } else { + throw new Error('No email recipient provided'); + } } const client = new ServiceBusClient(this._config.azureServiceBus.connectionString); From c45ff8c8018344ea0f42d3a2c9ad451cfc5a3ed7 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 18 Nov 2022 15:25:29 -0500 Subject: [PATCH 073/209] fix variable name in index --- lib/mailProvider/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mailProvider/index.ts b/lib/mailProvider/index.ts index c9842295c..f53ceb89d 100644 --- a/lib/mailProvider/index.ts +++ b/lib/mailProvider/index.ts @@ -87,7 +87,7 @@ export function createMailProviderInstance(config): IMailProvider { } switch (provider) { case 'azureServiceBus': { - mailProvider = new AzureServiceBus(mailConfig); + mailProvider = new AzureServiceBus(config); break; } case 'smtpMailService': { From d6db2f587089c239c087b991b15bf74c457d91d9 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 18 Nov 2022 16:52:03 -0500 Subject: [PATCH 074/209] add ga tagging via the googleAnalyticsKey env var --- views/ga.pug | 12 +++++------- views/layout.pug | 3 +++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/views/ga.pug b/views/ga.pug index 2d81ad746..cc4378c69 100644 --- a/views/ga.pug +++ b/views/ga.pug @@ -5,10 +5,8 @@ if (googleAnalyticsKey) script. - (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ - (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), - m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) - })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); - - ga('create', '#{googleAnalyticsKey}', 'auto'); - ga('send', 'pageview'); + (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': + new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], + j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= + 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); + })(window,document,'script','dataLayer','#{googleAnalyticsKey}'); diff --git a/views/layout.pug b/views/layout.pug index 7a2e40e9c..874a44c06 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -7,6 +7,9 @@ doctype html html(lang="en") include head body + if (googleAnalyticsKey) + noscript. + iframe(src="https://www.googletagmanager.com/ns.html?id=" + googleAnalyticsKey height="0" width="0" style="display:none;visibility:hidden") include alerts - var scheme = primaryAuthenticationScheme || (config ? config.authentication.scheme : null) if scheme === 'aad' From 67b9559f5e1086882010e91447d1d4aaab2f7e9a Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sat, 19 Nov 2022 01:09:45 -0500 Subject: [PATCH 075/209] Updated Email CDN and Company Name --- jobs/reports/repositoryDefinitions.json | 2 +- routes/org/team/index.ts | 4 ++-- views/email/email.pug | 4 ++-- views/email/footer.pug | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jobs/reports/repositoryDefinitions.json b/jobs/reports/repositoryDefinitions.json index 50fcaf1d6..00a603376 100644 --- a/jobs/reports/repositoryDefinitions.json +++ b/jobs/reports/repositoryDefinitions.json @@ -104,7 +104,7 @@ "name": "oneYearOldPrivateRepositories", "title": "Private engineering on GitHub (long-term)", "ignoredDescription": "These repositories remain private, were created more than a year ago, and have not shipped as public open source. These repos should be deleted, moved to a private engineering system such as VSTS, or develop a plan to move to another engineering system.", - "ignoredActionText": "Microsoft GitHub is only intended for work in the process of being open sourced and in the support of open source projects. Consider building a plan to resource the relocation of these repositories to an approved, compliant corporate engineering system (1ES/OneBranch/VSTS) so that the project will meet security needs such as being located within a Microsoft data center.", + "ignoredActionText": "NIH GitHub is only intended for work in the process of being open sourced and in the support of open source projects. Consider building a plan to resource the relocation of these repositories to an approved, compliant corporate engineering system (1ES/OneBranch/VSTS) so that the project will meet security needs such as being located within a Microsoft data center.", "category": "weeklySummary", "hasTable": true, "hasList": false, diff --git a/routes/org/team/index.ts b/routes/org/team/index.ts index 3bf66cd3d..a683f1be6 100644 --- a/routes/org/team/index.ts +++ b/routes/org/team/index.ts @@ -302,7 +302,7 @@ export async function submitTeamJoinRequest( category: ['request', 'repos'], headline: `${team.name} permission request`, notification: 'action', - app: 'Microsoft GitHub', + app: 'NIH GitHub', correlationId, version: config.logging.version, actionUrl: approvalBaseUrl + requestId, @@ -369,7 +369,7 @@ export async function submitTeamJoinRequest( This mail was sent to: ${personMail}`), headline: 'Team request submitted', notification: 'information', - app: 'Microsoft GitHub', + app: 'NIH GitHub', correlationId, version: config.logging.version, actionUrl: approvalBaseUrl + requestId, diff --git a/views/email/email.pug b/views/email/email.pug index 05443c662..edbb1eddc 100644 --- a/views/email/email.pug +++ b/views/email/email.pug @@ -15,8 +15,8 @@ //- The assets are stored in the storage account 'ospomail', public blob container 'opensource' //- An Akamai CDN is used to serve the images, https://ospomail.azureedge.net points to the container -- var logoBase = 'https://github.nih.gov/assets/img/logo/'; -- var logoImage = 'cover.png' +- var logoBase = 'https://cdn.cloud.nih.gov/images/'; +- var logoImage = 'github.png' - var orgIdSize = 42 - var iconSize = 60 - var logo = logoBase + logoImage diff --git a/views/email/footer.pug b/views/email/footer.pug index def155cf4..e1dbbf265 100644 --- a/views/email/footer.pug +++ b/views/email/footer.pug @@ -47,5 +47,5 @@ a(href='mailto:GitHub@nih.gov') GitHub@nih.gov td(width='120', valign='middle') - img(align='right', valign='middle', src='https://github.nih.gov/assets/img/nih_long.png', width='108', height='17', alt='National Institutes of Health') + img(align='right', valign='middle', src='https://cdn.cloud.nih.gov/images/nih_long.png', width='108', height='17', alt='National Institutes of Health') From 67b96da89f2bccf2d1d6a510bf8153f76f242a34 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Mon, 21 Nov 2022 14:00:38 -0500 Subject: [PATCH 076/209] Instantiate ASB mail provider with entire config. --- lib/mailProvider/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mailProvider/index.ts b/lib/mailProvider/index.ts index c9842295c..f53ceb89d 100644 --- a/lib/mailProvider/index.ts +++ b/lib/mailProvider/index.ts @@ -87,7 +87,7 @@ export function createMailProviderInstance(config): IMailProvider { } switch (provider) { case 'azureServiceBus': { - mailProvider = new AzureServiceBus(mailConfig); + mailProvider = new AzureServiceBus(config); break; } case 'smtpMailService': { From ae2cd09296c51cd19cf70a228d5472bf0f39c3f1 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Mon, 21 Nov 2022 21:00:26 -0500 Subject: [PATCH 077/209] Disabled make-repo-public --- views/repos/repo.pug | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/views/repos/repo.pug b/views/repos/repo.pug index 71650c15b..9aec661ed 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -229,17 +229,17 @@ block content target='_blank' ) Webhooks - if repoPermissions.allowAdministration && repo.private === true - ul.list-unstyled.list-vspace - li - form(method='post') - input.btn.btn-sm( - type='submit', - name='make-repo-public' - class='btn-danger', - value='Make repo public', - onclick='return confirm(\'Are you sure that you want to make this repo public?\');' - title='Click to toggle this repo from private to public') + //- if repoPermissions.allowAdministration && repo.private === true + //- ul.list-unstyled.list-vspace + //- li + //- form(method='post') + //- input.btn.btn-sm( + //- type='submit', + //- name='make-repo-public' + //- class='btn-danger', + //- value='Make repo public', + //- onclick='return confirm(\'Are you sure that you want to make this repo public?\');' + //- title='Click to toggle this repo from private to public') if repositoryMetadataEntity && repositoryMetadataEntity.repositoryName && repositoryMetadataEntity.organizationName #corporateMetadata From 8e29722ab060f3e285f34d01044396d1cf2f9c0b Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Mon, 28 Nov 2022 08:38:04 -0500 Subject: [PATCH 078/209] Update staging_create_acr_image.yml --- .../workflows/staging_create_acr_image.yml | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index 3382d6e72..c042ab00e 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -9,37 +9,6 @@ jobs: steps: - uses: actions/checkout@v3 - - name: get orgs from graphql - run: | - gh api graphql -f ent=nih -f query='query($ent: String!) { - enterprise(slug: $ent) { - organizations(first: 100) { - nodes { - description - login - databaseId - id - name - } - } - } - }' >> raw.json - cat raw.json - env: - GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} - - name: run powershell script to create env orgs json - run: | - ./.github/scripts/Create-EnvOrgs.ps1 - cat orgs.json - ls - shell: pwsh - - name: check file - run: | - cat orgs.json - ls -lah - rm env-orgs.json - cat orgs.json >> env-orgs.json - cat env-orgs.json - uses: azure/docker-login@v1 with: login-server: ${{ secrets.DEV_REGISTRY_SERVER }} From 313e8bd3f0a871d7af379363ee0bfeb5a811c613 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Mon, 28 Nov 2022 14:52:40 -0500 Subject: [PATCH 079/209] More better disable make-repo-public --- routes/org/repos.ts | 33 +++++++++++++++++---------------- views/repos/repo.pug | 1 + 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/routes/org/repos.ts b/routes/org/repos.ts index 6727b7436..f2e037d17 100644 --- a/routes/org/repos.ts +++ b/routes/org/repos.ts @@ -246,22 +246,23 @@ export async function renameRepositoryDefaultBranchEndToEnd(providers: IProvider }; } -router.post('/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), asyncHandler(async function (req: ILocalRequest, res, next) { - const repoPermissions = req.repoPermissions; - if (!repoPermissions.allowAdministration) { - return next(new Error('You do not have administrative permission on this repository')); - } - // only supporting the 'take public' operation now - const takePublic = req.body['make-repo-public']; - if (!takePublic) { - return next(new Error('Unsupported operation')); - } - const repository = req.repository as Repository; - await repository.editPublicPrivate({ private: false }); - req.individualContext.webContext.saveUserAlert(`${repository.full_name} is now public.`, 'Repository publish', UserAlertType.Success); - await repository.getDetails(NoCacheNoBackground); - return res.redirect(`/${repository.organization.name}/repos/${repository.name}?published`); -})); +// Disabling this function as it is dangerous: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement +// router.post('/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), asyncHandler(async function (req: ILocalRequest, res, next) { +// const repoPermissions = req.repoPermissions; +// if (!repoPermissions.allowAdministration) { +// return next(new Error('You do not have administrative permission on this repository')); +// } +// // only supporting the 'take public' operation now +// const takePublic = req.body['make-repo-public']; +// if (!takePublic) { +// return next(new Error('Unsupported operation')); +// } +// const repository = req.repository as Repository; +// await repository.editPublicPrivate({ private: false }); +// req.individualContext.webContext.saveUserAlert(`${repository.full_name} is now public.`, 'Repository publish', UserAlertType.Success); +// await repository.getDetails(NoCacheNoBackground); +// return res.redirect(`/${repository.organization.name}/repos/${repository.name}?published`); +// })); router.get('/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), asyncHandler(async function (req: ILocalRequest, res, next) { const { linkProvider, config, graphProvider } = getProviders(req); diff --git a/views/repos/repo.pug b/views/repos/repo.pug index 9aec661ed..fa2c62b4f 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -229,6 +229,7 @@ block content target='_blank' ) Webhooks + //- Disabling this function as it is dangerous: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement //- if repoPermissions.allowAdministration && repo.private === true //- ul.list-unstyled.list-vspace //- li From d4d4df7dea16c884c43449ce6e02dd98d038dbc2 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Mon, 28 Nov 2022 16:47:44 -0500 Subject: [PATCH 080/209] Better commenting --- routes/org/repos.ts | 2 +- views/repos/repo.pug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/org/repos.ts b/routes/org/repos.ts index f2e037d17..2a08db222 100644 --- a/routes/org/repos.ts +++ b/routes/org/repos.ts @@ -246,7 +246,7 @@ export async function renameRepositoryDefaultBranchEndToEnd(providers: IProvider }; } -// Disabling this function as it is dangerous: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement +// Disabling this function as it is high risk: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement // router.post('/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), asyncHandler(async function (req: ILocalRequest, res, next) { // const repoPermissions = req.repoPermissions; // if (!repoPermissions.allowAdministration) { diff --git a/views/repos/repo.pug b/views/repos/repo.pug index fa2c62b4f..f00227b04 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -229,7 +229,7 @@ block content target='_blank' ) Webhooks - //- Disabling this function as it is dangerous: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement + //- Disabling this function as it is high risk: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement //- if repoPermissions.allowAdministration && repo.private === true //- ul.list-unstyled.list-vspace //- li From 52eee44658159986feb3bfe0db60e76391a65a87 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 30 Nov 2022 15:27:50 -0500 Subject: [PATCH 081/209] Update Create-EnvOrgs.ps1 --- .github/scripts/Create-EnvOrgs.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/scripts/Create-EnvOrgs.ps1 b/.github/scripts/Create-EnvOrgs.ps1 index 4a7954ec3..c1fcfadb6 100644 --- a/.github/scripts/Create-EnvOrgs.ps1 +++ b/.github/scripts/Create-EnvOrgs.ps1 @@ -11,6 +11,7 @@ foreach ($org in $output.data.enterprise.organizations.nodes) { id = $($org.databaseId) type = @("public", "private") description = "$($org.description)" + locked = $True } $orgsArry += $envObj From ce1d827af0c6ad46a2bcf1126f59d315b54e9f7f Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Tue, 29 Nov 2022 13:49:35 -0500 Subject: [PATCH 082/209] Fix bug not showing orgs the user is an admin of. --- user/aggregate.ts | 10 +++++++--- views/index.pug | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/user/aggregate.ts b/user/aggregate.ts index f4459cbc6..5b686f6d6 100644 --- a/user/aggregate.ts +++ b/user/aggregate.ts @@ -24,7 +24,7 @@ export interface IAggregateUserOrganizations extends IKnownAggregateUserOrganiza export interface IKnownAggregateUserOrganizations { member: Organization[]; admin: Organization[]; - // in: TODO + in: Organization[]; // pending: TODO } @@ -127,9 +127,10 @@ export class UserContext { } known.admin = known.admin.sort(insensitiveSortOrganizations); known.member = known.member.sort(insensitiveSortOrganizations); + known.in = Array.prototype.concat(known.admin, known.member); // Available organizations const all = new Set(this._operations.organizations.values()); - for (const o of known.member) { + for (const o of known.in) { all.delete(o); } known.available = Array.from(all).sort(insensitiveSortOrganizations); @@ -164,7 +165,7 @@ export class UserContext { SettleToStateValue(this.aggregateLegacyRepositories()), ]); const results: IAggregateUserSummary = { - organizations: organizations.value || { member: [], admin: [], available: [] }, + organizations: organizations.value || { member: [], admin: [], available: [], in: [] }, teams: teams.value || { maintainer: [], member: [] }, repos: repositories.value || { byTeam: [] }, }; @@ -260,6 +261,7 @@ export class UserContext { const state: IKnownAggregateUserOrganizations = { admin: [], member: [], + in: [], }; for (let { organization, role } of membership) { if (role !== OrganizationMembershipRole.Admin && role !== OrganizationMembershipRole.Member) { @@ -340,7 +342,9 @@ export class UserContext { const state: IKnownAggregateUserOrganizations = { admin: admin.map(name => this._operations.getOrganization(name)), member: member.map(name => this._operations.getOrganization(name)), + in: [] }; + state.in = Array.prototype.concat(state.admin, state.member); return state; } } diff --git a/views/index.pug b/views/index.pug index 86f45ae2b..2e68894a1 100644 --- a/views/index.pug +++ b/views/index.pug @@ -57,14 +57,14 @@ block content h3 2-factor auth p PROTECTED - if onboarding !== true && overview && overview.organizations && overview.organizations.member && overview.organizations.member.length + if onboarding !== true && overview && overview.organizations && (overview.organizations.in && overview.organizations.in.length) h1 a.a-unstyled(name='orgs') Your #{config.brand.companyName} GitHub organization memberships else h4 You've successfully linked your #{config.brand.companyName} and GitHub accounts. - var currentPriority = '' - - var oom = overview && overview.organizations ? overview.organizations.member : [] + - var oom = overview && overview.organizations ? overview.organizations.in : [] each o in oom div.link-box a(href=o.name + onboardingPostfixUrl) @@ -228,7 +228,7 @@ block content - currentPriority = o.priority //-if currentPriority == 'secondary' //-if o.locked === true // o.membershipStateTemporary !== 'active' - if o.locked === true || o.hidden === true + if o.hidden === true //- Do not show by invitation only orgs at this time else div.link-box @@ -237,7 +237,11 @@ block content h6.text-muted strong(style='text-decoration: underline')= o.name = ' ' - small: span.label.label-muted Join + small: span.label.label-muted + if o.locked === true + | By invitation only + else + | Open to all if true || onboarding === true p: small= o.nativeUrl p.small.text-mute= o.description From f4990a10eb956166469e67f449b57cd63b3dca92 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Thu, 1 Dec 2022 10:27:44 -0500 Subject: [PATCH 083/209] Update env-orgs.json --- env-orgs.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/env-orgs.json b/env-orgs.json index b263495de..4564282f5 100644 --- a/env-orgs.json +++ b/env-orgs.json @@ -3,12 +3,14 @@ "name" : "NIHGOV", "id" : 2710462, "type": ["public", "private"], - "description" : "NIHโ€ฆTurning Discovery Into Healthยฎ" + "description" : "NIHโ€ฆTurning Discovery Into Healthยฎ", + "locked": true }, { "name" : "STRIDES", "id" : 69810051, "type": ["public", "private"], - "description" : "NIH Science and Technology Research Infrastructure for Discovery, Experimentation, and Sustainability (STRIDES) Initiative" + "description" : "NIH Science and Technology Research Infrastructure for Discovery, Experimentation, and Sustainability (STRIDES) Initiative", + "locked": true } ] From b5cce0ab68ad0ed65c1dc76a1ab7a68aa6437bed Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 6 Dec 2022 15:21:04 -0500 Subject: [PATCH 084/209] Reversed Org List Sort Order --- views/index.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/index.pug b/views/index.pug index 2e68894a1..de0644617 100644 --- a/views/index.pug +++ b/views/index.pug @@ -65,7 +65,7 @@ block content - var currentPriority = '' - var oom = overview && overview.organizations ? overview.organizations.in : [] - each o in oom + each o in Array.prototype.reverse(oom) div.link-box a(href=o.name + onboardingPostfixUrl) h2: strong= o.name From f8abdd7607ffeae416f68bf36ad7456d9a0895c9 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 6 Dec 2022 16:21:42 -0500 Subject: [PATCH 085/209] For real this time. --- views/index.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/index.pug b/views/index.pug index de0644617..46708e173 100644 --- a/views/index.pug +++ b/views/index.pug @@ -65,7 +65,7 @@ block content - var currentPriority = '' - var oom = overview && overview.organizations ? overview.organizations.in : [] - each o in Array.prototype.reverse(oom) + each o in oom.reverse() div.link-box a(href=o.name + onboardingPostfixUrl) h2: strong= o.name From e15a5be8b3e273394ac0ae4811e2c8db1da09fd0 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 7 Dec 2022 16:23:39 -0500 Subject: [PATCH 086/209] Added comment for significant code change --- views/ga.pug | 1 + 1 file changed, 1 insertion(+) diff --git a/views/ga.pug b/views/ga.pug index cc4378c69..c6f2bb61b 100644 --- a/views/ga.pug +++ b/views/ga.pug @@ -3,6 +3,7 @@ //- Licensed under the MIT license. See LICENSE file in the project root for full license information. //- +// This is no longer using Google Analytics, but Google Tag Manager. Be sure to set GOOGLE_ANALYTICS_KEY environment variable as a GTM key. if (googleAnalyticsKey) script. (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': From 729f083efbfdfb0229032d81d245f7112cc5ab5a Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 8 Dec 2022 12:42:45 -0500 Subject: [PATCH 087/209] Feature flag that allows users to sanitized details of a locked organization when trying to join. --- business/operations/index.ts | 4 + config/features.json | 3 +- docs/features.md | 7 ++ routes/org/join.ts | 69 ++++++++++++++++- views/org/public_view.pug | 143 +++++++++++++++++++++++++++++++++++ 5 files changed, 222 insertions(+), 4 deletions(-) create mode 100644 views/org/public_view.pug diff --git a/business/operations/index.ts b/business/operations/index.ts index 9bf44287f..c301de312 100644 --- a/business/operations/index.ts +++ b/business/operations/index.ts @@ -926,6 +926,10 @@ export class Operations return this.config?.features?.features.allowUndoSystem === true; } + allowUsersToViewLockedOrgDetails() { + return this.config?.features?.features.allowUsersToViewLockedOrgDetails === true; + } + // Eventually link/unlink should move from context into operations here to centralize more than just the events async fireLinkEvent(value): Promise { diff --git a/config/features.json b/config/features.json index 8188b6bdd..937e2a5aa 100644 --- a/config/features.json +++ b/config/features.json @@ -9,5 +9,6 @@ "allowAdministratorManualLinking": "env://FEATURE_FLAG_ALLOW_ADMIN_MANUAL_LINKING?trueIf=1", "allowApiClient": "env://FEATURE_FLAG_ALLOW_API_CLIENT?trueIf=1", "exposeWebhookIngestionEndpoint": "env://EXPOSE_WEBHOOK_INGESTION_ENDPOINT?trueIf=1", - "allowFossFundElections": "env://FEATURE_FLAG_FOSS_FUND_ELECTIONS?trueIf=1" + "allowFossFundElections": "env://FEATURE_FLAG_FOSS_FUND_ELECTIONS?trueIf=1", + "allowUsersToViewLockedOrgDetails": "env://FEATURE_FLAG_ALLOW_USERS_TO_VIEW_LOCKED_ORG_DETAILS?trueIf=1" } \ No newline at end of file diff --git a/docs/features.md b/docs/features.md index f520683d6..35ed497ed 100644 --- a/docs/features.md +++ b/docs/features.md @@ -37,6 +37,13 @@ variable value to `1`. - Risk/notes: when exposing this endpoint, webhook signature validation should also be performed. At this time, the webhook signature verification code is incomplete. - Recommendation: use a more secure route, such as the queue-based firehose processing method. +- allowUsersToViewLockedOrgDetails + + - Variable: `FEATURE_FLAG_ALLOW_USERS_TO_VIEW_LOCKED_ORG_DETAILS` + - Value: set to `1` to allow users to view sanitized detail page for locked organizations (eg information about how they can join) + - Default: `0` + - Risk/notes: Be sure the review the information included on the sanitized organization detail page before enabling. + ## Temporary features An optional set of features are being developed for use in summer 2020 as part diff --git a/routes/org/join.ts b/routes/org/join.ts index f0f509923..c2e8cfbf5 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -10,6 +10,7 @@ import asyncHandler from 'express-async-handler'; const router: Router = Router(); import querystring from 'querystring'; +import { IAggregateUserSummary } from '../../user/aggregate'; import { getProviders } from '../../transitional'; import { IndividualContext } from '../../user'; @@ -18,21 +19,83 @@ import RequireActiveGitHubSession from '../../middleware/github/requireActiveSes import { jsonError } from '../../middleware/jsonError'; import { Organization, Team } from '../../business'; import QueryCache from '../../business/queryCache'; -import { ReposAppRequest, OrganizationMembershipState, OrganizationMembershipRole } from '../../interfaces'; +import { ReposAppRequest, OrganizationMembershipState, OrganizationMembershipRole, OrganizationMembershipRoleQuery } from '../../interfaces'; router.use(function (req: ReposAppRequest, res, next) { - const organization = req.organization; + const { organization } = req; let err = null; + if (organization.locked) { + + const { allowUsersToViewLockedOrgDetails } = getProviders(req).config.features; + + if (allowUsersToViewLockedOrgDetails) { + return showOrgJoinDetails(req) + } + + console.error(`Default functionality does not allow users to access the join page of a locked organization. To override this set the feature flag 'FEATURE_FLAG_ALLOW_USERS_TO_VIEW_LOCKED_ORG_DETAILS=1'`) + err = new Error('This organization is locked to new members.'); err.detailed = `At this time, the maintainers of the ${organization.name} organization have decided to not enable onboarding through this portal.`; err.skipLog = true; + next(err); } - next(err); + + next(); }); router.use(RequireActiveGitHubSession); +async function showOrgJoinDetails(req: ReposAppRequest) { + // Present user with a sanitized version of the organization detail page for users attempting to join a locked + // organization when the ALLOW_USERS_TO_VIEW_LOCKED_ORG_DETAILS feature flag is enabled. Attempting to keep + // this implementation as close to the default org get route as possible + const { individualContext, organization } = req; + + + const [ linkedOrgAdmins, unlinkedOrgAdmins, orgDetails, organizationOverview ] = await Promise.all([ + organization.getLinkedMembers({ role: OrganizationMembershipRoleQuery.Admin }), + organization.getUnlinkedMembers({ role: OrganizationMembershipRoleQuery.Admin }), + organization.getDetails(), + individualContext.aggregations.getAggregatedOrganizationOverview(organization) + ]) + + // clean up admin data for the front end + const organizationAdmins = Array.prototype.concat(linkedOrgAdmins, unlinkedOrgAdmins).reduce((acc, admin) => { + const {member, link} = admin; + + // linked and unlinked admins return slightly different data structures + const login = member ? member.login : admin.login; + + // fallback to corporateUsername if corporateMailAddress is not available + const corporateMailAddress = link ? link.corporateMailAddress || link.corporateUsername : undefined; + + acc.push({ + login, + corporateMailAddress + }) + + return acc + }, []); + + const results = { + orgUser: organization.memberFromEntity(orgDetails), + orgDetails, //org details from GitHub + organizationOverview, + organizationAdmins, + }; + + req.individualContext.webContext.render({ + view: 'org/public_view', + title: organization.name, + state: { + accountInfo: results, + organization, + organizationEntity: organization.getEntity(), + }, + }); +} + function clearAuditListAndRedirect(res: Response, organization: Organization, onboarding: boolean, req: any, state: OrganizationMembershipState) { // Behavior change, only important to those not using GitHub's 2FA enforcement feature; no longer clearing the cache const url = organization.baseUrl + 'security-check' + (onboarding ? '?onboarding=' + onboarding : '?joining=' + organization.name); diff --git a/views/org/public_view.pug b/views/org/public_view.pug new file mode 100644 index 000000000..fc80bbcf3 --- /dev/null +++ b/views/org/public_view.pug @@ -0,0 +1,143 @@ +//- +//- Copyright (c) Microsoft. +//- Licensed under the MIT license. See LICENSE file in the project root for full license information. +//- + +extends ../layout + +block js_doc_ready + | if (typeof initializeManageFilter == 'function') { initializeManageFilter(); } + | if (typeof initializeMembershipFilter == 'function') { initializeMembershipFilter(); } + +block content + - var fileSize = viewServices.fileSize + - var moment = viewServices.moment + - var octicon = viewServices.octicon + + div.container + - var orgAccount = accountInfo.orgUser + - var orgUser = accountInfo.orgUser.organizationProfile + - var organizationAdmins = accountInfo.organizationAdmins + + div.container + h1(style='margin-bottom:18px') + span.capitalize= organization.name + ' ' + small Organization + div.row + div.col-md-3.col-lg-3 + p(style='margin-bottom:18px') + img.img-thumbnail.img-responsive(src=orgAccount.avatar(400), alt=`${organization.name} logo`) + p(style='margin-top:18px') + a.btn.btn-sm.btn-muted(href='https://github.com/' + organization.name, target='_new') + | Open on GitHub + div.col-md-8.col-lg-8.col-md-offset-1.col-lg-offset-1 + div.row + div.col-md-6.col-lg-6 + if orgUser.company + h6 Company + p= orgUser.company + if orgUser.location + h6 Location + p= orgUser.location + if orgUser.email + h6 E-mail + p= orgUser.email + if orgUser.blog + h6 On the Web + p + a(href=orgUser.blog, target='_new')= orgUser.blog + if orgAccount && orgAccount.getEntity() && orgAccount.getEntity().created_at + - var createdAt = new Date(orgAccount.getEntity().created_at) + h6 Created + p + time(datetime=createdAt.toISOString())= createdAt.toDateString() + if orgAccount && orgAccount.getEntity() && orgAccount.getEntity().updated_at + - var updatedAt = new Date(orgAccount.getEntity().updated_at) + h6 Updated + p + time(datetime=updatedAt.toISOString())= updatedAt.toDateString() + hr + if organization.configuredOrganizationRepositoryTypes + h6 Supported Repository Types + ul.list-unstyled + li Public + if organization.configuredOrganizationRepositoryTypes == 'publicprivate' || organization.configuredOrganizationRepositoryTypes == 'private' + li Private + if organizationEntity + hr + if organizationEntity.disk_usage + h6 STORAGE USED + ul.list-unstyled: li + != octicon('database', 13) + = ' ' + fileSize(organizationEntity.disk_usage * 1024) + + if organizationEntity.default_repository_permission + h6 DEFAULT REPOSITORY PERMISSION + ul.list-unstyled: li + if organizationEntity.default_repository_permission == 'none' + | Private repos are only visible to members with read permission + else + = organizationEntity.default_repository_permission + + if organizationEntity.members_can_create_repositories !== undefined + h6 REPOSITORY CREATE PERMISSIONS + if organizationEntity.members_can_create_repositories + ul.list-unstyled: li Members can create repositories directly on GitHub.com. + else + ul.list-unstyled: li Members cannot directly create repositories on GitHub.com. + + if organizationEntity.two_factor_requirement_enabled !== undefined + h6 TWO-FACTOR REQUIREMENTS + if organizationEntity.two_factor_requirement_enabled + ul.list-unstyled: li Two-factor authentication required + else + ul.list-unstyled: li.text-danger Not required + + div.col-md-6.col-lg-h6 + h6 Repositories + if orgUser.public_repos + h2 + = orgUser.public_repos + ' ' + small Public + if orgUser.total_private_repos + h4 + = orgUser.total_private_repos + ' ' + small Private + + hr + - var isEnterpriseCloud = orgUser && orgUser.plan && orgUser.plan.name == 'enterprise' + if isEnterpriseCloud + h6 ∞ Repositories + else + h6 Remaining Repositories + if orgUser.plan && orgUser.plan.private_repos + h4.capitalize + = orgUser.plan.name + ' ' + small Plan + if !isEnterpriseCloud + h6 + = (orgUser.plan.private_repos - orgUser.total_private_repos) + ' ' + small Private + if !isEnterpriseCloud + h4 + | ∞  + small Public + if organization.locked + hr + p(class='text-danger') + span(style='margin-right: 5px') + != octicon('alert', 17) + = 'Invitation Required' + p Access to this organization requires an invitation from one of the following administrators. + h6 Admins + ul.list-unstyled + - var admins = organizationAdmins + - var adminCount = admins.length + - for (var i = 0; i < adminCount; i++) + li + span(style='margin-right: 5px') + != octicon('mark-github', 17) + if admins[i].corporateMailAddress + a(href='mailto://' + admins[i].corporateMailAddress)= admins[i].login + else + a(href='https://github.com/' + admins[i].login, target='_new')= admins[i].login From f156a98e9647384189a3f415720ecd2ec2abd9c5 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 14 Dec 2022 14:51:10 -0500 Subject: [PATCH 088/209] Fixed malformed email URL --- views/org/public_view.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/org/public_view.pug b/views/org/public_view.pug index fc80bbcf3..5a4c63ae2 100644 --- a/views/org/public_view.pug +++ b/views/org/public_view.pug @@ -138,6 +138,6 @@ block content span(style='margin-right: 5px') != octicon('mark-github', 17) if admins[i].corporateMailAddress - a(href='mailto://' + admins[i].corporateMailAddress)= admins[i].login + a(href='mailto:' + admins[i].corporateMailAddress)= admins[i].login else a(href='https://github.com/' + admins[i].login, target='_new')= admins[i].login From 35b76a69cabd1205b3875988b6048ddaadc561bd Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 15 Dec 2022 08:42:36 -0500 Subject: [PATCH 089/209] Update org join view to render admin details more consistently with the rest of the app. --- routes/org/join.ts | 7 +++++-- views/org/public_view.pug | 28 ++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/routes/org/join.ts b/routes/org/join.ts index c2e8cfbf5..8cedc850b 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -68,11 +68,14 @@ async function showOrgJoinDetails(req: ReposAppRequest) { const login = member ? member.login : admin.login; // fallback to corporateUsername if corporateMailAddress is not available - const corporateMailAddress = link ? link.corporateMailAddress || link.corporateUsername : undefined; + const mailAddress = link ? link.corporateMailAddress || link.corporateUsername : undefined; + const primaryName = link ? link.corporateDisplayName || link.corporateUsername : member.login; acc.push({ login, - corporateMailAddress + mailAddress, + avatar_url: member.avatar_url, + primaryName }) return acc diff --git a/views/org/public_view.pug b/views/org/public_view.pug index 5a4c63ae2..92720e37a 100644 --- a/views/org/public_view.pug +++ b/views/org/public_view.pug @@ -129,15 +129,27 @@ block content != octicon('alert', 17) = 'Invitation Required' p Access to this organization requires an invitation from one of the following administrators. - h6 Admins + h6(style='margin-bottom:.3em') Admins ul.list-unstyled - var admins = organizationAdmins - var adminCount = admins.length - for (var i = 0; i < adminCount; i++) - li - span(style='margin-right: 5px') - != octicon('mark-github', 17) - if admins[i].corporateMailAddress - a(href='mailto:' + admins[i].corporateMailAddress)= admins[i].login - else - a(href='https://github.com/' + admins[i].login, target='_new')= admins[i].login + - var admin = admins[i] + li(style='vertical-align:top;width:370px') + ul.list-inline + if admin.avatar_url + li(style='vertical-align:top;margin-top:12px;padding-right:3px'): img( + alt=admin.login, + src=admin.avatar_url + '&s=96', + style='width:36px;height:36px;border-radius:20px') + li + ul.list-unstyled(style='margin-right:16px') + li: h5(style='margin-bottom:.3em') + a(href='/people?q=' + admin.login)= admin.primaryName + .label.label-info(title=organization.name + ' organization owner', style='margin-left: 5px; cursor: default') Owner + ul.list-inline + if admin.primaryName != admin.login + li: p(style='font-size: .8em')= admin.login + if admin.mailAddress + li: a(href='mailto:' + admin.mailAddress, title='Send corporate email to ' + admin.mailAddress) + != octicon('mail', 16) From 128097b491b4b4553ee1d47bd953b0416a41538e Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 15 Dec 2022 11:22:17 -0500 Subject: [PATCH 090/209] Remove border-radius, and Admins header. --- views/org/public_view.pug | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/views/org/public_view.pug b/views/org/public_view.pug index 92720e37a..c27b03281 100644 --- a/views/org/public_view.pug +++ b/views/org/public_view.pug @@ -129,7 +129,6 @@ block content != octicon('alert', 17) = 'Invitation Required' p Access to this organization requires an invitation from one of the following administrators. - h6(style='margin-bottom:.3em') Admins ul.list-unstyled - var admins = organizationAdmins - var adminCount = admins.length @@ -141,7 +140,7 @@ block content li(style='vertical-align:top;margin-top:12px;padding-right:3px'): img( alt=admin.login, src=admin.avatar_url + '&s=96', - style='width:36px;height:36px;border-radius:20px') + style='width:36px;height:36px;') li ul.list-unstyled(style='margin-right:16px') li: h5(style='margin-bottom:.3em') From bf2f6cd2ebb3c383ade6f2f04b204ed9127acb55 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 15 Dec 2022 12:18:44 -0500 Subject: [PATCH 091/209] Update public_view.pug --- views/org/public_view.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/org/public_view.pug b/views/org/public_view.pug index c27b03281..0fa731a14 100644 --- a/views/org/public_view.pug +++ b/views/org/public_view.pug @@ -150,5 +150,5 @@ block content if admin.primaryName != admin.login li: p(style='font-size: .8em')= admin.login if admin.mailAddress - li: a(href='mailto:' + admin.mailAddress, title='Send corporate email to ' + admin.mailAddress) + li: a(href='mailto:' + admin.mailAddress, title='Send email to ' + admin.mailAddress) != octicon('mail', 16) From 41be9068c271bc31da2e8d76ba272eb6b19f1767 Mon Sep 17 00:00:00 2001 From: Joel Peterson Date: Thu, 15 Dec 2022 19:57:38 -0500 Subject: [PATCH 092/209] Fixed comment --- views/ga.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/ga.pug b/views/ga.pug index c6f2bb61b..632444673 100644 --- a/views/ga.pug +++ b/views/ga.pug @@ -3,7 +3,7 @@ //- Licensed under the MIT license. See LICENSE file in the project root for full license information. //- -// This is no longer using Google Analytics, but Google Tag Manager. Be sure to set GOOGLE_ANALYTICS_KEY environment variable as a GTM key. +//- This is no longer using Google Analytics, but Google Tag Manager. Be sure to set GOOGLE_ANALYTICS_KEY environment variable as a GTM key. if (googleAnalyticsKey) script. (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': From 149d7e99181b9bb1d83bf7587b1474f43d9f5902 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 16 Dec 2022 08:15:31 -0500 Subject: [PATCH 093/209] Link user's GitHub profile to admin card. --- views/org/public_view.pug | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/views/org/public_view.pug b/views/org/public_view.pug index 0fa731a14..64cafa2f1 100644 --- a/views/org/public_view.pug +++ b/views/org/public_view.pug @@ -148,7 +148,8 @@ block content .label.label-info(title=organization.name + ' organization owner', style='margin-left: 5px; cursor: default') Owner ul.list-inline if admin.primaryName != admin.login - li: p(style='font-size: .8em')= admin.login + li: p(style='font-size: .8em') + a(href='https://github.com/' + admin.login, target='_new', style='color: black; text-decoration:none')= admin.login if admin.mailAddress li: a(href='mailto:' + admin.mailAddress, title='Send email to ' + admin.mailAddress) != octicon('mail', 16) From a74a9d33c9c54098d1931450b0b7659496ff9742 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 16 Dec 2022 08:18:04 -0500 Subject: [PATCH 094/209] Update public_view pug file to use consistent casing. --- routes/org/join.ts | 2 +- views/org/{public_view.pug => publicView.pug} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename views/org/{public_view.pug => publicView.pug} (100%) diff --git a/routes/org/join.ts b/routes/org/join.ts index 8cedc850b..6e1857db3 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -89,7 +89,7 @@ async function showOrgJoinDetails(req: ReposAppRequest) { }; req.individualContext.webContext.render({ - view: 'org/public_view', + view: 'org/publicView', title: organization.name, state: { accountInfo: results, diff --git a/views/org/public_view.pug b/views/org/publicView.pug similarity index 100% rename from views/org/public_view.pug rename to views/org/publicView.pug From e061de525d987c5759a4f04497ced93e17f46ca8 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 16 Dec 2022 14:16:04 -0500 Subject: [PATCH 095/209] Add administrative route that exports unlinked members as a csv. --- routes/administration/index.ts | 31 +++++++++++++++++++++++++++++++ views/administration/menu.pug | 1 + 2 files changed, 32 insertions(+) diff --git a/routes/administration/index.ts b/routes/administration/index.ts index e94d8c359..85043062c 100644 --- a/routes/administration/index.ts +++ b/routes/administration/index.ts @@ -46,4 +46,35 @@ router.get('/', (req: ReposAppRequest, res, next) => { }); }); +router.get('/unlinked-user-report', async (req: ReposAppRequest, res, next) => { + try { + const { operations: { organizations } } = getProviders(req); + + const checks = []; + + for (let [key, value] of organizations.entries()) { + checks.push(value.getUnlinkedMembers().then(unlinkedMembers => { + return unlinkedMembers.map(unlinkedMember => { + return [ + unlinkedMember.id, unlinkedMember.login, key + ]; + }); + })); + }; + + const results = await Promise.all(checks); + + const unlinkedMembers = results.reduce((acc, entry) => { + acc += `${entry.join(',')}\r\n` + return acc + },'id,login,organization\r\n'); + + res.header('Content-Type', 'text/csv'); + res.attachment('unlinked-user-report.csv'); + res.send(unlinkedMembers); + } catch (err) { + next(err); + } +}); + export default router; diff --git a/views/administration/menu.pug b/views/administration/menu.pug index a37664f79..ecd6b5015 100644 --- a/views/administration/menu.pug +++ b/views/administration/menu.pug @@ -15,6 +15,7 @@ .panel-heading Data .list-group a.list-group-item(href='/administration/contributingorgs', class={active: view === 'administration/contributingorgs'}) Contributed orgs + a.list-group-item(href='/administration/unlinked-user-report') Unlinked user report if _corpAdminUrls .panel.panel-default From 61a04a938b26bafcb3427a7592c9f35c8421cec0 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 29 Dec 2022 11:44:06 -0500 Subject: [PATCH 096/209] Update user report to include both linked and nonlinked users --- routes/administration/index.ts | 35 +++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/routes/administration/index.ts b/routes/administration/index.ts index 85043062c..d85c81a30 100644 --- a/routes/administration/index.ts +++ b/routes/administration/index.ts @@ -46,32 +46,41 @@ router.get('/', (req: ReposAppRequest, res, next) => { }); }); -router.get('/unlinked-user-report', async (req: ReposAppRequest, res, next) => { +/* +Returns a CSV of every org and its members, with a column indicating whether the member is linked or not +*/ +router.get('/users-report', async (req: ReposAppRequest, res, next) => { try { const { operations: { organizations } } = getProviders(req); - + const checks = []; - - for (let [key, value] of organizations.entries()) { - checks.push(value.getUnlinkedMembers().then(unlinkedMembers => { - return unlinkedMembers.map(unlinkedMember => { + + for (let [orgName, org] of organizations.entries()) { + + checks.push(org.getUnlinkedMembers().then(unlinkedMembers => unlinkedMembers.map(unlinkedMember => ([orgName, unlinkedMember.id, unlinkedMember.login, false])))); + + checks.push(org.getLinkedMembers().then(linkedMembers => { + return linkedMembers.map(linkedMember => { + const { + member + } = linkedMember; return [ - unlinkedMember.id, unlinkedMember.login, key + orgName, member.id, member.login, true ]; }); })); }; - + const results = await Promise.all(checks); - - const unlinkedMembers = results.reduce((acc, entry) => { + + const usersReport = results.reduce((acc, entry) => { acc += `${entry.join(',')}\r\n` return acc - },'id,login,organization\r\n'); + }, 'Organization,UserId,UserLogin,IsLinked\r\n'); res.header('Content-Type', 'text/csv'); - res.attachment('unlinked-user-report.csv'); - res.send(unlinkedMembers); + res.attachment('users-report.csv'); + res.send(usersReport); } catch (err) { next(err); } From cfc19b3eca5e2df5de90bad5853b428c4f57ed50 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 29 Dec 2022 16:31:47 -0500 Subject: [PATCH 097/209] Deduplicate user report. --- business/organization.ts | 4 +++ package-lock.json | 48 ++++++++++++++++++++++++++++ package.json | 3 +- routes/administration/index.ts | 57 +++++++++++++++++++++------------- views/administration/menu.pug | 2 +- 5 files changed, 90 insertions(+), 24 deletions(-) diff --git a/business/organization.ts b/business/organization.ts index 9938dfe96..ecba72e22 100644 --- a/business/organization.ts +++ b/business/organization.ts @@ -957,6 +957,10 @@ export class Organization { return pairs.filter(pair => !pair.link).map(entry => entry.member); } + async getUnlinkedAndLinkedMembers(options?: IGetOrganizationMembersOptions): Promise { + return await this.getMemberPairs(options); + } + async getTeams(options?: IPagedCacheOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this._operations); diff --git a/package-lock.json b/package-lock.json index 4ac612db7..7295daf90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,6 +46,7 @@ "github-username-regex": "1.0.0", "hsts": "2.2.0", "js-yaml": "4.1.0", + "json-2-csv": "^3.18.0", "jsonc": "2.0.0", "jsonwebtoken": "8.5.1", "jwks-rsa": "2.1.4", @@ -4028,6 +4029,14 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, + "node_modules/deeks": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/deeks/-/deeks-2.6.0.tgz", + "integrity": "sha512-zu/g4fVjPreYuP11f3o5W7TeSRscpnn9LQO15lxIXu66MwOopIxj4jhLDEGMW7JkZYqWEz5JG3qs88kHNMY08g==", + "engines": { + "node": ">= 12" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4170,6 +4179,14 @@ "node": ">=8" } }, + "node_modules/doc-path": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-3.0.6.tgz", + "integrity": "sha512-fUNXXk+4MbfKkXec41cIyD5DTPISVD0MzMPWX2qz+kL7otFtQRHCkyPaD8qmLyQpfYQWye/z7oXeeD0nQp8HYQ==", + "engines": { + "node": ">=12" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -7027,6 +7044,18 @@ "node": ">=4" } }, + "node_modules/json-2-csv": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-3.18.0.tgz", + "integrity": "sha512-+1lxMDaIx71QWVaENrphLb+o9xUY34nxVW6dKiRzFM2YYyxFbIkKNn4J3oVEOn/xxNtkmg8XVGmpZT+wIoi5xw==", + "dependencies": { + "deeks": "2.6.0", + "doc-path": "3.0.6" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -13648,6 +13677,11 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, + "deeks": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/deeks/-/deeks-2.6.0.tgz", + "integrity": "sha512-zu/g4fVjPreYuP11f3o5W7TeSRscpnn9LQO15lxIXu66MwOopIxj4jhLDEGMW7JkZYqWEz5JG3qs88kHNMY08g==" + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -13754,6 +13788,11 @@ "path-type": "^4.0.0" } }, + "doc-path": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-3.0.6.tgz", + "integrity": "sha512-fUNXXk+4MbfKkXec41cIyD5DTPISVD0MzMPWX2qz+kL7otFtQRHCkyPaD8qmLyQpfYQWye/z7oXeeD0nQp8HYQ==" + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -15878,6 +15917,15 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-2-csv": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-3.18.0.tgz", + "integrity": "sha512-+1lxMDaIx71QWVaENrphLb+o9xUY34nxVW6dKiRzFM2YYyxFbIkKNn4J3oVEOn/xxNtkmg8XVGmpZT+wIoi5xw==", + "requires": { + "deeks": "2.6.0", + "doc-path": "3.0.6" + } + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", diff --git a/package.json b/package.json index 425bfcb5e..8f9bdbecc 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "github-username-regex": "1.0.0", "hsts": "2.2.0", "js-yaml": "4.1.0", + "json-2-csv": "^3.18.0", "jsonc": "2.0.0", "jsonwebtoken": "8.5.1", "jwks-rsa": "2.1.4", @@ -160,4 +161,4 @@ "ts-node": "10.7.0", "typescript": "4.6.3" } -} \ No newline at end of file +} diff --git a/routes/administration/index.ts b/routes/administration/index.ts index d85c81a30..8cea95ada 100644 --- a/routes/administration/index.ts +++ b/routes/administration/index.ts @@ -15,6 +15,9 @@ import getCompanySpecificDeployment from '../../middleware/companySpecificDeploy import RouteApp from './app'; import RouteApps from './apps'; +import { json2csvAsync } from 'json-2-csv'; +import _ from 'lodash'; + router.use('*', asyncHandler(async function (req: ReposAppRequest, res, next) { const { corporateAdministrationProfile } = getProviders(req); if (corporateAdministrationProfile && corporateAdministrationProfile.urls) { @@ -52,35 +55,45 @@ Returns a CSV of every org and its members, with a column indicating whether the router.get('/users-report', async (req: ReposAppRequest, res, next) => { try { const { operations: { organizations } } = getProviders(req); - const checks = []; + const users = {}; for (let [orgName, org] of organizations.entries()) { - - checks.push(org.getUnlinkedMembers().then(unlinkedMembers => unlinkedMembers.map(unlinkedMember => ([orgName, unlinkedMember.id, unlinkedMember.login, false])))); - - checks.push(org.getLinkedMembers().then(linkedMembers => { - return linkedMembers.map(linkedMember => { - const { - member - } = linkedMember; - return [ - orgName, member.id, member.login, true - ]; - }); + checks.push(org.getUnlinkedAndLinkedMembers() + .then(memberPairs => { + + memberPairs.forEach(memberPair => { + const { member: { id: UserId, login: UserLogin }, link: memberLink } = memberPair; + const isLinked = memberLink ? true : false; + let userObj = { UserLogin, UserId, Organizations: [], IsLinked: isLinked }; + + if (isLinked) { + const { + corporateId: CorporateId, + corporateMailAddress: CorporateMailAddress, + corporateUsername: CorporateUsername, + corporateAlias: CorporateAlias, + corporateDisplayName: CorporateDisplayName + } = memberLink; + + userObj = { ...userObj, ...{ CorporateId, CorporateUsername, CorporateAlias, CorporateDisplayName, CorporateMailAddress } } + } + + users[UserLogin] = users[UserLogin] || userObj; + users[UserLogin].Organizations.push(orgName); + }); })); - }; - - const results = await Promise.all(checks); - - const usersReport = results.reduce((acc, entry) => { - acc += `${entry.join(',')}\r\n` - return acc - }, 'Organization,UserId,UserLogin,IsLinked\r\n'); + }; + + await Promise.all(checks) + const header = 'UserLogin,UserId,Organizations,IsLinked,CorporateId,CorporateMailAddress,CorporateUsername,CorporateAlias,CorporateDisplayName'; + const cleanedObjects: object[] = _.sortBy(Object.values(users), 'UserLogin'); + const payload = await json2csvAsync(cleanedObjects, { keys: header.split(','), emptyFieldValue: '' }); + res.header('Content-Type', 'text/csv'); res.attachment('users-report.csv'); - res.send(usersReport); + res.send(payload); } catch (err) { next(err); } diff --git a/views/administration/menu.pug b/views/administration/menu.pug index ecd6b5015..d08cec47a 100644 --- a/views/administration/menu.pug +++ b/views/administration/menu.pug @@ -15,7 +15,7 @@ .panel-heading Data .list-group a.list-group-item(href='/administration/contributingorgs', class={active: view === 'administration/contributingorgs'}) Contributed orgs - a.list-group-item(href='/administration/unlinked-user-report') Unlinked user report + a.list-group-item(href='/administration/users-report') Users report if _corpAdminUrls .panel.panel-default From ef2706c473fb854b1aa9e67231ec44c03ff700e2 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:25:59 -0500 Subject: [PATCH 098/209] Update container.yml --- .github/workflows/container.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index f800d71d5..2f5a94afa 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -1,4 +1,4 @@ -name: Build +name: Docker Image - Build on: push: From cc2aff9032c7721ae5f7d4fc73d57692e8ebf34e Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:26:40 -0500 Subject: [PATCH 099/209] Update main_nihgithubportal.yml --- .github/workflows/main_nihgithubportal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 55f8013a8..df2a8b571 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -1,7 +1,7 @@ # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy # More GitHub Actions for Azure: https://github.com/Azure/actions -name: Build and deploy Node.js app to Azure Web App - nihgithubportal +name: NIH GHMP (Prod) - Build on: push: From 8f62e721aac41c60108c2543441b886a3e03d219 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:26:57 -0500 Subject: [PATCH 100/209] Update staging_nihdevgithubportal.yml --- .github/workflows/staging_nihdevgithubportal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index e662fd456..a82fa6c95 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -1,7 +1,7 @@ # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy # More GitHub Actions for Azure: https://github.com/Azure/actions -name: Build and deploy Node.js app to Azure Web App - nihdevgithubportal +name: NIH GHMP (Dev) - Build on: push: From 76a71e3a29ce3a046fe2cc1776c8966a73f12fc4 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:27:18 -0500 Subject: [PATCH 101/209] Update staging_nihdevgithubportal.yml --- .github/workflows/staging_nihdevgithubportal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index a82fa6c95..ac3ea27d1 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -1,7 +1,7 @@ # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy # More GitHub Actions for Azure: https://github.com/Azure/actions -name: NIH GHMP (Dev) - Build +name: NIH GHMP (Dev) - Build & Deploy on: push: From ff098d96ebe31742a88d5d6253d5151d75bc4410 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:27:31 -0500 Subject: [PATCH 102/209] Update main_nihgithubportal.yml --- .github/workflows/main_nihgithubportal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index df2a8b571..00dadfcae 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -1,7 +1,7 @@ # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy # More GitHub Actions for Azure: https://github.com/Azure/actions -name: NIH GHMP (Prod) - Build +name: NIH GHMP (Prod) - Build & Deploy on: push: From b5823d50348d52a816dfe0e4bec5d0a03dc52d8a Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:28:30 -0500 Subject: [PATCH 103/209] Update staging_create_acr_image.yml --- .github/workflows/staging_create_acr_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index c042ab00e..4d173b287 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -1,4 +1,4 @@ -name: Linux Container Node Workflow +name: Container Image (Dev) - Build & Register on: workflow_dispatch: From 31876bf9628203e887d510e5634a980c1661f578 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:29:11 -0500 Subject: [PATCH 104/209] Update main_create_acr_image.yaml --- .github/workflows/main_create_acr_image.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_create_acr_image.yaml b/.github/workflows/main_create_acr_image.yaml index 627bfdbbc..2ac7ecfd9 100644 --- a/.github/workflows/main_create_acr_image.yaml +++ b/.github/workflows/main_create_acr_image.yaml @@ -1,4 +1,4 @@ -name: Linux Container Node Workflow +name: Container Image (Prod) - Build & Register on: workflow_dispatch: From 7d885f70a947c86ec988d159563d8e0fcb8bad72 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:30:29 -0500 Subject: [PATCH 105/209] Update staging_create_acr_image.yml --- .github/workflows/staging_create_acr_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index 4d173b287..cc3c64005 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -1,4 +1,4 @@ -name: Container Image (Dev) - Build & Register +name: NIH GHMP Container (Dev) - Build & Register on: workflow_dispatch: From e420e0a509987fb0b86569ee0c4c7cddcf23aad2 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:30:46 -0500 Subject: [PATCH 106/209] Update main_create_acr_image.yaml --- .github/workflows/main_create_acr_image.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_create_acr_image.yaml b/.github/workflows/main_create_acr_image.yaml index 2ac7ecfd9..22f175e2d 100644 --- a/.github/workflows/main_create_acr_image.yaml +++ b/.github/workflows/main_create_acr_image.yaml @@ -1,4 +1,4 @@ -name: Container Image (Prod) - Build & Register +name: NIH GHMP Container (Prod) - Build & Register on: workflow_dispatch: From 905af1f8ea9e55f551ee7dd882a4012b7b8df7c6 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:31:47 -0500 Subject: [PATCH 107/209] Update container.yml --- .github/workflows/container.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index 2f5a94afa..4b776c169 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -1,4 +1,4 @@ -name: Docker Image - Build +name: Unused Docker Image - Build on: push: From e8884d982ecf54e0e4a0b9ece70e1ca2b01ef1de Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:32:21 -0500 Subject: [PATCH 108/209] Update codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6edaa622d..37924397c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,4 +1,4 @@ -name: "Code scanning - action" +name: CodeQL Analysis on: push: From 987637286020798e51b4861d830bd46ae2da2991 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:33:18 -0500 Subject: [PATCH 109/209] Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 597f7d3a1..5dae04983 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: Test +name: GitHub NPM Test on: push: From 9f825f647454f832f91fa7870a3db2a864995746 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:33:29 -0500 Subject: [PATCH 110/209] Update codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 37924397c..99b9ce576 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,4 +1,4 @@ -name: CodeQL Analysis +name: GitHub CodeQL Analysis on: push: From 3442ae3f3bd73e505f7edd79b17075f73aafc66d Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 09:46:29 -0500 Subject: [PATCH 111/209] Create update_orgsettings_table.yaml --- .../workflows/update_orgsettings_table.yaml | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/update_orgsettings_table.yaml diff --git a/.github/workflows/update_orgsettings_table.yaml b/.github/workflows/update_orgsettings_table.yaml new file mode 100644 index 000000000..00365bc66 --- /dev/null +++ b/.github/workflows/update_orgsettings_table.yaml @@ -0,0 +1,67 @@ +name: NIH GHMP (Dev) - Update Database Org Settings + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1.127.0 + with: + ruby-version: '3.0' # Not needed with a .ruby-version file + + - name: update ruby reqs + run: | + gem install jwt + + - name: run jwt generator + run: | + ruby .github/scripts/jwt.rb >> token + ls -lah + env: + PEM: ${{ secrets.APP_PEM}} + + + - name: run gh cli to get app install info + run: | + curl \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $(cat token)" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/app/installations | jq >> app_output.json + + - name: run powershell script to build sql + run: | + .github/scripts/Create-PSQLUpdate.ps1 + shell: pwsh + + env: + PAT: ${{ secrets.ENT_READ_PAT }} + + - name: output sql + run: | + ls -lah + cat ./app_output.json + cat ./update.sql + + - name: Azure Login + uses: Azure/login@v1.4.6 + with: + creds: '{"clientId":"${{ secrets.CLIENT_ID }}","clientSecret":"${{ secrets.CLIENT_SECRET }}","subscriptionId":"${{ secrets.SUBSCRIPTION_ID }}","tenantId":"${{ secrets.TENANT_ID }}"}' + + - name: PSQL update + uses: azure/postgresql@v1 + with: + connection-string: ${{โ€ฏsecrets.PSQL_CONN }} + server-name: nih-portaldb.postgres.database.azure.com + plsql-file: ./update.sql + + - name: Azure CLI Action + uses: Azure/cli@v1 + with: + # Specify the script here + inlineScript: az webapp restart --name REPLACENAME --resource-group REPLACE_RESOURCE_GROUP + From f05b8f8fa43a0c1cce7b6631a953b3e17f33a4b3 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 09:48:36 -0500 Subject: [PATCH 112/209] Create jwt.rb --- .github/scripts/jwt.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/scripts/jwt.rb diff --git a/.github/scripts/jwt.rb b/.github/scripts/jwt.rb new file mode 100644 index 000000000..31f1dfdf3 --- /dev/null +++ b/.github/scripts/jwt.rb @@ -0,0 +1,19 @@ +require 'openssl' +require 'jwt' # https://rubygems.org/gems/jwt + +# Private key contents +private_pem = ENV["PEM"] +private_key = OpenSSL::PKey::RSA.new(private_pem) + +# Generate the JWT +payload = { + # issued at time, 60 seconds in the past to allow for clock drift + iat: Time.now.to_i - 60, + # JWT expiration time (10 minute maximum) + exp: Time.now.to_i + (10 * 60), + # GitHub App's identifier + iss: 240324 +} + +jwt = JWT.encode(payload, private_key, "RS256") +puts jwt From a8d173a69ff8e759cfb8d7581856d096359ea669 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 09:49:07 -0500 Subject: [PATCH 113/209] Update jwt.rb --- .github/scripts/jwt.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/jwt.rb b/.github/scripts/jwt.rb index 31f1dfdf3..faed28e1b 100644 --- a/.github/scripts/jwt.rb +++ b/.github/scripts/jwt.rb @@ -12,7 +12,7 @@ # JWT expiration time (10 minute maximum) exp: Time.now.to_i + (10 * 60), # GitHub App's identifier - iss: 240324 + iss: REPLACE_WITH_APP_ID } jwt = JWT.encode(payload, private_key, "RS256") From 4daf2bf93815c3d01421f58506d6c0fac1256b8a Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 09:52:36 -0500 Subject: [PATCH 114/209] Create Create-PSQLUpdate.ps1 --- .github/scripts/Create-PSQLUpdate.ps1 | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .github/scripts/Create-PSQLUpdate.ps1 diff --git a/.github/scripts/Create-PSQLUpdate.ps1 b/.github/scripts/Create-PSQLUpdate.ps1 new file mode 100644 index 000000000..0680ad336 --- /dev/null +++ b/.github/scripts/Create-PSQLUpdate.ps1 @@ -0,0 +1,74 @@ +function Get-OrgData { + param ( + # Org id to get data for + [Int32] + $OrganizationID, + # Github token + [String] + $Token + ) + # Get data from the REST api + $headers = @{ + "Accept" = "application/vnd.github.v3+json" + "Authorization" = "Bearer $token" + } + $orgData = Invoke-RestMethod -Uri "https://api.github.com/orgs/$OrganizationID" -Method Get -Headers $headers + return $orgData +} + +$data = Get-Content /home/runner/work/github-portal/github-portal/app_output.json -Raw | ConvertFrom-Json + +$insertData = @() + +foreach ($item in $data) { + $orgData = Get-OrgData -OrganizationID $item.account.id -Token $env:PAT + $insertData += [PSCustomObject]@{ + type = @("public", "private", "internal") + active = $true + description = $orgData.description + updated = get-date -format yyyy-MM-ddTHH:mm:ssZ + installations = @( + @{ + appId = $item.app_id + installationId = $item.id + } + ) + organizationid = $item.account.id + organizationname = $item.account.login + features = @("locked", "createReposDirect") + } +} + +$insertData + +# test if the file exists +if (Test-Path ./update.sql) { + # if it does, delete it + Remove-Item ./update.sql -Force +} + +# make new empty sql file +New-Item -Path ./update.sql -ItemType File -Force + +# add heredoc to to the file to start a sql transaction and remove the rows from the organizationsettings table +$deleteRows = @" +BEGIN; +DELETE FROM organizationsettings; +COMMIT; +"@ + +$deleteRows | Out-File -FilePath ./update.sql -Append + +"BEGIN;" | Out-File -FilePath ./update.sql -Append + +# loop through the data and add the insert statements to the sql file +foreach ($item in $insertData) { + $jsonBlob = $item | ConvertTo-Json -Compress + $insertStatement = @" + INSERT INTO public.organizationsettings + VALUES ('organizationsetting', $($item.organizationid), '$jsonBlob'); +"@ + $insertStatement | Out-File -FilePath ./update.sql -Append +} + +"COMMIT;" | Out-File -FilePath ./update.sql -Append From 443de5c7ae7c71e7295966000e08c242c7228780 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 09:55:40 -0500 Subject: [PATCH 115/209] Update update_orgsettings_table.yaml --- .github/workflows/update_orgsettings_table.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/update_orgsettings_table.yaml b/.github/workflows/update_orgsettings_table.yaml index 00365bc66..643f28ea3 100644 --- a/.github/workflows/update_orgsettings_table.yaml +++ b/.github/workflows/update_orgsettings_table.yaml @@ -16,10 +16,10 @@ jobs: - name: update ruby reqs run: | gem install jwt - + # ruby jwt script has hardcoded reference to GitHub app id - unique in each branch - name: run jwt generator run: | - ruby .github/scripts/jwt.rb >> token + ruby .github/scripts/jwt.rb >> token ls -lah env: PEM: ${{ secrets.APP_PEM}} @@ -32,7 +32,8 @@ jobs: -H "Authorization: Bearer $(cat token)" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/app/installations | jq >> app_output.json - + + # needs a PAT that can read org and enterprise data - name: run powershell script to build sql run: | .github/scripts/Create-PSQLUpdate.ps1 @@ -56,12 +57,12 @@ jobs: uses: azure/postgresql@v1 with: connection-string: ${{โ€ฏsecrets.PSQL_CONN }} - server-name: nih-portaldb.postgres.database.azure.com + server-name: REPLACE_WITH_DATABASE_NAME plsql-file: ./update.sql - name: Azure CLI Action uses: Azure/cli@v1 with: - # Specify the script here + # Needs the azure webapp name and resource group - unique in each branch inlineScript: az webapp restart --name REPLACENAME --resource-group REPLACE_RESOURCE_GROUP From 604b3388ed423bfa59d09f7efef7355df5f49aab Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:05:30 -0500 Subject: [PATCH 116/209] Rename update_orgsettings_table.yaml to staging_update_orgsettings_table.yaml --- ...gsettings_table.yaml => staging_update_orgsettings_table.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{update_orgsettings_table.yaml => staging_update_orgsettings_table.yaml} (100%) diff --git a/.github/workflows/update_orgsettings_table.yaml b/.github/workflows/staging_update_orgsettings_table.yaml similarity index 100% rename from .github/workflows/update_orgsettings_table.yaml rename to .github/workflows/staging_update_orgsettings_table.yaml From 149802cff706d7037360232d696c0e045f7291c6 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:32:24 -0500 Subject: [PATCH 117/209] Update staging_update_orgsettings_table.yaml --- .github/workflows/staging_update_orgsettings_table.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/staging_update_orgsettings_table.yaml b/.github/workflows/staging_update_orgsettings_table.yaml index 643f28ea3..402434295 100644 --- a/.github/workflows/staging_update_orgsettings_table.yaml +++ b/.github/workflows/staging_update_orgsettings_table.yaml @@ -22,7 +22,8 @@ jobs: ruby .github/scripts/jwt.rb >> token ls -lah env: - PEM: ${{ secrets.APP_PEM}} + PEM: ${{ secrets.DEV_APP_PEM}} + APPID: ${{ secrets.DEV_APP_ID }} - name: run gh cli to get app install info From 78db7a5791ce86475e9e3d4d66a9257cad604913 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:33:12 -0500 Subject: [PATCH 118/209] Update jwt.rb --- .github/scripts/jwt.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/jwt.rb b/.github/scripts/jwt.rb index faed28e1b..a9f5239b8 100644 --- a/.github/scripts/jwt.rb +++ b/.github/scripts/jwt.rb @@ -12,7 +12,7 @@ # JWT expiration time (10 minute maximum) exp: Time.now.to_i + (10 * 60), # GitHub App's identifier - iss: REPLACE_WITH_APP_ID + iss: ENV["APP_ID"] } jwt = JWT.encode(payload, private_key, "RS256") From 5b3320e2cef1be4385f7e68f4baa24007f7e3fc3 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:34:04 -0500 Subject: [PATCH 119/209] Update jwt.rb --- .github/scripts/jwt.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/jwt.rb b/.github/scripts/jwt.rb index a9f5239b8..69f97a47c 100644 --- a/.github/scripts/jwt.rb +++ b/.github/scripts/jwt.rb @@ -12,7 +12,7 @@ # JWT expiration time (10 minute maximum) exp: Time.now.to_i + (10 * 60), # GitHub App's identifier - iss: ENV["APP_ID"] + iss: ENV["APPID"] } jwt = JWT.encode(payload, private_key, "RS256") From b0466b6aa2cca2f338559c5f4a99b9c7a5f25893 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:39:53 -0500 Subject: [PATCH 120/209] Update staging_update_orgsettings_table.yaml --- .github/workflows/staging_update_orgsettings_table.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/staging_update_orgsettings_table.yaml b/.github/workflows/staging_update_orgsettings_table.yaml index 402434295..fc3188e93 100644 --- a/.github/workflows/staging_update_orgsettings_table.yaml +++ b/.github/workflows/staging_update_orgsettings_table.yaml @@ -52,7 +52,7 @@ jobs: - name: Azure Login uses: Azure/login@v1.4.6 with: - creds: '{"clientId":"${{ secrets.CLIENT_ID }}","clientSecret":"${{ secrets.CLIENT_SECRET }}","subscriptionId":"${{ secrets.SUBSCRIPTION_ID }}","tenantId":"${{ secrets.TENANT_ID }}"}' + creds: '{"clientId":"${{ secrets.AAD_CLIENT_ID }}","clientSecret":"${{ secrets.AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AAD_TENANT_ID }}"}' - name: PSQL update uses: azure/postgresql@v1 From 78894338f3992b1c84b06adb4eb10ba217c8675a Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 6 Jan 2023 17:13:09 -0500 Subject: [PATCH 121/209] Update staging_update_orgsettings_table.yaml --- .github/workflows/staging_update_orgsettings_table.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/staging_update_orgsettings_table.yaml b/.github/workflows/staging_update_orgsettings_table.yaml index fc3188e93..c30de7c7f 100644 --- a/.github/workflows/staging_update_orgsettings_table.yaml +++ b/.github/workflows/staging_update_orgsettings_table.yaml @@ -22,7 +22,7 @@ jobs: ruby .github/scripts/jwt.rb >> token ls -lah env: - PEM: ${{ secrets.DEV_APP_PEM}} + PEM: ${{ secrets.DEV_APP_PEM }} APPID: ${{ secrets.DEV_APP_ID }} @@ -57,13 +57,13 @@ jobs: - name: PSQL update uses: azure/postgresql@v1 with: - connection-string: ${{โ€ฏsecrets.PSQL_CONN }} - server-name: REPLACE_WITH_DATABASE_NAME + connection-string: ${{โ€ฏsecrets.DEV_PSQL_CONN }} + server-name: $${{ secrets.DEV_PSQL_SERVER }} plsql-file: ./update.sql - name: Azure CLI Action uses: Azure/cli@v1 with: # Needs the azure webapp name and resource group - unique in each branch - inlineScript: az webapp restart --name REPLACENAME --resource-group REPLACE_RESOURCE_GROUP + inlineScript: az webapp restart --name ${{ secrets.DEV_AAS }} --resource-group ${{ secrets.DEV_RG }} From 0068c4a5f6d16b9db300c1aeba94f7c61cdfa4d8 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:04:17 -0800 Subject: [PATCH 122/209] Fixed the footer attribution --- views/footer.pug | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/views/footer.pug b/views/footer.pug index 01f450ca7..b4c44ae9c 100644 --- a/views/footer.pug +++ b/views/footer.pug @@ -103,14 +103,14 @@ footer if config && config.brand && config.brand.supportMail ul.list-inline(style='margin-bottom: 0px') li: a(href='mailto:' + config.brand.supportMail) Contact site administrator - li: a(href='https://github.com/microsoft/opensource-portal', target='_new') Contribute to this site on GitHub + li: a(href='https://github.com/NIHGOV/github-portal', target='_new') Contribute to this site on GitHub if serverName && correlationId | Powered by  - a(href='/thanks') great open source,  + a(href='https://github.nih.gov/about/credits' target="_blank") great open source,  span(title=correlationId + ' ' + serverName) Microsoft Azure,  | and the GitHub API else - | Powered by great open source, Microsoft Azure, and the GitHub API + | Powered by great open source, Microsoft Azure, and the GitHub API .col-sm-6.col-md-6.col-lg-6 .pull-right.text-right a#microsoftFooterLogo(href=(config && config.brand ? config.brand.companyLink : 'about:blank'), title=(config && config.brand ? config.brand.companyName : '')) From 013ba45f80c99040781b030154f9932d25a49dc1 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 13 Jan 2023 14:57:54 -0500 Subject: [PATCH 123/209] Create main_update_orgsettings_table.yaml add a production environment action to update the orgsettings table --- .../main_update_orgsettings_table.yaml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 .github/workflows/main_update_orgsettings_table.yaml diff --git a/.github/workflows/main_update_orgsettings_table.yaml b/.github/workflows/main_update_orgsettings_table.yaml new file mode 100644 index 000000000..794ca7a61 --- /dev/null +++ b/.github/workflows/main_update_orgsettings_table.yaml @@ -0,0 +1,69 @@ +name: NIH GHMP (Prod) - Update Database Org Settings + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1.127.0 + with: + ruby-version: '3.0' # Not needed with a .ruby-version file + + - name: update ruby reqs + run: | + gem install jwt + # ruby jwt script has hardcoded reference to GitHub app id - unique in each branch + - name: run jwt generator + run: | + ruby .github/scripts/jwt.rb >> token + ls -lah + env: + PEM: ${{ secrets.PROD_APP_PEM }} + APPID: ${{ secrets.PROD_APP_ID }} + + + - name: run gh cli to get app install info + run: | + curl \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $(cat token)" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/app/installations | jq >> app_output.json + + # needs a PAT that can read org and enterprise data + - name: run powershell script to build sql + run: | + .github/scripts/Create-PSQLUpdate.ps1 + shell: pwsh + + env: + PAT: ${{ secrets.ENT_READ_PAT }} + + - name: output sql + run: | + ls -lah + cat ./app_output.json + cat ./update.sql + + - name: Azure Login + uses: Azure/login@v1.4.6 + with: + creds: '{"clientId":"${{ secrets.AAD_CLIENT_ID }}","clientSecret":"${{ secrets.AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AAD_TENANT_ID }}"}' + + - name: PSQL update + uses: azure/postgresql@v1 + with: + connection-string: ${{โ€ฏsecrets.PROD_PSQL_CONN }} + server-name: $${{ secrets.PROD_PSQL_SERVER }} + plsql-file: ./update.sql + + - name: Azure CLI Action + uses: Azure/cli@v1 + with: + # Needs the azure webapp name and resource group - unique in each branch + inlineScript: az webapp restart --name ${{ secrets.PROD_AAS }} --resource-group ${{ secrets.PROD_RG }} + From 45dfa59bd6a78bc0147f1d0d139d0ba035ff029e Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:44:58 -0500 Subject: [PATCH 124/209] Update main_update_orgsettings_table.yaml --- .github/workflows/main_update_orgsettings_table.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main_update_orgsettings_table.yaml b/.github/workflows/main_update_orgsettings_table.yaml index 794ca7a61..39ab84eb9 100644 --- a/.github/workflows/main_update_orgsettings_table.yaml +++ b/.github/workflows/main_update_orgsettings_table.yaml @@ -33,6 +33,7 @@ jobs: -H "Authorization: Bearer $(cat token)" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/app/installations | jq >> app_output.json + cat ./app_output.json # needs a PAT that can read org and enterprise data - name: run powershell script to build sql From 730cd5e51f11b48377f03e61e6c616a977d8aa5c Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:46:35 -0500 Subject: [PATCH 125/209] Update Create-PSQLUpdate.ps1 adding logging --- .github/scripts/Create-PSQLUpdate.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/scripts/Create-PSQLUpdate.ps1 b/.github/scripts/Create-PSQLUpdate.ps1 index 0680ad336..1c7763092 100644 --- a/.github/scripts/Create-PSQLUpdate.ps1 +++ b/.github/scripts/Create-PSQLUpdate.ps1 @@ -21,6 +21,7 @@ $data = Get-Content /home/runner/work/github-portal/github-portal/app_output.jso $insertData = @() foreach ($item in $data) { + Write-Output "Getting data for Org: $($item.account.id)" $orgData = Get-OrgData -OrganizationID $item.account.id -Token $env:PAT $insertData += [PSCustomObject]@{ type = @("public", "private", "internal") From 1388483970d089e237cc5772de65d5144bf987a8 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 13 Jan 2023 17:10:44 -0500 Subject: [PATCH 126/209] Update main_update_orgsettings_table.yaml --- .github/workflows/main_update_orgsettings_table.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_update_orgsettings_table.yaml b/.github/workflows/main_update_orgsettings_table.yaml index 39ab84eb9..0b678b298 100644 --- a/.github/workflows/main_update_orgsettings_table.yaml +++ b/.github/workflows/main_update_orgsettings_table.yaml @@ -32,7 +32,7 @@ jobs: -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $(cat token)" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/app/installations | jq >> app_output.json + https://api.github.com/app/installations?per_page=100 | jq >> app_output.json cat ./app_output.json # needs a PAT that can read org and enterprise data From ae71387ece54097a9e77ed7eece442c69aa32f8a Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 13 Jan 2023 17:34:55 -0500 Subject: [PATCH 127/209] Update Create-PSQLUpdate.ps1 fix description --- .github/scripts/Create-PSQLUpdate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/Create-PSQLUpdate.ps1 b/.github/scripts/Create-PSQLUpdate.ps1 index 1c7763092..0bb5c70bd 100644 --- a/.github/scripts/Create-PSQLUpdate.ps1 +++ b/.github/scripts/Create-PSQLUpdate.ps1 @@ -26,7 +26,7 @@ foreach ($item in $data) { $insertData += [PSCustomObject]@{ type = @("public", "private", "internal") active = $true - description = $orgData.description + portaldescription = $orgData.description updated = get-date -format yyyy-MM-ddTHH:mm:ssZ installations = @( @{ From be81124d2825bd8c00c92a7990104d818ecdbfda Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 13 Jan 2023 17:44:31 -0800 Subject: [PATCH 128/209] Switch Org list back to non-reserve sort now that we're in Dynamic Mode --- views/index.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/index.pug b/views/index.pug index 46708e173..2e68894a1 100644 --- a/views/index.pug +++ b/views/index.pug @@ -65,7 +65,7 @@ block content - var currentPriority = '' - var oom = overview && overview.organizations ? overview.organizations.in : [] - each o in oom.reverse() + each o in oom div.link-box a(href=o.name + onboardingPostfixUrl) h2: strong= o.name From 92979ed4450b30bcb3c1c8bd18249e2e6ea93f3d Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 27 Apr 2023 12:36:50 -0400 Subject: [PATCH 129/209] Updates showOrgJoinDetails middleware to improve unlinked admin handling. --- routes/org/join.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routes/org/join.ts b/routes/org/join.ts index 6e1857db3..b25888c05 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -66,15 +66,15 @@ async function showOrgJoinDetails(req: ReposAppRequest) { // linked and unlinked admins return slightly different data structures const login = member ? member.login : admin.login; - + const avatar_url = member ? member.avatar_url : admin.avatar_url; // fallback to corporateUsername if corporateMailAddress is not available const mailAddress = link ? link.corporateMailAddress || link.corporateUsername : undefined; - const primaryName = link ? link.corporateDisplayName || link.corporateUsername : member.login; + const primaryName = link ? link.corporateDisplayName || link.corporateUsername : login; acc.push({ login, mailAddress, - avatar_url: member.avatar_url, + avatar_url, primaryName }) From d4cfb4f1d2685e82575d44d415c5df4278d1007e Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 4 May 2023 09:06:00 -0400 Subject: [PATCH 130/209] Ensure the redis key is set before attempting to auth with it. --- middleware/initialize.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/middleware/initialize.ts b/middleware/initialize.ts index 784fd22da..685be2bda 100644 --- a/middleware/initialize.ts +++ b/middleware/initialize.ts @@ -592,7 +592,11 @@ async function connectRedis( debug(`connecting to ${purpose} Redis ${redisConfig.host || redisConfig.tls}`); const redisClient: RedisClientType = createClient(redisOptions); await redisClient.connect(); - await redisClient.auth({ password: config.redis.key }); + + if (config.redis.tls) { + await redisClient.auth({ password: config.redis.key }); + } + return redisClient; } From d22f4d751ed23645dc1b7b88819006c2a3745c96 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 4 May 2023 09:15:29 -0400 Subject: [PATCH 131/209] Fix typescript bug. --- business/operations/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/business/operations/index.ts b/business/operations/index.ts index 5f1a0a7c0..a60f82381 100644 --- a/business/operations/index.ts +++ b/business/operations/index.ts @@ -1237,7 +1237,7 @@ export class Operations } allowUsersToViewLockedOrgDetails() { - return this.config?.features?.features.allowUsersToViewLockedOrgDetails === true; + return this.config?.features?.allowUsersToViewLockedOrgDetails === true; } // Eventually link/unlink should move from context into operations here to centralize more than just the events From 33cbda12bf0ed35b3028ec8ff05f090b0780234f Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 4 May 2023 09:19:12 -0400 Subject: [PATCH 132/209] Ensure the redis key is set before attempting to auth with it. --- middleware/initialize.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleware/initialize.ts b/middleware/initialize.ts index 685be2bda..d31186de8 100644 --- a/middleware/initialize.ts +++ b/middleware/initialize.ts @@ -593,7 +593,7 @@ async function connectRedis( const redisClient: RedisClientType = createClient(redisOptions); await redisClient.connect(); - if (config.redis.tls) { + if (config.redis.key) { await redisClient.auth({ password: config.redis.key }); } From d2f047da0cacc3148aa92f16a24cb2b31e453b89 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 4 May 2023 09:32:27 -0400 Subject: [PATCH 133/209] NIH color palette. --- views/email/email.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/views/email/email.css b/views/email/email.css index a2139abf4..7f37ff49a 100644 --- a/views/email/email.css +++ b/views/email/email.css @@ -12,7 +12,7 @@ h1 { } h1.blue { - color: #20558a; + color: #0078d7;; } h2 { @@ -35,7 +35,7 @@ p { a, a:link { - color: #20558a; + color: #0078d7; } a:visited { @@ -78,7 +78,7 @@ table.notification-action { } table.notification-information { - background-color: #20558a; + background-color: #0078d7; color: white; border: 0; min-height: 64px; @@ -128,7 +128,7 @@ p.footer { p.footer a { text-decoration: none; - color: #20558a; + color: #0078d7; } th { From 082975c5ede34e3b52a684cb0135b01d536a00ee Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 4 May 2023 10:37:54 -0400 Subject: [PATCH 134/209] NIH css styles. --- .../resources/repos-css/oss.css | 17 +++++++++-------- views/email/email.css | 8 ++++---- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/default-assets-package/resources/repos-css/oss.css b/default-assets-package/resources/repos-css/oss.css index a8709984f..82354e29c 100644 --- a/default-assets-package/resources/repos-css/oss.css +++ b/default-assets-package/resources/repos-css/oss.css @@ -139,7 +139,7 @@ textarea#editor-body { margin-bottom: 24px; width: 100%; min-height: 480px; - font-family: Consolas, 'Courier New', Courier, monospace; + font-family: Consolas, Courier, 'Courier New'; } footer { @@ -202,6 +202,10 @@ code { color: lightgray; } +.invisible { + visibility: hidden; +} + .alert-gray { background-color: #eee; border-color: #ddd; @@ -356,7 +360,7 @@ div.link-box { .ms-blue-border-top { border-style: solid; border-top-color: #20558a; - border-width: 4px 0 0 0; + border-width: 4px 0 0; } .transparent-border { @@ -581,8 +585,7 @@ th.w-10 { /* Nav: second level (shown on .active) */ .wiki-sidebar .nav .nav { - display: none; - /* Hide by default, but at >768px, show it */ + display: none; /* Hide by default, but at >768px, show it */ padding-bottom: 10px; } @@ -641,14 +644,12 @@ th.w-10 { } .wiki-sidebar.affix { - position: fixed; - /* Undo the static from mobile first approach */ + position: fixed; /* Undo the static from mobile first approach */ top: 20px; } .wiki-sidebar.affix-bottom { - position: absolute; - /* Undo the static from mobile first approach */ + position: absolute; /* Undo the static from mobile first approach */ } .wiki-sidebar.affix-bottom .wiki-sidenav, diff --git a/views/email/email.css b/views/email/email.css index 7f37ff49a..a2139abf4 100644 --- a/views/email/email.css +++ b/views/email/email.css @@ -12,7 +12,7 @@ h1 { } h1.blue { - color: #0078d7;; + color: #20558a; } h2 { @@ -35,7 +35,7 @@ p { a, a:link { - color: #0078d7; + color: #20558a; } a:visited { @@ -78,7 +78,7 @@ table.notification-action { } table.notification-information { - background-color: #0078d7; + background-color: #20558a; color: white; border: 0; min-height: 64px; @@ -128,7 +128,7 @@ p.footer { p.footer a { text-decoration: none; - color: #0078d7; + color: #20558a; } th { From 0762da853f9bf4df530dc025362d8226eaea6aec Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 4 May 2023 15:07:59 -0400 Subject: [PATCH 135/209] Add webhooks docs. --- .cspell.json | 3 +++ docs/webhooks.md | 59 +++++++++++++++++++++++++++++++++++++++++++++ docs/workflow.json | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 docs/webhooks.md create mode 100644 docs/workflow.json diff --git a/.cspell.json b/.cspell.json index 16053182e..a6832f5b4 100644 --- a/.cspell.json +++ b/.cspell.json @@ -206,6 +206,7 @@ "dpkg", "dropup", "DSRE", + "eastus", "edgecase", "electionid", "eligibilityend", @@ -648,6 +649,8 @@ "resave", "resaved", "resaving", + "RESOURCEGROUP", + "RESOURCEGROUPNAME", "respos", "restapi", "revokedbycorporateid", diff --git a/docs/webhooks.md b/docs/webhooks.md new file mode 100644 index 000000000..5dbda6b83 --- /dev/null +++ b/docs/webhooks.md @@ -0,0 +1,59 @@ +# Publishing Webhooks + +This codebase contains logic to consume webhook payloads from various queues, however it does not contain the logic required to publish webhooks to a queue. These instructions document a cloud-native option for achieving this. These instructions were created from information found in [this issue](https://github.com/microsoft/opensource-management-portal/issues/454). + +## Leverage App Logic to process webhooks + +Azure Logic Apps is a cloud platform where you can create and run automated workflows with little to no code. This service allows us to quickly build scalable and performant services without having to maintain additional code. The following steps will walk you through how to create a Logic App that will process webhooks from GitHub. + +### Sequence Diagram + +```mermaid +sequenceDiagram + GitHub->>+App Logic: POST webhook + Note over App Logic: transform payload + App Logic->>+Azure Service Bus Queue: publish message +``` + +### Configuration steps + +1. `export RESOURCEGROUP=[name of your resource group]` +2. Create a service bus in Azure. + + `az servicebus namespace create --resource-group $RESOURCEGROUP --name portal-events --location eastus` + +3. Create the `events` queue in the service bus. + + `az servicebus queue create --resource-group $RESOURCEGROUP --namespace-name portal-events --name events` + +4. Create a shared access policies from the Azure Portal. + + 1. Navigate to the service bus namespace. + 2. Click `Shared access policies` on the sidebar. + 3. Click "Add" + 4. Policy name: `send-events` + 5. Permission `Send` + 6. Copy down the primary connection string to be set in Logic App. + 7. Navigate to the service bus namespace. + 8. Click `Shared access policies` on the sidebar. + 9. Click "Add" + 10. Policy name: `read-events` + 11. Permission `Listen` + 12. Copy down the primary connection string to be set in Logic App. + +5. Update parameters in [workflow.json](workflow.json). + + 1. Replace `00000000-0000-0000-0000-000000000000` with your subscription id. + 2. In the servicebus connectionId property also update the resource group. + +6. Create the workflow. + + `az logic workflow create --resource-group $RESOURCEGROUP --location eastus --name process_webhooks --definition "workflow.json"` + +### Environment variables + +Set the following environment variables for the firehose service. + +- Ensure `GITHUB_WEBHOOKS_PROVIDER` environment variable is set to `servicebus` +- Ensure `GITHUB_WEBHOOKS_SERVICEBUS_QUEUE` is set to `events` +- `GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING`= [connection string from step 5] diff --git a/docs/workflow.json b/docs/workflow.json new file mode 100644 index 000000000..d0c305f67 --- /dev/null +++ b/docs/workflow.json @@ -0,0 +1,60 @@ +{ + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "actions": { + "Send_message": { + "inputs": { + "body": { + "ContentData": "@{base64(triggerBody())}", + "ContentType": "application/json", + "Properties": { + "delivery": "@coalesce(triggerOutputs()['headers']['X-GitHub-Delivery'])", + "event": "@coalesce(triggerOutputs()['headers']['X-GitHub-Event'])", + "signature": "@coalesce(triggerOutputs()['headers']['X-Hub-Signature'])", + "signature256": "@coalesce(triggerOutputs()['headers']['X-Hub-Signature-256'])", + "started": "@utcNow()" + } + }, + "host": { + "connection": { + "name": "@parameters('$connections')['servicebus']['connectionId']" + } + }, + "method": "post", + "path": "/@{encodeURIComponent(encodeURIComponent('events'))}/messages", + "queries": { + "systemProperties": "Run Details" + } + }, + "runAfter": {}, + "type": "ApiConnection" + } + }, + "contentVersion": "1.0.0.0", + "outputs": {}, + "parameters": { + "$connections": { + "defaultValue": {}, + "type": "Object" + } + }, + "triggers": { + "manual": { + "inputs": {}, + "kind": "Http", + "type": "Request" + } + } + }, + "parameters": { + "$connections": { + "value": { + "servicebus": { + "connectionId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/[RESOURCEGROUPNAME]/providers/Microsoft.Web/connections/servicebus", + "connectionName": "servicebus", + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Web/locations/eastus/managedApis/servicebus" + } + } + } + } +} From 8e8715435a5d7d5a64c9ce2a2823f639144097bd Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 5 May 2023 07:57:10 -0400 Subject: [PATCH 136/209] Fix linter errors. --- lib/mailProvider/azureServiceBus.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mailProvider/azureServiceBus.ts b/lib/mailProvider/azureServiceBus.ts index 2821abb82..8ea4540e9 100644 --- a/lib/mailProvider/azureServiceBus.ts +++ b/lib/mailProvider/azureServiceBus.ts @@ -42,7 +42,7 @@ export default class AzureServiceBus implements IMailProvider { return mail; } - async initialize() { } + async initialize() {} async sendMail(mail: IMail): Promise { const { @@ -82,4 +82,4 @@ export default class AzureServiceBus implements IMailProvider { catch(err) { throw err; } -} \ No newline at end of file +} From 0c7d0d6715a21aada780396077ed08ca54298e76 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 5 May 2023 08:56:49 -0400 Subject: [PATCH 137/209] Whitelist spelling errors. --- .cspell.json | 11 +++++++++++ .github/scripts/Create-EnvOrgs.ps1 | 8 ++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.cspell.json b/.cspell.json index a6832f5b4..7ac26c390 100644 --- a/.cspell.json +++ b/.cspell.json @@ -98,7 +98,9 @@ "byidpriv", "byidvis", "byuser", + "CACF", "Caser", + "CBFFB", "CDOC", "CELA", "champscount", @@ -251,6 +253,7 @@ "existingrepoid", "existingreponame", "fakeaccesstoken", + "FEBDA", "feedscan", "fieldname", "fifteenpercent", @@ -280,6 +283,7 @@ "gheclogin", "ghid", "GHID", + "GHMP", "ghname", "ghowners", "GHPI", @@ -453,6 +457,8 @@ "newrepo", "newrepolockdown", "newrepolockremoved", + "nihgithubportal", + "nihdevgithubportal", "nodeapp", "nodenext", "noemail", @@ -572,6 +578,7 @@ "pkgs", "pkgtext", "Plex", + "plsql", "pmownerid", "popd", "portaldescription", @@ -595,6 +602,7 @@ "publicprivate", "publishedaction", "PUBLISHERNAME", + "PUBLISHPROFILE", "Puid", "pullmerges", "pullrequestreview", @@ -604,6 +612,7 @@ "pushedat", "pushprotection", "pvtv", + "pwsh", "pypi", "qcuser", "querycache", @@ -643,6 +652,7 @@ "repositoryprivate", "repositoryteamcache", "reposize", + "reqs", "requestedtime", "requestid", "requesttype", @@ -824,6 +834,7 @@ "waitlist", "watcherscount", "Wcag", + "webapps", "webcontext", "webhoooks", "welcomeemailsent", diff --git a/.github/scripts/Create-EnvOrgs.ps1 b/.github/scripts/Create-EnvOrgs.ps1 index c1fcfadb6..e49450404 100644 --- a/.github/scripts/Create-EnvOrgs.ps1 +++ b/.github/scripts/Create-EnvOrgs.ps1 @@ -3,7 +3,7 @@ $output = Get-Content ./raw.json | ConvertFrom-Json Write-Output $output.data.enterprise.organizations.nodes -$orgsArry = @() +$orgsArray = @() foreach ($org in $output.data.enterprise.organizations.nodes) { $envObj = [PSCustomObject]@{ @@ -14,8 +14,8 @@ foreach ($org in $output.data.enterprise.organizations.nodes) { locked = $True } - $orgsArry += $envObj - Write-Output $orgsArry + $orgsArray += $envObj + Write-Output $orgsArray } -$orgsArry | ConvertTo-Json -Depth 10 | Out-File -FilePath "orgs.json" +$orgsArray | ConvertTo-Json -Depth 10 | Out-File -FilePath "orgs.json" From d1b48b4f54e3fe7f374c36949c6cc72b37268880 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 5 May 2023 10:41:06 -0400 Subject: [PATCH 138/209] Don't rely on global installation of husky to build Docker. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18e2fdfc5..3c00712a9 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "lint:md": "markdownlint-cli2 \"**/*.md\"", "lint:spell": "cspell --no-progress \"**\"", "lint": "npm run lint:js && npm run lint:md && npm run lint:spell", - "prepare": "husky install", + "prepare": "npx husky install", "start-4000": "PORT=4000 DEBUG=startup node ./dist/bin/www", "start-in-container": "node ./bin/www", "start": "node ./dist/bin/www", From b39b8c10e32cbf3299c4a44cc1a04d26ba6e0253 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 5 May 2023 14:49:10 -0400 Subject: [PATCH 139/209] Include a list of orgs a user owns in the administrative user report. --- routes/administration/index.ts | 78 +++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/routes/administration/index.ts b/routes/administration/index.ts index 8cea95ada..0030447e2 100644 --- a/routes/administration/index.ts +++ b/routes/administration/index.ts @@ -49,31 +49,55 @@ router.get('/', (req: ReposAppRequest, res, next) => { }); }); -/* -Returns a CSV of every org and its members, with a column indicating whether the member is linked or not +/* +Asynchronously returns a CSV file with of each user, the organizations they belong to, and whether they are linked or not */ router.get('/users-report', async (req: ReposAppRequest, res, next) => { try { - const { operations: { organizations } } = getProviders(req); + // Use getProviders middleware to obtain operational data, which includes an array of organizations + const { + operations: { organizations }, + } = getProviders(req); const checks = []; const users = {}; - for (let [orgName, org] of organizations.entries()) { - checks.push(org.getUnlinkedAndLinkedMembers() - .then(memberPairs => { - - memberPairs.forEach(memberPair => { - const { member: { id: UserId, login: UserLogin }, link: memberLink } = memberPair; + // Loop through each organization in the array + for (const [orgName, org] of organizations.entries()) { + // Get an array of owner logins for the org, which we'll use later + const ownerLogins = (await org.getOwners()).map((owner) => owner.login); + + // Push a promise to the checks array, which will be resolved later with a result + checks.push( + // Calling this on an org returns an array of member pairs, each representing a GitHub user who is a member of the org + org.getUnlinkedAndLinkedMembers().then((memberPairs) => { + // Loop through each member pair in the array + memberPairs.forEach((memberPair) => { + // Extract the member object and the link object from the member pair object + const { + member: { id: UserId, login: UserLogin }, + link: memberLink, + } = memberPair; + + // Store whether the member is linked or not in a variable const isLinked = memberLink ? true : false; - let userObj = { UserLogin, UserId, Organizations: [], IsLinked: isLinked }; - + + // Create an object representing the user; we'll fill it in more later + let userObj = { + UserLogin, + UserId, + Organizations: [], + OwnedOrganizations: [], + IsLinked: isLinked, + }; + + // If the user is linked, add the fields from the memberLink object to the user object if (isLinked) { - const { - corporateId: CorporateId, - corporateMailAddress: CorporateMailAddress, - corporateUsername: CorporateUsername, - corporateAlias: CorporateAlias, - corporateDisplayName: CorporateDisplayName + const { + corporateId: CorporateId, + corporateMailAddress: CorporateMailAddress, + corporateUsername: CorporateUsername, + corporateAlias: CorporateAlias, + corporateDisplayName: CorporateDisplayName } = memberLink; userObj = { ...userObj, ...{ CorporateId, CorporateUsername, CorporateAlias, CorporateDisplayName, CorporateMailAddress } } @@ -81,18 +105,30 @@ router.get('/users-report', async (req: ReposAppRequest, res, next) => { users[UserLogin] = users[UserLogin] || userObj; users[UserLogin].Organizations.push(orgName); + + if (ownerLogins.includes(UserLogin)) { + users[UserLogin].OwnedOrganizations.push(orgName); + } }); })); }; - - await Promise.all(checks) - const header = 'UserLogin,UserId,Organizations,IsLinked,CorporateId,CorporateMailAddress,CorporateUsername,CorporateAlias,CorporateDisplayName'; + // Wait for all of the promises in the checks array to be resolved + await Promise.all(checks); + // Define the header row for the CSV + const header = + 'UserLogin,UserId,Organizations,OwnedOrganizations,IsLinked,CorporateId,CorporateMailAddress,CorporateUsername,CorporateAlias,CorporateDisplayName'; + + // Sort the users object by user login and convert the values back into an array const cleanedObjects: object[] = _.sortBy(Object.values(users), 'UserLogin'); + + // Use the json2csvAsync library to convert the cleaned array of user objects into a CSV payload const payload = await json2csvAsync(cleanedObjects, { keys: header.split(','), emptyFieldValue: '' }); - + + // Set up response headers to return a CSV file res.header('Content-Type', 'text/csv'); res.attachment('users-report.csv'); + // Send the payload as the response body res.send(payload); } catch (err) { next(err); From 0cd0b1d4d8d65d2f0f19c16153506191f904eb94 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 4 May 2023 09:06:00 -0400 Subject: [PATCH 140/209] Ensure the redis key is set before attempting to auth with it. --- middleware/initialize.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/middleware/initialize.ts b/middleware/initialize.ts index 784fd22da..d31186de8 100644 --- a/middleware/initialize.ts +++ b/middleware/initialize.ts @@ -592,7 +592,11 @@ async function connectRedis( debug(`connecting to ${purpose} Redis ${redisConfig.host || redisConfig.tls}`); const redisClient: RedisClientType = createClient(redisOptions); await redisClient.connect(); - await redisClient.auth({ password: config.redis.key }); + + if (config.redis.key) { + await redisClient.auth({ password: config.redis.key }); + } + return redisClient; } From a7bca65e813bdbf12b2de3307d1294a91a1551d2 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 11 May 2023 17:45:24 -0400 Subject: [PATCH 141/209] Updates the dependabot config. * Adds config for node dependencies in /default-assets-package * Prefixes dependabot commit messages with `npm:end:` or `actions:` * Increase indentation of the updates property in dependabot config. * Target the dependabot updates at the `staging` branch instead of main. --- .github/dependabot.yml | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7b7bf98b0..f026a2a80 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,12 +1,25 @@ version: 2 updates: -- package-ecosystem: npm - directory: "/" - schedule: - interval: weekly - open-pull-requests-limit: 10 -- package-ecosystem: github-actions - directory: "/" - schedule: - interval: weekly - open-pull-requests-limit: 10 + - package-ecosystem: npm + directory: / + target-branch: staging + schedule: + interval: daily + open-pull-requests-limit: 10 + commit-message: + prefix: "npm:back-end" + - package-ecosystem: npm + directory: /default-assets-package + target-branch: staging + schedule: + interval: daily + open-pull-requests-limit: 10 + commit-message: + prefix: "npm:front-end" + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 10 + commit-message: + prefix: "actions" From b2be58e68f3dffd58afb8d15edcdddfd5873d81d Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Wed, 24 May 2023 16:02:26 -0400 Subject: [PATCH 142/209] Update the Dockerfile. --- Dockerfile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6a7f8cd25..91a1715fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -64,18 +64,10 @@ COPY --from=build --chown=oss:oss /build/default-assets-package ./default-assets COPY --from=build --chown=oss:oss /build/config ./config COPY --from=build --chown=oss:oss /build/views ./views COPY --from=build --chown=oss:oss /build/package.json ./package.json -COPY --from=build --chown=oss:oss /build/jobs/reports/views ./jobs/reports/views #Do stuff for GitHub Environment Orgs COPY --from=build --chown=oss:oss /build/env-orgs.json ./env-orgs.json -# Reports are not actively working in the project, but keeping these files ready -COPY --from=build --chown=oss:oss /build/jobs/reports/exemptRepositories.json \ - /build/jobs/reports/organizationDefinitions.json \ - /build/jobs/reports/repositoryDefinitions.json \ - /build/jobs/reports/teamDefinitions.json \ - ./jobs/reports/ - # Host the app USER oss ENTRYPOINT ["npm", "run-script", "start-in-container"] \ No newline at end of file From 6be3ebaca537e2747db5a0f3a3a9ed62030cd727 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Wed, 24 May 2023 16:02:42 -0400 Subject: [PATCH 143/209] Add dockerfile entry to dependabot. --- .github/dependabot.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a3934b370..d88ad582e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,12 +1,31 @@ version: 2 updates: - package-ecosystem: npm - directory: '/' + directory: / + target-branch: staging + schedule: + interval: daily + open-pull-requests-limit: 10 + commit-message: + prefix: 'npm - back-end' + - package-ecosystem: npm + directory: /default-assets-package + target-branch: staging schedule: interval: daily open-pull-requests-limit: 10 + commit-message: + prefix: 'npm - front-end' - package-ecosystem: github-actions - directory: '/' + target-branch: staging + directory: / schedule: interval: weekly open-pull-requests-limit: 10 + commit-message: + prefix: 'actions' + - package-ecosystem: 'docker' + target-branch: staging + directory: '/' + schedule: + interval: 'weekly' From 99e8e4f20833ab40ddbf4aa96931e428e77abfed Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Thu, 25 May 2023 07:49:50 -0400 Subject: [PATCH 144/209] fix typescript error --- routes/org/join.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/routes/org/join.ts b/routes/org/join.ts index 8fd4923a7..ec1612520 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -10,8 +10,6 @@ import asyncHandler from 'express-async-handler'; const router: Router = Router(); import querystring from 'querystring'; -import { IAggregateUserSummary } from '../../user/aggregate'; - import { CreateError, getProviders } from '../../transitional'; import { IndividualContext } from '../../business/user'; import { sleep, storeOriginalUrlAsReferrer, wrapError } from '../../utils'; From 7a1633d0e14fc0ae2b4e20018bb8803f391f24ca Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 26 May 2023 11:44:36 -0400 Subject: [PATCH 145/209] GH-170 - Add NIH Devcontainer (#282) * GH-170 Add NIH devcontainer. * Add sql connection to sqltools * Run `npm i` in default-assets-package. * Set default variable for REDIS_TLS_HOST in nih/devcontainer. * Set REDIS_HOST env var. * Update devcontainer to use GH_ prefix vs GITHUB. * Add script to set Codespace secrets from env secrets. * Update gh-codespace-secret.sh * Set password for redis service * Bump connect-redis in package-lock.json * Ingore SESSION_COOKIE_DOMAIN in devcontainer. * Add instructions for the NIH devcontainer. * Add new lines. --- .cspell.json | 3 +- .devcontainer/nih/Dockerfile | 14 + .devcontainer/nih/README.md | 13 + .devcontainer/nih/devcontainer.json | 119 ++++++++ .devcontainer/nih/docker-compose.yml | 23 ++ .devcontainer/nih/gh-codespace-secret.sh | 50 ++++ .devcontainer/nih/setup.sh | 4 + middleware/initialize.ts | 5 +- middleware/session.ts | 9 +- package-lock.json | 337 +++++------------------ 10 files changed, 301 insertions(+), 276 deletions(-) create mode 100644 .devcontainer/nih/Dockerfile create mode 100644 .devcontainer/nih/README.md create mode 100644 .devcontainer/nih/devcontainer.json create mode 100644 .devcontainer/nih/docker-compose.yml create mode 100755 .devcontainer/nih/gh-codespace-secret.sh create mode 100755 .devcontainer/nih/setup.sh diff --git a/.cspell.json b/.cspell.json index 83c822f72..22e5b16fe 100644 --- a/.cspell.json +++ b/.cspell.json @@ -18,7 +18,8 @@ "**/demo/user.json", "**/*_html.ts", "**/*.ignore_data.ts", - "package*.json" + "package*.json", + ".devcontainer/nih/**" ], "enableGlobDot": true, "useGitignore": true, diff --git a/.devcontainer/nih/Dockerfile b/.devcontainer/nih/Dockerfile new file mode 100644 index 000000000..d59927b1f --- /dev/null +++ b/.devcontainer/nih/Dockerfile @@ -0,0 +1,14 @@ +# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster +ARG VARIANT=16-bullseye +FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-${VARIANT} + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment if you want to install an additional version of node using nvm +# ARG EXTRA_NODE_VERSION=10 +# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" + +# [Optional] Uncomment if you want to install more global node packages +# RUN su node -c "npm install -g " diff --git a/.devcontainer/nih/README.md b/.devcontainer/nih/README.md new file mode 100644 index 000000000..715ccaaec --- /dev/null +++ b/.devcontainer/nih/README.md @@ -0,0 +1,13 @@ +# NIH Devcontainer + +## Steps for running from GitHub Codespaces + +1. [Set Environment Secrets](#secrets) +1. Launch your Codespace using [these settings](https://github.com/codespaces/new?hide_repo_select=true&ref=GH-170-devcontainer&repo=348553095&skip_quickstart=true&machine=standardLinux32gb&devcontainer_path=.devcontainer%2Fnih%2Fdevcontainer.json&geo=UsEast). +1. Run the "Launch site 3000"configuration from the `Run and Debug` panel in VS Code. + +### Secrets + +Use Codespace secrets to inject sensitive configuration variables into GitHub Codespaces. This can either be done [manually](https://github.com/settings/codespaces), or with the [gh-codespace-secret.sh](gh-codespace-secret.sh) shell script which automatically loads/updates portal-specific variables that are set in the current environment. Note: before running `gh-codespace-secret.sh` you will need to have a `GITHUB_TOKEN` environment variable set with a PAT that has the `codespace:secrets` scope. + +If you create the secrets manually, be sure to make the secrets visible to the repsoitory from which you are launching the codespace (eg github.com/NIHGov/github-portal). diff --git a/.devcontainer/nih/devcontainer.json b/.devcontainer/nih/devcontainer.json new file mode 100644 index 000000000..cbdbce071 --- /dev/null +++ b/.devcontainer/nih/devcontainer.json @@ -0,0 +1,119 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/typescript-node +{ + "name": "NIH GitHub Portal", + "dockerComposeFile": "docker-compose.yml", + "service": "web", + "workspaceFolder": "/workspace", + "postCreateCommand": "./.devcontainer/nih/setup.sh", + // If you change any local env vars be sure to close ALL VSCODE windows + // before rebuilding so vars are updated in the container + "remoteEnv": { + "AAD_CLIENT_ID": "${localEnv:AAD_CLIENT_ID}", + "AAD_CLIENT_SECRET": "${localEnv:AAD_CLIENT_SECRET}", + "AAD_ISSUER": "${localEnv:AAD_ISSUER}", + "AAD_REDIRECT_URL": "${localEnv:AAD_REDIRECT_URL}", + "AAD_TENANT_ID": "${localEnv:AAD_TENANT_ID}", + "APPINSIGHTS_INSTRUMENTATION_CS": "${localEnv:APPINSIGHTS_INSTRUMENTATION_CS}", + "APPINSIGHTS_INSTRUMENTATION_KEY": "${localEnv:APPINSIGHTS_INSTRUMENTATION_KEY}", + "AUTHORIZED_CORPORATE_ADMINISTRATOR_USERNAMES": "${localEnv:AUTHORIZED_CORPORATE_ADMINISTRATOR_USERNAMES}", + "DEBUG": "${localEnv:DEBUG:*}", + "DEBUG_ALLOW_HTTP": "${localEnv:DEBUG_ALLOW_HTTP}", + "DEBUG_SHOW_FOOTER": "${localEnv:DEBUG_SHOW_FOOTER:1}", + "ENVIRONMENT_NAME": "${localEnv:ENVIRONMENT_NAME}", + "GITHUB_APP_ACTIONS_APP_ID": "${localEnv:GH_APP_ACTIONS_APP_ID}", + "GITHUB_APP_ACTIONS_KEY": "${localEnv:GH_APP_ACTIONS_KEY}", + "GITHUB_APP_ACTIONS_KEY_FILE": "${localEnv:GH_APP_ACTIONS_KEY_FILE}", + "GITHUB_APP_ACTIONS_SLUG": "${localEnv:GH_APP_ACTIONS_SLUG}", + "GITHUB_APP_DATA_APP_ID": "${localEnv:GH_APP_DATA_APP_ID}", + "GITHUB_APP_DATA_KEY": "${localEnv:GH_APP_DATA_KEY}", + "GITHUB_APP_DATA_KEY_FILE": "${localEnv:GH_APP_DATA_KEY_FILE}", + "GITHUB_APP_DATA_SLUG": "${localEnv:GH_APP_DATA_SLUG}", + "GITHUB_APP_JOBS_APP_ID": "${localEnv:GH_APP_JOBS_APP_ID}", + "GITHUB_APP_JOBS_KEY": "${localEnv:GH_APP_JOBS_KEY}", + "GITHUB_APP_JOBS_KEY_FILE": "${localEnv:GH_APP_JOBS_KEY_FILE}", + "GITHUB_APP_JOBS_SLUG": "${localEnv:GH_APP_JOBS_SLUG}", + "GITHUB_APP_ONBOARDING_APP_ID": "${localEnv:GH_APP_ONBOARDING_APP_ID}", + "GITHUB_APP_ONBOARDING_KEY": "${localEnv:GH_APP_ONBOARDING_KEY}", + "GITHUB_APP_ONBOARDING_KEY_FILE": "${localEnv:GH_APP_ONBOARDING_KEY_FILE}", + "GITHUB_APP_ONBOARDING_SLUG": "${localEnv:GH_APP_ONBOARDING_SLUG}", + "GITHUB_APP_OPERATIONS_APP_ID": "${localEnv:GH_APP_OPERATIONS_APP_ID}", + "GITHUB_APP_OPERATIONS_KEY": "${localEnv:GH_APP_OPERATIONS_KEY}", + "GITHUB_APP_OPERATIONS_KEY_FILE": "${localEnv:GH_APP_OPERATIONS_KEY_FILE}", + "GITHUB_APP_OPERATIONS_SLUG": "${localEnv:GH_APP_OPERATIONS_SLUG}", + "GITHUB_APP_SECURITY_APP_ID": "${localEnv:GH_APP_SECURITY_APP_ID}", + "GITHUB_APP_SECURITY_KEY": "${localEnv:GH_APP_SECURITY_KEY}", + "GITHUB_APP_SECURITY_KEY_FILE": "${localEnv:GH_APP_SECURITY_KEY_FILE}", + "GITHUB_APP_SECURITY_SLUG": "${localEnv:GH_APP_SECURITY_SLUG}", + "GITHUB_APP_UI_APP_ID": "${localEnv:GH_APP_UI_APP_ID}", + "GITHUB_APP_UI_KEY": "${localEnv:GH_APP_UI_KEY}", + "GITHUB_APP_UI_KEY_FILE": "${localEnv:GH_APP_UI_KEY_FILE}", + "GITHUB_APP_UI_OAUTH_CLIENT_ID": "${localEnv:GH_APP_UI_OAUTH_CLIENT_ID}", + "GITHUB_APP_UI_OAUTH_CLIENT_SECRET": "${localEnv:GH_APP_UI_OAUTH_CLIENT_SECRET}", + "GITHUB_APP_UI_SLUG": "${localEnv:GH_APP_UI_SLUG}", + "GITHUB_APP_UPDATES_APP_ID": "${localEnv:GH_APP_UPDATES_APP_ID}", + "GITHUB_APP_UPDATES_KEY": "${localEnv:GH_APP_UPDATES_KEY}", + "GITHUB_APP_UPDATES_KEY_FILE": "${localEnv:GH_APP_UPDATES_KEY_FILE}", + "GITHUB_APP_UPDATES_SLUG": "${localEnv:GH_APP_UPDATES_SLUG}", + "GITHUB_CALLBACK_URL": "${localEnv:GH_CALLBACK_URL}", + "GITHUB_CLIENT_ID": "${localEnv:GH_CLIENT_ID}", + "GITHUB_CLIENT_SECRET": "${localEnv:GH_CLIENT_SECRET}", + "GITHUB_ORGANIZATIONS_FILE": "${localEnv:GH_ORGANIZATIONS_FILE}", + "GITHUB_PRIMARY_ORGANIZATION_ID": "${localEnv:GH_PRIMARY_ORGANIZATION_ID}", + "GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING": "${localEnv:GH_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING}", + "GOOGLE_ANALYTICS_KEY": "${localEnv:GOOGLE_ANALYTICS_KEY}", + "MAIL_AZURESERVICEBUS_CONNECTIONSTRING": "${localEnv:MAIL_AZURESERVICEBUS_CONNECTIONSTRING}", + "MAIL_AZURESERVICEBUS_QUEUENAME": "${localEnv:MAIL_AZURESERVICEBUS_QUEUENAME}", + "MAIL_FROM": "${localEnv:MAIL_FROM}", + "PORTAL_ADMIN_EMAIL": "${localEnv:PORTAL_ADMIN_EMAIL}", + "REDIS_HOST": "${localEnv:REDIS_HOST:redis}", + "REDIS_TLS_HOST": "${localEnv:REDIS_TLS_HOST}", + "REDIS_PORT": "${localEnv:REDIS_PORT}", + "REDIS_KEY": "${localEnv:REDIS_KEY:redispw}", + "REPOS_LINKS_PROVIDER_NAME": "${localEnv:REPOS_LINKS_PROVIDER_NAME:postgres}", + "REPOS_POSTGRES_DATABASE": "${localEnv:REPOS_POSTGRES_DATABASE:postgres}", + "REPOS_POSTGRES_HOST": "${localEnv:REPOS_POSTGRES_HOST:localhost}", + "REPOS_POSTGRES_PASSWORD": "${localEnv:REPOS_POSTGRES_PASSWORD:postgres}", + "REPOS_POSTGRES_PORT": "${localEnv:REPOS_POSTGRES_PORT:5432}", + "REPOS_POSTGRES_SSL": "${localEnv:REPOS_POSTGRES_SSL:false}", + "REPOS_POSTGRES_USER": "${localEnv:REPOS_POSTGRES_USER:postgres}", + "SESSION_PROVIDER": "${localEnv:SESSION_PROVIDER:redis}", + "SESSION_COOKIE_DOMAIN": "${localEnv:SESSION_COOKIE_DOMAIN}", + "SITE_SERVICE_BANNER": "${localEnv:SITE_SERVICE_BANNER}", + "SITE_SERVICE_BANNER_DETAILS": "${localEnv:SITE_SERVICE_BANNER_DETAILS}", + "SITE_SERVICE_BANNER_LINK": "${localEnv:SITE_SERVICE_BANNER_LINK}", + "TEAM_JOIN_APPROVAL_TYPES": "${localEnv:TEAM_JOIN_APPROVAL_TYPES:mail}" + }, + + "customizations": { + "vscode": { + "settings": { + "sqltools.connections": [ + { + "name": "Postgres Database", + "driver": "PostgreSQL", + "previewLimit": 50, + "server": "localhost", + "port": 5432, + "database": "postgres", + "username": "postgres", + "password": "postgres" + } + ] + }, + "extensions": ["mtxr.sqltools", "mtxr.sqltools-driver-pg"] + } + }, + + "forwardPorts": [3000, 5432], + + //"remoteUser": "node" + "portsAttributes": { + "3000": { + "label": "NIH Portal" + }, + "5432": { + "label": "Postgres Database" + } + } +} diff --git a/.devcontainer/nih/docker-compose.yml b/.devcontainer/nih/docker-compose.yml new file mode 100644 index 000000000..4ea92d928 --- /dev/null +++ b/.devcontainer/nih/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3.9' +services: + web: + build: . + volumes: + - ../..:/workspace:cached + command: sleep infinity + network_mode: service:db + redis: + image: 'redis:alpine' + command: redis-server --requirepass redispw + db: + image: 'postgres:alpine' + restart: unless-stopped + volumes: + - ../../pg.sql:/docker-entrypoint-initdb.d/pg.sql + - postgres-data:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + POSTGRES_DB: postgres +volumes: + postgres-data: diff --git a/.devcontainer/nih/gh-codespace-secret.sh b/.devcontainer/nih/gh-codespace-secret.sh new file mode 100755 index 000000000..deebd352b --- /dev/null +++ b/.devcontainer/nih/gh-codespace-secret.sh @@ -0,0 +1,50 @@ +#!/bin/bash +set -e +WRITE=0 +REPOSITORIES=${REPOS:-"nihgov/github-portal"} + +if [[ -z "$GITHUB_TOKEN" ]]; then + printf "GITHUB_TOKEN with scope 'codespace:secrets' must be set to create secrets." 1>&2 + exit 1 +fi + +# Fail safe requiring explicit permission to write secrets with the --write flag +if [[ $1 == "--write" ]]; then + WRITE=1 +else + printf "Running in dry-run mode. Pass --write flag to create secrets.\n\n" +fi + +# Filter to remove variables that have default values in the devcontainer.json +# to reduce unneeded secrets from being created. +FILTER="KEY_FILE\|REPOS_*\|^DEBUG|SESSION_COOKIE_DOMAIN" + +# Get list of application environment variables from the devcontainer.json file +ENV_VARS=($(cat devcontainer.json | sed 's/^ *\/\/.*//' | jq -r ".remoteEnv | keys[]" | grep -v $FILTER)) + +FLAG="--no-store" + +# Remove no store flag if not in dry-run +if [ "$WRITE" -eq "1" ]; then + FLAG="" +fi + +# Loop through each variable and create a secret if the variable is set +for VAR in "${ENV_VARS[@]}" +do + # Check if the variable is set + if [[ -n "${!VAR}" ]]; then + + # Replace GITHUB_ with GH_ since GitHub secrets cannot start with GITHUB + CLEANED_VAR="${VAR/GITHUB_/GH_}" + + # If in dry-run mode print the encrypted, base64-encoded value instead of + # storing it on Github with the --no-store flag + if [ "$WRITE" -eq "0" ]; then + printf "\033[0;32m$CLEANED_VAR: \033[0m" + fi + + # Create the secret or print the encrpyted secret + gh secret set -a codespaces $FLAG -u $CLEANED_VAR -b"${!VAR}" -r $REPOSITORIES + fi +done diff --git a/.devcontainer/nih/setup.sh b/.devcontainer/nih/setup.sh new file mode 100755 index 000000000..2fd000480 --- /dev/null +++ b/.devcontainer/nih/setup.sh @@ -0,0 +1,4 @@ +git config --global --add safe.directory /workspace +npm i +cd default-assets-package +npm i diff --git a/middleware/initialize.ts b/middleware/initialize.ts index 63f8c5340..49801b92c 100644 --- a/middleware/initialize.ts +++ b/middleware/initialize.ts @@ -596,10 +596,7 @@ async function connectRedis( debug(`connecting to ${purpose} Redis ${redisConfig.host || redisConfig.tls}`); const redisClient: RedisClientType = createClient(redisOptions); await redisClient.connect(); - - if (config.redis.key) { - await redisClient.auth({ password: config.redis.key }); - } + await redisClient.auth({ password: config.redis.key }); return redisClient; } diff --git a/middleware/session.ts b/middleware/session.ts index 9699ae1cb..092378525 100644 --- a/middleware/session.ts +++ b/middleware/session.ts @@ -47,11 +47,10 @@ export default async function ConnectSession( const redisPrefix = config.session.redis.prefix ? `${config.session.redis.prefix}.session` : 'session'; const redisLegacy = sessionRedisClient.duplicate(); redisLegacy.connect(); - await new Promise((resolve, reject) => { - (redisLegacy.auth as any)(config.redis.key, (authError: Error) => { - authError ? reject(authError) : resolve(); - }); - }); + + // NIH - Replaced this as redis auth does not work with upstream + // auth logic here. + await redisLegacy.auth({ password: config.session.redis.key }); const redisOptions = { client: redisLegacy, ttl: config.session.redis.ttl, diff --git a/package-lock.json b/package-lock.json index 465e94d7f..617963919 100644 --- a/package-lock.json +++ b/package-lock.json @@ -116,33 +116,6 @@ "node": ">=16" } }, - "default-assets-package": { - "name": "@ospo/site-assets", - "version": "1.1.0", - "extraneous": true, - "license": "UNLICENSED", - "dependencies": { - "blockui": "^1.0.0", - "components-font-awesome": "^4.2.0", - "typeahead": "^0.2.2", - "typeahead.js": "^0.11.1" - }, - "devDependencies": { - "bootstrap": "3.4.1", - "bootswatch": "3.4.1", - "c3": "0.4.14", - "grunt": "1.5.3", - "grunt-contrib-clean": "2.0.0", - "grunt-contrib-concat": "^1.0.1", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-less": "^2.0.0", - "grunt-exec": "3.0.0", - "jquery": "^3.4.0", - "load-grunt-tasks": "^4.0.0", - "octicons": "4.4.0", - "timeago": "1.6.4" - } - }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "dev": true, @@ -390,8 +363,7 @@ }, "node_modules/@azure/identity": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.2.2.tgz", - "integrity": "sha512-1xspoCfluAQUZmmWdPUNuiweIjE/ckZtR4gcnDbB2NMr36fk9MwXWaVJ7m1NKhOSz2RgMMLVUvZ2AISGcaAOTA==", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -1622,9 +1594,8 @@ }, "node_modules/@eslint/js": { "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", - "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2143,8 +2114,7 @@ }, "node_modules/@octokit/auth-app": { "version": "4.0.13", - "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.13.tgz", - "integrity": "sha512-NBQkmR/Zsc+8fWcVIFrwDgNXS7f4XDrkd9LHdi9DPQw1NdGHLviLzRO2ZBwTtepnwHXW5VTrVU9eFGijMUqllg==", + "license": "MIT", "dependencies": { "@octokit/auth-oauth-app": "^5.0.0", "@octokit/auth-oauth-user": "^2.0.0", @@ -2162,8 +2132,7 @@ }, "node_modules/@octokit/auth-app/node_modules/lru-cache": { "version": "9.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", - "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", + "license": "ISC", "engines": { "node": "14 || >=16.14" } @@ -2224,8 +2193,7 @@ }, "node_modules/@octokit/core": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz", - "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==", + "license": "MIT", "dependencies": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", @@ -2286,8 +2254,7 @@ }, "node_modules/@octokit/openapi-types": { "version": "17.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-17.2.0.tgz", - "integrity": "sha512-MazrFNx4plbLsGl+LFesMo96eIXkFgEtaKbnNpdh4aQ0VM10aoylFsTYP1AEjkeoRNZiiPe3T6Gl2Hr8dJWdlQ==" + "license": "MIT" }, "node_modules/@octokit/plugin-paginate-graphql": { "version": "2.0.1", @@ -2298,8 +2265,7 @@ }, "node_modules/@octokit/plugin-paginate-rest": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", - "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", + "license": "MIT", "dependencies": { "@octokit/tsconfig": "^1.0.2", "@octokit/types": "^9.2.3" @@ -2320,8 +2286,7 @@ }, "node_modules/@octokit/plugin-rest-endpoint-methods": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.2.tgz", - "integrity": "sha512-R0oJ7j6f/AdqPLtB9qRXLO+wjI9pctUn8Ka8UGfGaFCcCv3Otx14CshQ89K4E88pmyYZS8p0rNTiprML/81jig==", + "license": "MIT", "dependencies": { "@octokit/types": "^9.2.3", "deprecation": "^2.3.1" @@ -2335,8 +2300,7 @@ }, "node_modules/@octokit/request": { "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.5.tgz", - "integrity": "sha512-z83E8UIlPNaJUsXpjD8E0V5o/5f+vJJNbNcBwVZsX3/vC650U41cOkTLjq4PKk9BYonQGOnx7N17gvLyNjgGcQ==", + "license": "MIT", "dependencies": { "@octokit/endpoint": "^7.0.0", "@octokit/request-error": "^3.0.0", @@ -2363,8 +2327,7 @@ }, "node_modules/@octokit/rest": { "version": "19.0.11", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz", - "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==", + "license": "MIT", "dependencies": { "@octokit/core": "^4.2.1", "@octokit/plugin-paginate-rest": "^6.1.2", @@ -2377,13 +2340,11 @@ }, "node_modules/@octokit/tsconfig": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", - "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" + "license": "MIT" }, "node_modules/@octokit/types": { "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.3.tgz", - "integrity": "sha512-MMeLdHyFIALioycq+LFcA71v0S2xpQUX2cw6pPbHQjaibcHYwLnmK/kMZaWuGfGfjBJZ3wRUq+dOaWsvrPJVvA==", + "license": "MIT", "dependencies": { "@octokit/openapi-types": "^17.2.0" } @@ -2555,9 +2516,8 @@ }, "node_modules/@ts-morph/common": { "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.12.3.tgz", - "integrity": "sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==", "dev": true, + "license": "MIT", "dependencies": { "fast-glob": "^3.2.7", "minimatch": "^3.0.4", @@ -2724,9 +2684,8 @@ }, "node_modules/@types/json-schema": { "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/jsonwebtoken": { "version": "9.0.2", @@ -2769,8 +2728,7 @@ }, "node_modules/@types/node": { "version": "20.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz", - "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==" + "license": "MIT" }, "node_modules/@types/node-fetch": { "version": "2.6.1", @@ -2815,9 +2773,8 @@ }, "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 + "dev": true, + "license": "MIT" }, "node_modules/@types/passport": { "version": "1.0.12", @@ -2858,9 +2815,8 @@ }, "node_modules/@types/pg": { "version": "8.10.1", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.1.tgz", - "integrity": "sha512-AmEHA/XxMxemQom5iDwP62FYNkv+gDDnetRG7v2N2dPtju7UKI7FknUimcZo7SodKTHtckYPzaTqUEvUKbVJEA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "pg-protocol": "*", @@ -2869,9 +2825,8 @@ }, "node_modules/@types/pg/node_modules/pg-types": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", - "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", "dev": true, + "license": "MIT", "dependencies": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", @@ -2887,18 +2842,16 @@ }, "node_modules/@types/pg/node_modules/postgres-array": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", - "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/@types/pg/node_modules/postgres-bytea": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", - "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", "dev": true, + "license": "MIT", "dependencies": { "obuf": "~1.1.2" }, @@ -2908,18 +2861,16 @@ }, "node_modules/@types/pg/node_modules/postgres-date": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", - "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/@types/pg/node_modules/postgres-interval": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", - "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" } @@ -2952,9 +2903,8 @@ }, "node_modules/@types/semver": { "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/send": { "version": "0.17.1", @@ -2991,9 +2941,8 @@ }, "node_modules/@types/validator": { "version": "13.7.17", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.17.tgz", - "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { "version": "17.0.24", @@ -3010,9 +2959,8 @@ }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz", - "integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.59.7", @@ -3044,9 +2992,8 @@ }, "node_modules/@typescript-eslint/parser": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz", - "integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "5.59.7", "@typescript-eslint/types": "5.59.7", @@ -3071,9 +3018,8 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.59.7", "@typescript-eslint/visitor-keys": "5.59.7" @@ -3088,9 +3034,8 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", - "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "5.59.7", "@typescript-eslint/utils": "5.59.7", @@ -3115,9 +3060,8 @@ }, "node_modules/@typescript-eslint/types": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -3128,9 +3072,8 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", - "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "5.59.7", "@typescript-eslint/visitor-keys": "5.59.7", @@ -3155,9 +3098,8 @@ }, "node_modules/@typescript-eslint/utils": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", - "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", @@ -3181,9 +3123,8 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.59.7", "eslint-visitor-keys": "^3.3.0" @@ -3387,9 +3328,8 @@ }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4044,9 +3984,8 @@ }, "node_modules/code-block-writer": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", - "integrity": "sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/collect-v8-coverage": { "version": "1.0.1", @@ -4718,9 +4657,8 @@ }, "node_modules/eslint": { "version": "8.41.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", - "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", @@ -4785,9 +4723,8 @@ }, "node_modules/eslint-plugin-es-x": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-6.2.1.tgz", - "integrity": "sha512-uR34zUhZ9EBoiSD2DdV5kHLpydVEvwWqjteUr9sXRgJknwbKZJZhdJ7uFnaTtd+Nr/2G3ceJHnHXrFhJ67n3Tw==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.5.0" @@ -4804,9 +4741,8 @@ }, "node_modules/eslint-plugin-n": { "version": "16.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.0.0.tgz", - "integrity": "sha512-akkZTE3hsHBrq6CwmGuYCzQREbVUrA855kzcHqe6i0FLBkeY7Y/6tThCVkjUnjhvRBAlc+8lILcSe5QvvDpeZQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", @@ -4849,9 +4785,8 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -4975,9 +4910,8 @@ }, "node_modules/estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -5625,9 +5559,8 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -5664,9 +5597,8 @@ }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has": { "version": "1.0.3", @@ -7836,8 +7768,7 @@ }, "node_modules/nodemailer": { "version": "6.9.2", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.2.tgz", - "integrity": "sha512-4+TYaa/e1nIxQfyw/WzNPYTEZ5OvHIDEnmjs4LPmIfccPQN+2CYKmGHjWixn/chzD3bmUTu5FMfpltizMxqzdg==", + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -7888,9 +7819,8 @@ }, "node_modules/obuf": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/octicons": { "version": "5.0.1", @@ -8151,9 +8081,8 @@ }, "node_modules/path-browserify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", @@ -8199,8 +8128,7 @@ }, "node_modules/pg": { "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.0.tgz", - "integrity": "sha512-meLUVPn2TWgJyLmy7el3fQQVwft4gU5NGyvV0XbD41iU9Jbg8lCH4zexhIkihDzVHJStlt6r088G6/fWeNjhXA==", + "license": "MIT", "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", @@ -8227,14 +8155,12 @@ }, "node_modules/pg-cloudflare": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.0.tgz", - "integrity": "sha512-tGM8/s6frwuAIyRcJ6nWcIvd3+3NmUKIs6OjviIm1HPPFEt5MzQDOTBQyhPWg/m0kCl95M6gA1JaIXtS8KovOA==", + "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.0.tgz", - "integrity": "sha512-x14ibktcwlHKoHxx9X3uTVW9zIGR41ZB6QNhHb21OPNdCCO3NaRnpJuwKIQSR4u+Yqjx4HCvy7Hh7VSy1U4dGg==" + "license": "MIT" }, "node_modules/pg-escape": { "version": "0.2.0", @@ -8249,9 +8175,8 @@ }, "node_modules/pg-numeric": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", - "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", "dev": true, + "license": "ISC", "engines": { "node": ">=4" } @@ -8415,9 +8340,8 @@ }, "node_modules/postgres-range": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", - "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -8939,8 +8863,7 @@ }, "node_modules/semver": { "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -9378,9 +9301,8 @@ }, "node_modules/true-myth": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/true-myth/-/true-myth-4.1.1.tgz", - "integrity": "sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg==", "dev": true, + "license": "MIT", "engines": { "node": "10.* || >= 12.*" } @@ -9429,9 +9351,8 @@ }, "node_modules/ts-morph": { "version": "13.0.3", - "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-13.0.3.tgz", - "integrity": "sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw==", "dev": true, + "license": "MIT", "dependencies": { "@ts-morph/common": "~0.12.3", "code-block-writer": "^11.0.0" @@ -9481,9 +9402,8 @@ }, "node_modules/ts-prune": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/ts-prune/-/ts-prune-0.10.3.tgz", - "integrity": "sha512-iS47YTbdIcvN8Nh/1BFyziyUqmjXz7GVzWu02RaZXqb+e/3Qe1B7IQ4860krOeCGUeJmterAlaM2FRH0Ue0hjw==", "dev": true, + "license": "MIT", "dependencies": { "commander": "^6.2.1", "cosmiconfig": "^7.0.1", @@ -9498,18 +9418,16 @@ }, "node_modules/ts-prune/node_modules/commander": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/ts-prune/node_modules/cosmiconfig": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -9523,9 +9441,8 @@ }, "node_modules/ts-prune/node_modules/yaml": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, + "license": "ISC", "engines": { "node": ">= 6" } @@ -10161,8 +10078,6 @@ }, "@azure/identity": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.2.2.tgz", - "integrity": "sha512-1xspoCfluAQUZmmWdPUNuiweIjE/ckZtR4gcnDbB2NMr36fk9MwXWaVJ7m1NKhOSz2RgMMLVUvZ2AISGcaAOTA==", "requires": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -11042,8 +10957,6 @@ }, "@eslint/js": { "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", - "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", "dev": true }, "@hapi/boom": { @@ -11417,8 +11330,6 @@ }, "@octokit/auth-app": { "version": "4.0.13", - "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.13.tgz", - "integrity": "sha512-NBQkmR/Zsc+8fWcVIFrwDgNXS7f4XDrkd9LHdi9DPQw1NdGHLviLzRO2ZBwTtepnwHXW5VTrVU9eFGijMUqllg==", "requires": { "@octokit/auth-oauth-app": "^5.0.0", "@octokit/auth-oauth-user": "^2.0.0", @@ -11432,9 +11343,7 @@ }, "dependencies": { "lru-cache": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", - "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==" + "version": "9.1.1" } } }, @@ -11478,8 +11387,6 @@ }, "@octokit/core": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz", - "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==", "requires": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", @@ -11520,9 +11427,7 @@ } }, "@octokit/openapi-types": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-17.2.0.tgz", - "integrity": "sha512-MazrFNx4plbLsGl+LFesMo96eIXkFgEtaKbnNpdh4aQ0VM10aoylFsTYP1AEjkeoRNZiiPe3T6Gl2Hr8dJWdlQ==" + "version": "17.2.0" }, "@octokit/plugin-paginate-graphql": { "version": "2.0.1", @@ -11530,8 +11435,6 @@ }, "@octokit/plugin-paginate-rest": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", - "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", "requires": { "@octokit/tsconfig": "^1.0.2", "@octokit/types": "^9.2.3" @@ -11543,8 +11446,6 @@ }, "@octokit/plugin-rest-endpoint-methods": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.2.tgz", - "integrity": "sha512-R0oJ7j6f/AdqPLtB9qRXLO+wjI9pctUn8Ka8UGfGaFCcCv3Otx14CshQ89K4E88pmyYZS8p0rNTiprML/81jig==", "requires": { "@octokit/types": "^9.2.3", "deprecation": "^2.3.1" @@ -11552,8 +11453,6 @@ }, "@octokit/request": { "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.5.tgz", - "integrity": "sha512-z83E8UIlPNaJUsXpjD8E0V5o/5f+vJJNbNcBwVZsX3/vC650U41cOkTLjq4PKk9BYonQGOnx7N17gvLyNjgGcQ==", "requires": { "@octokit/endpoint": "^7.0.0", "@octokit/request-error": "^3.0.0", @@ -11573,8 +11472,6 @@ }, "@octokit/rest": { "version": "19.0.11", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz", - "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==", "requires": { "@octokit/core": "^4.2.1", "@octokit/plugin-paginate-rest": "^6.1.2", @@ -11583,14 +11480,10 @@ } }, "@octokit/tsconfig": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", - "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" + "version": "1.0.2" }, "@octokit/types": { "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.3.tgz", - "integrity": "sha512-MMeLdHyFIALioycq+LFcA71v0S2xpQUX2cw6pPbHQjaibcHYwLnmK/kMZaWuGfGfjBJZ3wRUq+dOaWsvrPJVvA==", "requires": { "@octokit/openapi-types": "^17.2.0" } @@ -11698,8 +11591,6 @@ }, "@ts-morph/common": { "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.12.3.tgz", - "integrity": "sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==", "dev": true, "requires": { "fast-glob": "^3.2.7", @@ -11846,8 +11737,6 @@ }, "@types/json-schema": { "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/jsonwebtoken": { @@ -11883,9 +11772,7 @@ "dev": true }, "@types/node": { - "version": "20.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz", - "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==" + "version": "20.2.3" }, "@types/node-fetch": { "version": "2.6.1", @@ -11924,8 +11811,6 @@ }, "@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/passport": { @@ -11963,8 +11848,6 @@ }, "@types/pg": { "version": "8.10.1", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.1.tgz", - "integrity": "sha512-AmEHA/XxMxemQom5iDwP62FYNkv+gDDnetRG7v2N2dPtju7UKI7FknUimcZo7SodKTHtckYPzaTqUEvUKbVJEA==", "dev": true, "requires": { "@types/node": "*", @@ -11974,8 +11857,6 @@ "dependencies": { "pg-types": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", - "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", "dev": true, "requires": { "pg-int8": "1.0.1", @@ -11989,14 +11870,10 @@ }, "postgres-array": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", - "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", "dev": true }, "postgres-bytea": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", - "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", "dev": true, "requires": { "obuf": "~1.1.2" @@ -12004,14 +11881,10 @@ }, "postgres-date": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", - "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", "dev": true }, "postgres-interval": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", - "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", "dev": true } } @@ -12039,8 +11912,6 @@ }, "@types/semver": { "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, "@types/send": { @@ -12073,8 +11944,6 @@ }, "@types/validator": { "version": "13.7.17", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.17.tgz", - "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==", "dev": true }, "@types/yargs": { @@ -12090,8 +11959,6 @@ }, "@typescript-eslint/eslint-plugin": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz", - "integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", @@ -12108,8 +11975,6 @@ }, "@typescript-eslint/parser": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz", - "integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==", "dev": true, "requires": { "@typescript-eslint/scope-manager": "5.59.7", @@ -12120,8 +11985,6 @@ }, "@typescript-eslint/scope-manager": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", "dev": true, "requires": { "@typescript-eslint/types": "5.59.7", @@ -12130,8 +11993,6 @@ }, "@typescript-eslint/type-utils": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", - "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", "dev": true, "requires": { "@typescript-eslint/typescript-estree": "5.59.7", @@ -12142,14 +12003,10 @@ }, "@typescript-eslint/types": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", "dev": true }, "@typescript-eslint/typescript-estree": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", - "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", "dev": true, "requires": { "@typescript-eslint/types": "5.59.7", @@ -12163,8 +12020,6 @@ }, "@typescript-eslint/utils": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", - "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", @@ -12179,8 +12034,6 @@ }, "@typescript-eslint/visitor-keys": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", "dev": true, "requires": { "@typescript-eslint/types": "5.59.7", @@ -12300,8 +12153,6 @@ }, "array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "asap": { @@ -12689,8 +12540,6 @@ }, "code-block-writer": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", - "integrity": "sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==", "dev": true }, "collect-v8-coverage": { @@ -13121,8 +12970,6 @@ }, "eslint": { "version": "8.41.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", - "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", @@ -13196,8 +13043,6 @@ }, "eslint-plugin-es-x": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-6.2.1.tgz", - "integrity": "sha512-uR34zUhZ9EBoiSD2DdV5kHLpydVEvwWqjteUr9sXRgJknwbKZJZhdJ7uFnaTtd+Nr/2G3ceJHnHXrFhJ67n3Tw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.1.2", @@ -13206,8 +13051,6 @@ }, "eslint-plugin-n": { "version": "16.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.0.0.tgz", - "integrity": "sha512-akkZTE3hsHBrq6CwmGuYCzQREbVUrA855kzcHqe6i0FLBkeY7Y/6tThCVkjUnjhvRBAlc+8lILcSe5QvvDpeZQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", @@ -13229,8 +13072,6 @@ }, "eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -13282,8 +13123,6 @@ }, "estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { @@ -13689,8 +13528,6 @@ }, "globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -13716,8 +13553,6 @@ }, "graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "has": { @@ -15086,9 +14921,7 @@ "dev": true }, "nodemailer": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.2.tgz", - "integrity": "sha512-4+TYaa/e1nIxQfyw/WzNPYTEZ5OvHIDEnmjs4LPmIfccPQN+2CYKmGHjWixn/chzD3bmUTu5FMfpltizMxqzdg==" + "version": "6.9.2" }, "normalize-path": { "version": "3.0.0", @@ -15115,8 +14948,6 @@ }, "obuf": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, "octicons": { @@ -15280,8 +15111,6 @@ }, "path-browserify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "dev": true }, "path-exists": { @@ -15310,8 +15139,6 @@ }, "pg": { "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.0.tgz", - "integrity": "sha512-meLUVPn2TWgJyLmy7el3fQQVwft4gU5NGyvV0XbD41iU9Jbg8lCH4zexhIkihDzVHJStlt6r088G6/fWeNjhXA==", "requires": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", @@ -15325,14 +15152,10 @@ }, "pg-cloudflare": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.0.tgz", - "integrity": "sha512-tGM8/s6frwuAIyRcJ6nWcIvd3+3NmUKIs6OjviIm1HPPFEt5MzQDOTBQyhPWg/m0kCl95M6gA1JaIXtS8KovOA==", "optional": true }, "pg-connection-string": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.0.tgz", - "integrity": "sha512-x14ibktcwlHKoHxx9X3uTVW9zIGR41ZB6QNhHb21OPNdCCO3NaRnpJuwKIQSR4u+Yqjx4HCvy7Hh7VSy1U4dGg==" + "version": "2.6.0" }, "pg-escape": { "version": "0.2.0" @@ -15342,8 +15165,6 @@ }, "pg-numeric": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", - "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", "dev": true }, "pg-pool": { @@ -15440,8 +15261,6 @@ }, "postgres-range": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", - "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", "dev": true }, "prelude-ls": { @@ -15774,8 +15593,6 @@ }, "semver": { "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "requires": { "lru-cache": "^6.0.0" } @@ -16057,8 +15874,6 @@ }, "true-myth": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/true-myth/-/true-myth-4.1.1.tgz", - "integrity": "sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg==", "dev": true }, "ts-jest": { @@ -16077,8 +15892,6 @@ }, "ts-morph": { "version": "13.0.3", - "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-13.0.3.tgz", - "integrity": "sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw==", "dev": true, "requires": { "@ts-morph/common": "~0.12.3", @@ -16106,8 +15919,6 @@ }, "ts-prune": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/ts-prune/-/ts-prune-0.10.3.tgz", - "integrity": "sha512-iS47YTbdIcvN8Nh/1BFyziyUqmjXz7GVzWu02RaZXqb+e/3Qe1B7IQ4860krOeCGUeJmterAlaM2FRH0Ue0hjw==", "dev": true, "requires": { "commander": "^6.2.1", @@ -16120,14 +15931,10 @@ "dependencies": { "commander": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true }, "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", @@ -16139,8 +15946,6 @@ }, "yaml": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true } } From 80313378c2d0e5251f9c74d4a4e736aba02d726f Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 2 Jun 2023 10:13:23 -0400 Subject: [PATCH 146/209] Use ubuntu-latest runner. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d822b5c9..27cb497a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ on: jobs: test: - runs-on: [self-hosted, 1ES.Pool=ost-ospo-opensource] + runs-on: ubuntu-latest steps: - name: Checkout repository From 8552600251c5465b2cf2036eddb7f6ecff241ea1 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 7 Jul 2023 12:09:55 -0400 Subject: [PATCH 147/209] Update codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 4bfc955e2..be69f6ca4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,4 +1,4 @@ -name: 'Code scanning - action' +name: GitHub CodeQL Analysis on: push: From e3898ac3bac1231d6ccf7ab99004365c08fb7f0d Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 7 Jul 2023 12:10:59 -0400 Subject: [PATCH 148/209] Update container.yml --- .github/workflows/container.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index e1a2fb5db..179b287a5 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -1,4 +1,4 @@ -name: Ship it ๐Ÿฟ๏ธ +name: Unused Docker Image - Build on: push: From bf8c39d8798b4a9e811d9f7255233a9d432cd058 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jul 2023 16:04:18 +0000 Subject: [PATCH 149/209] npm:back-end: bump dotenv from 10.0.0 to 16.3.1 Bumps [dotenv](https://github.com/motdotla/dotenv) from 10.0.0 to 16.3.1. - [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) - [Commits](https://github.com/motdotla/dotenv/compare/v10.0.0...v16.3.1) --- updated-dependencies: - dependency-name: dotenv dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 ++++++++++---- package.json | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 617963919..c38f6ac03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "cors": "2.8.5", "debug": "4.3.4", "deepmerge": "4.3.1", - "dotenv": "16.0.3", + "dotenv": "16.3.1", "express": "4.18.2", "express-async-handler": "1.1.4", "express-session": "1.17.3", @@ -4552,10 +4552,14 @@ } }, "node_modules/dotenv": { - "version": "16.0.3", - "license": "BSD-2-Clause", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, "node_modules/dtrace-provider": { @@ -12905,7 +12909,9 @@ } }, "dotenv": { - "version": "16.0.3" + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" }, "dtrace-provider": { "version": "0.8.8", diff --git a/package.json b/package.json index 81053cc82..9c58ee489 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "cors": "2.8.5", "debug": "4.3.4", "deepmerge": "4.3.1", - "dotenv": "16.0.3", + "dotenv": "16.3.1", "express": "4.18.2", "express-async-handler": "1.1.4", "express-session": "1.17.3", From 348e1b048cb1cb30ce8401c29934bcfc5a7132a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jul 2023 16:04:21 +0000 Subject: [PATCH 150/209] npm:back-end: bump jsonwebtoken from 8.5.1 to 9.0.1 Bumps [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) from 8.5.1 to 9.0.1. - [Changelog](https://github.com/auth0/node-jsonwebtoken/blob/master/CHANGELOG.md) - [Commits](https://github.com/auth0/node-jsonwebtoken/commits) --- updated-dependencies: - dependency-name: jsonwebtoken dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 11 +++++++---- package.json | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 617963919..34ba88094 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "js-yaml": "4.1.0", "json-2-csv": "^3.18.0", "jsonc": "2.0.0", - "jsonwebtoken": "9.0.0", + "jsonwebtoken": "9.0.1", "jwks-rsa": "3.0.1", "language-map": "1.5.0", "lodash": "4.17.21", @@ -6842,8 +6842,9 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.0", - "license": "MIT", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", + "integrity": "sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==", "dependencies": { "jws": "^3.2.2", "lodash": "^4.17.21", @@ -14328,7 +14329,9 @@ } }, "jsonwebtoken": { - "version": "9.0.0", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", + "integrity": "sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==", "requires": { "jws": "^3.2.2", "lodash": "^4.17.21", diff --git a/package.json b/package.json index 81053cc82..5dbae7434 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "js-yaml": "4.1.0", "json-2-csv": "^3.18.0", "jsonc": "2.0.0", - "jsonwebtoken": "9.0.0", + "jsonwebtoken": "9.0.1", "jwks-rsa": "3.0.1", "language-map": "1.5.0", "lodash": "4.17.21", From dae32b0c6eb936b7773911e2ef8f5091246a9f01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jul 2023 16:04:28 +0000 Subject: [PATCH 151/209] npm:back-end: bump @types/node from 14.17.0 to 20.4.2 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.17.0 to 20.4.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 11 +++++++---- package.json | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 617963919..d3d0bff11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,7 +82,7 @@ "@types/luxon": "3.3.0", "@types/memory-cache": "0.2.2", "@types/morgan": "1.9.4", - "@types/node": "20.2.3", + "@types/node": "20.4.2", "@types/node-jose": "1.1.10", "@types/object-path": "0.11.1", "@types/passport": "1.0.12", @@ -2727,8 +2727,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.2.3", - "license": "MIT" + "version": "20.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", + "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" }, "node_modules/@types/node-fetch": { "version": "2.6.1", @@ -11772,7 +11773,9 @@ "dev": true }, "@types/node": { - "version": "20.2.3" + "version": "20.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", + "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" }, "@types/node-fetch": { "version": "2.6.1", diff --git a/package.json b/package.json index 81053cc82..a5b3ee0b4 100644 --- a/package.json +++ b/package.json @@ -138,7 +138,7 @@ "@types/luxon": "3.3.0", "@types/memory-cache": "0.2.2", "@types/morgan": "1.9.4", - "@types/node": "20.2.3", + "@types/node": "20.4.2", "@types/node-jose": "1.1.10", "@types/object-path": "0.11.1", "@types/passport": "1.0.12", From 391ab0fffba8483612edc734c06651e65632b293 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jul 2023 23:06:34 +0000 Subject: [PATCH 152/209] npm:back-end: bump @azure/storage-queue from 12.13.0 to 12.14.0 Bumps [@azure/storage-queue](https://github.com/Azure/azure-sdk-for-js) from 12.13.0 to 12.14.0. - [Release notes](https://github.com/Azure/azure-sdk-for-js/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/Changelog-for-next-generation.md) - [Commits](https://github.com/Azure/azure-sdk-for-js/compare/@azure/storage-queue_12.13.0...@azure/storage-queue_12.14.0) --- updated-dependencies: - dependency-name: "@azure/storage-queue" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 11 +++++++---- package.json | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 617963919..d0f0468ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@azure/keyvault-secrets": "4.7.0", "@azure/service-bus": "7.9.0", "@azure/storage-blob": "12.14.0", - "@azure/storage-queue": "12.13.0", + "@azure/storage-queue": "12.14.0", "@octokit/auth-app": "4.0.13", "@octokit/plugin-paginate-graphql": "2.0.1", "@octokit/request": "6.2.5", @@ -604,8 +604,9 @@ } }, "node_modules/@azure/storage-queue": { - "version": "12.13.0", - "license": "MIT", + "version": "12.14.0", + "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.14.0.tgz", + "integrity": "sha512-1j6uxhzCcbEDVPOTNWIJ5CsLzOAU5U/bXgGZeT25fy6IghFTC1JlPGALez2CWJ9fBVj6AmSnsiBXL/77iXhSpg==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^3.0.0", @@ -10261,7 +10262,9 @@ } }, "@azure/storage-queue": { - "version": "12.13.0", + "version": "12.14.0", + "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.14.0.tgz", + "integrity": "sha512-1j6uxhzCcbEDVPOTNWIJ5CsLzOAU5U/bXgGZeT25fy6IghFTC1JlPGALez2CWJ9fBVj6AmSnsiBXL/77iXhSpg==", "requires": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^3.0.0", diff --git a/package.json b/package.json index 81053cc82..d094ff5a2 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@azure/keyvault-secrets": "4.7.0", "@azure/service-bus": "7.9.0", "@azure/storage-blob": "12.14.0", - "@azure/storage-queue": "12.13.0", + "@azure/storage-queue": "12.14.0", "@octokit/plugin-paginate-graphql": "2.0.1", "@octokit/request": "6.2.5", "@octokit/auth-app": "4.0.13", From 3ded18fbe8a6e33c2c7cdd7dec84a56305bfc3fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:16:28 +0000 Subject: [PATCH 153/209] npm:back-end: bump nodemailer from 6.9.2 to 6.9.4 Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 6.9.2 to 6.9.4. - [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodemailer/nodemailer/compare/v6.9.2...v6.9.4) --- updated-dependencies: - dependency-name: nodemailer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 11 +++++++---- package.json | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 617963919..2f23fd1f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "moment": "2.29.4", "morgan": "1.10.0", "node-jose": "2.2.0", - "nodemailer": "6.9.2", + "nodemailer": "6.9.4", "object-path": "0.11.8", "octicons": "5.0.1", "passport": "0.6.0", @@ -7767,8 +7767,9 @@ "license": "MIT" }, "node_modules/nodemailer": { - "version": "6.9.2", - "license": "MIT", + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.4.tgz", + "integrity": "sha512-CXjQvrQZV4+6X5wP6ZIgdehJamI63MFoYFGGPtHudWym9qaEHDNdPzaj5bfMCvxG1vhAileSWW90q7nL0N36mA==", "engines": { "node": ">=6.0.0" } @@ -14921,7 +14922,9 @@ "dev": true }, "nodemailer": { - "version": "6.9.2" + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.4.tgz", + "integrity": "sha512-CXjQvrQZV4+6X5wP6ZIgdehJamI63MFoYFGGPtHudWym9qaEHDNdPzaj5bfMCvxG1vhAileSWW90q7nL0N36mA==" }, "normalize-path": { "version": "3.0.0", diff --git a/package.json b/package.json index 81053cc82..979e1fe70 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "moment": "2.29.4", "morgan": "1.10.0", "node-jose": "2.2.0", - "nodemailer": "6.9.2", + "nodemailer": "6.9.4", "object-path": "0.11.8", "octicons": "5.0.1", "passport": "0.6.0", From 176b59446010dc04cd5bd2b8c9480427fa735ac8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 14:56:24 +0000 Subject: [PATCH 154/209] npm:back-end: bump applicationinsights from 2.3.1 to 2.7.0 Bumps [applicationinsights](https://github.com/microsoft/ApplicationInsights-node.js) from 2.3.1 to 2.7.0. - [Release notes](https://github.com/microsoft/ApplicationInsights-node.js/releases) - [Commits](https://github.com/microsoft/ApplicationInsights-node.js/compare/2.3.1...2.7.0) --- updated-dependencies: - dependency-name: applicationinsights dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 11 +++++++---- package.json | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 04e8eb16c..97a37cd63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "@octokit/request": "6.2.5", "@octokit/rest": "19.0.11", "app-root-path": "3.1.0", - "applicationinsights": "2.6.0", + "applicationinsights": "2.7.0", "async-prompt": "1.0.1", "axios": "1.4.0", "basic-auth": "2.0.1", @@ -3281,8 +3281,9 @@ } }, "node_modules/applicationinsights": { - "version": "2.6.0", - "license": "MIT", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.7.0.tgz", + "integrity": "sha512-/vV5X6M4TlRA5NxNZAdCE0gukzfK24mb3z18D5Kl/CyIfSVIkafsIji3mK+Zi5q+7dn6H1CkFazlcnLf40anHw==", "dependencies": { "@azure/core-auth": "^1.4.0", "@azure/core-rest-pipeline": "1.10.1", @@ -12132,7 +12133,9 @@ "version": "3.1.0" }, "applicationinsights": { - "version": "2.6.0", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.7.0.tgz", + "integrity": "sha512-/vV5X6M4TlRA5NxNZAdCE0gukzfK24mb3z18D5Kl/CyIfSVIkafsIji3mK+Zi5q+7dn6H1CkFazlcnLf40anHw==", "requires": { "@azure/core-auth": "^1.4.0", "@azure/core-rest-pipeline": "1.10.1", diff --git a/package.json b/package.json index df6d826bc..1aaed13d0 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "@octokit/auth-app": "4.0.13", "@octokit/rest": "19.0.11", "app-root-path": "3.1.0", - "applicationinsights": "2.6.0", + "applicationinsights": "2.7.0", "async-prompt": "1.0.1", "axios": "1.4.0", "basic-auth": "2.0.1", From 603787a527dae3c1d0d54064440e5761646f089e Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Tue, 25 Jul 2023 09:46:35 -0400 Subject: [PATCH 155/209] removes user pat in cicd and fixes pagination for org data --- .github/scripts/Create-PSQLUpdate.ps1 | 29 ++++++++++++++++--- .../staging_update_orgsettings_table.yaml | 7 ++--- Dockerfile | 3 -- env-orgs.json | 16 ---------- 4 files changed, 27 insertions(+), 28 deletions(-) delete mode 100644 env-orgs.json diff --git a/.github/scripts/Create-PSQLUpdate.ps1 b/.github/scripts/Create-PSQLUpdate.ps1 index 0bb5c70bd..4ae8a5071 100644 --- a/.github/scripts/Create-PSQLUpdate.ps1 +++ b/.github/scripts/Create-PSQLUpdate.ps1 @@ -1,16 +1,36 @@ +function Get-InstallationToken { + param ( + [Int32] + # The app install ID for the org, used to generate the installation token + $InstallationID, + # Github token + [String] + $JWT + ) + # Get an installation token for the org + $headers = @{ + "Accept" = "application/vnd.github.v3+json" + "Authorization" = "Bearer $JWT" + } + + $response = Invoke-RestMethod -Uri "https://api.github.com/app/installations/$InstallationID/access_tokens" -Method Post -Headers $headers + return $response.token +} + + function Get-OrgData { param ( # Org id to get data for [Int32] $OrganizationID, - # Github token + # Github app token [String] - $Token + $InstallationToken ) # Get data from the REST api $headers = @{ "Accept" = "application/vnd.github.v3+json" - "Authorization" = "Bearer $token" + "Authorization" = "Bearer $InstallationToken" } $orgData = Invoke-RestMethod -Uri "https://api.github.com/orgs/$OrganizationID" -Method Get -Headers $headers return $orgData @@ -22,7 +42,8 @@ $insertData = @() foreach ($item in $data) { Write-Output "Getting data for Org: $($item.account.id)" - $orgData = Get-OrgData -OrganizationID $item.account.id -Token $env:PAT + $org_installation_token = Get-InstallationToken -InstallationID $item.id -JWT (Get-Content token) + $orgData = Get-OrgData -OrganizationID $item.account.id -InstallationToken $org_installation_token $insertData += [PSCustomObject]@{ type = @("public", "private", "internal") active = $true diff --git a/.github/workflows/staging_update_orgsettings_table.yaml b/.github/workflows/staging_update_orgsettings_table.yaml index c30de7c7f..31b520e29 100644 --- a/.github/workflows/staging_update_orgsettings_table.yaml +++ b/.github/workflows/staging_update_orgsettings_table.yaml @@ -28,20 +28,17 @@ jobs: - name: run gh cli to get app install info run: | - curl \ + gh api --paginate \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $(cat token)" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/app/installations | jq >> app_output.json + app/installations | jq >> app_output.json # needs a PAT that can read org and enterprise data - name: run powershell script to build sql run: | .github/scripts/Create-PSQLUpdate.ps1 shell: pwsh - - env: - PAT: ${{ secrets.ENT_READ_PAT }} - name: output sql run: | diff --git a/Dockerfile b/Dockerfile index 91a1715fa..9daba8526 100644 --- a/Dockerfile +++ b/Dockerfile @@ -65,9 +65,6 @@ COPY --from=build --chown=oss:oss /build/config ./config COPY --from=build --chown=oss:oss /build/views ./views COPY --from=build --chown=oss:oss /build/package.json ./package.json -#Do stuff for GitHub Environment Orgs -COPY --from=build --chown=oss:oss /build/env-orgs.json ./env-orgs.json - # Host the app USER oss ENTRYPOINT ["npm", "run-script", "start-in-container"] \ No newline at end of file diff --git a/env-orgs.json b/env-orgs.json deleted file mode 100644 index 4564282f5..000000000 --- a/env-orgs.json +++ /dev/null @@ -1,16 +0,0 @@ -[ - { - "name" : "NIHGOV", - "id" : 2710462, - "type": ["public", "private"], - "description" : "NIHโ€ฆTurning Discovery Into Healthยฎ", - "locked": true - }, - { - "name" : "STRIDES", - "id" : 69810051, - "type": ["public", "private"], - "description" : "NIH Science and Technology Research Infrastructure for Discovery, Experimentation, and Sustainability (STRIDES) Initiative", - "locked": true - } -] From 5fd710392532adfde874b0466638153871116b3a Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 25 Aug 2023 13:06:27 -0400 Subject: [PATCH 156/209] add processing for single quotes --- .github/scripts/Create-PSQLUpdate.ps1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/scripts/Create-PSQLUpdate.ps1 b/.github/scripts/Create-PSQLUpdate.ps1 index 4ae8a5071..0893bb02f 100644 --- a/.github/scripts/Create-PSQLUpdate.ps1 +++ b/.github/scripts/Create-PSQLUpdate.ps1 @@ -44,10 +44,17 @@ foreach ($item in $data) { Write-Output "Getting data for Org: $($item.account.id)" $org_installation_token = Get-InstallationToken -InstallationID $item.id -JWT (Get-Content token) $orgData = Get-OrgData -OrganizationID $item.account.id -InstallationToken $org_installation_token + if ($orgData.description -ne $null) { + $processed_description = $orgData.description.Replace("'", "''") + } + else { + $processed_description = $orgData.description + } + $insertData += [PSCustomObject]@{ type = @("public", "private", "internal") active = $true - portaldescription = $orgData.description + portaldescription = $processed_description updated = get-date -format yyyy-MM-ddTHH:mm:ssZ installations = @( @{ From b8303cf40f6d1802606423c71bf4851491fc267f Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Tue, 29 Aug 2023 13:08:39 -0400 Subject: [PATCH 157/209] GH-151: Add Card for Repo Admin --- business/repository.ts | 86 +++++++++++++++++++++++++++++++++++++++++- routes/org/repos.ts | 1 + views/layout.pug | 1 + views/nih/mixins.pug | 22 +++++++++++ views/repos/repo.pug | 7 +++- 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 views/nih/mixins.pug diff --git a/business/repository.ts b/business/repository.ts index 06ba5bd27..a1e82be00 100644 --- a/business/repository.ts +++ b/business/repository.ts @@ -15,6 +15,8 @@ import { Collaborator, TeamPermission, RepositoryIssue, + TeamMember, + OrganizationMember, } from '.'; import { RepositoryMetadataEntity } from '../entities/repositoryMetadata/repositoryMetadata'; import { AppPurpose, AppPurposeTypes } from './githubApps'; @@ -203,6 +205,18 @@ const safeEntityFieldsForJsonSend = [ 'id', ]; +const sortByLogin = (list) => { + return list.sort(function (a, b) { + if (a.login < b.login) { + return -1; + } + if (a.login > b.login) { + return 1; + } + return 0; + }); +}; + export class Repository { private _entity: any; private _baseUrl: string; @@ -1515,7 +1529,7 @@ export class Repository { } } - async getAdministrators(excludeOwners = true, excludeBroadAndSystemTeams = true): Promise { + async getAdministrators(excludeOwners = true, excludeBroadAndSystemTeams = true): Promise { const operations = throwIfNotGitHubCapable(this._operations); const opsSystemAccounts = operationsWithCapability( operations, @@ -1559,6 +1573,76 @@ export class Repository { return Array.from(users.values()); } + async getAdmins(excludeOwners = true, excludeBroadAndSystemTeams = true): Promise { + /** + * Returns repository administrators and organization owners that are not repository collaborators. + * + * @remarks + * NIH Specific: Used in logic that renders repository administrators cards on the Repo detail page. + * + * @param repository - The GitHub Repository + * @param excludeOwners - Exclude organization owners from the list of administrators + * @param excludeBroadAndSystemTeams - Exclude broad access and system teams from the list of administrators + * @returns An object of AdminUserCollections. + * + * @beta + */ + + const operations = throwIfNotGitHubCapable(this._operations); + const opsSystemAccounts = operationsWithCapability( + operations, + CoreCapability.ServiceAccounts + ); + const owners = await this._organization.getOwners(); + const ownersSet = new Set(owners.map((o) => o.login.toLowerCase())); + const actualCollaborators = await this.getCollaborators({ + affiliation: GitHubCollaboratorAffiliationQuery.Direct, + }); + + let collaborators: (TeamMember | Collaborator | OrganizationMember)[] = actualCollaborators.filter( + (c) => c.permissions?.admin === true + ); + + // No system accounts or owners + if (opsSystemAccounts) { + collaborators = collaborators.filter( + (c) => false === opsSystemAccounts.isSystemAccountByUsername(c.login) + ); + } + + if (excludeOwners) { + collaborators = collaborators.filter((c) => false === ownersSet.has(c.login.toLowerCase())); + } + + const teams = (await this.getTeamPermissions()).filter((tp) => tp.permission === 'admin'); + + for (let i = 0; i < teams.length; i++) { + const team = teams[i]; + if (excludeBroadAndSystemTeams && (team.team.isSystemTeam || team.team.isBroadAccessTeam)) { + // Do not include broad access teams + continue; + } + const members = await team.team.getMembers(); + for (let j = 0; j < members.length; j++) { + const tm = members[j]; + const login = tm.login.toLowerCase(); + if (!opsSystemAccounts || !opsSystemAccounts.isSystemAccountByUsername(login)) { + collaborators.push(tm); + } + } + } + + const collaboratorsSet = collaborators.map((c) => c.login.toLowerCase()); + const orgOwnersButNotCollaborators = excludeOwners + ? [] + : owners.filter((c) => false === collaboratorsSet.includes(c.login.toLowerCase())); + + collaborators.forEach((n) => (n['adminType'] = 'Admin')); + orgOwnersButNotCollaborators.forEach((n) => (n['adminType'] = 'Org Admin')); + + return sortByLogin(collaborators).concat(sortByLogin(orgOwnersButNotCollaborators)); + } + async getPushers(): Promise { const operations = throwIfNotGitHubCapable(this._operations); const opsSystemAccounts = operationsWithCapability( diff --git a/routes/org/repos.ts b/routes/org/repos.ts index 608c7f9b8..84bdd66b5 100644 --- a/routes/org/repos.ts +++ b/routes/org/repos.ts @@ -448,6 +448,7 @@ router.get( currentManagementChain, repo, repository, + repoAdmins: await repository.getAdmins(), // permissions: slicePermissionsForView(filterSystemTeams(teamsFilterType.systemTeamsExcluded, systemTeams, permissions)), // systemPermissions: slicePermissionsForView(filterSystemTeams(teamsFilterType.systemTeamsOnly, systemTeams, permissions)), // collaborators: sliceCollaboratorsForView(collaborators), diff --git a/views/layout.pug b/views/layout.pug index 874a44c06..640e9c6fd 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -2,6 +2,7 @@ //- Copyright (c) Microsoft. //- Licensed under the MIT license. See LICENSE file in the project root for full license information. //- +include ./nih/mixins doctype html html(lang="en") diff --git a/views/nih/mixins.pug b/views/nih/mixins.pug new file mode 100644 index 000000000..c5a084825 --- /dev/null +++ b/views/nih/mixins.pug @@ -0,0 +1,22 @@ + +//- Renders repository owners card +//- admins: user object with login, avatar_url, and adminType which is one of "Admin" or "Org Admin" +//- maxCards: Maximum number of cards to render +mixin repositoryAdminCards(admins, maxCards = 5) + ul.list-unstyled + - var cardsToShow = Math.min(admins.length, maxCards) + - for (var i = 0; i < cardsToShow; i++) + - var admin = admins[i] + li(style='vertical-align:top;width:370px') + ul.list-inline + if admin.avatar_url + li(style='vertical-align:top;margin-top:12px;padding-right:3px'): img( + alt=admin.login, + src=admin.avatar_url + '&s=96', + style='width:36px;height:36px;') + li + ul.list-unstyled(style='margin-right:16px') + li: h5(style='margin-bottom:.3em') + a(href='/people?q=' + admin.login)= admin.login + - var title = admin.adminType == "Org Admin" ? organization.name + ' organization owner' : repo.name + 'direct repo owner' + .label.label-info(title=title, style='margin-left: 5px; cursor: default')= admin.adminType diff --git a/views/repos/repo.pug b/views/repos/repo.pug index f00227b04..251a67f1e 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -228,7 +228,12 @@ block content href='https://github.com/' + repo.full_name + '/settings/hooks', target='_blank' ) Webhooks - + + hr + + h4 Repository Admins + if repoAdmins + +repositoryAdminCards(repoAdmins) //- Disabling this function as it is high risk: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement //- if repoPermissions.allowAdministration && repo.private === true //- ul.list-unstyled.list-vspace From 1bbfa731dea8c07ea6ad57be90e3561a2d47a0d0 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Tue, 29 Aug 2023 13:10:08 -0400 Subject: [PATCH 158/209] Enable viewing locked orgs feature flag in the devcontainer. --- .devcontainer/nih/devcontainer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.devcontainer/nih/devcontainer.json b/.devcontainer/nih/devcontainer.json index cbdbce071..5e77c838e 100644 --- a/.devcontainer/nih/devcontainer.json +++ b/.devcontainer/nih/devcontainer.json @@ -21,6 +21,7 @@ "DEBUG_ALLOW_HTTP": "${localEnv:DEBUG_ALLOW_HTTP}", "DEBUG_SHOW_FOOTER": "${localEnv:DEBUG_SHOW_FOOTER:1}", "ENVIRONMENT_NAME": "${localEnv:ENVIRONMENT_NAME}", + "FEATURE_FLAG_ALLOW_USERS_TO_VIEW_LOCKED_ORG_DETAILS": "1", "GITHUB_APP_ACTIONS_APP_ID": "${localEnv:GH_APP_ACTIONS_APP_ID}", "GITHUB_APP_ACTIONS_KEY": "${localEnv:GH_APP_ACTIONS_KEY}", "GITHUB_APP_ACTIONS_KEY_FILE": "${localEnv:GH_APP_ACTIONS_KEY_FILE}", From b07c1a77640e7e27c14c831e2aa97fe4e301050b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:20:27 -0400 Subject: [PATCH 159/209] npm:back-end: bump redis from 4.6.6 to 4.6.8 (#340) Bumps [redis](https://github.com/redis/node-redis) from 4.6.6 to 4.6.8. - [Release notes](https://github.com/redis/node-redis/releases) - [Changelog](https://github.com/redis/node-redis/blob/master/CHANGELOG.md) - [Commits](https://github.com/redis/node-redis/compare/redis@4.6.6...redis@4.6.8) --- updated-dependencies: - dependency-name: redis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 53 +++++++++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 97a37cd63..911fbbe64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "pug": "3.0.2", "pug-load": "3.0.0", "recursive-readdir": "2.2.3", - "redis": "4.6.6", + "redis": "4.6.8", "secure-compare": "3.0.1", "semver": "7.5.1", "serve-favicon": "2.5.0", @@ -2429,8 +2429,9 @@ } }, "node_modules/@redis/client": { - "version": "1.5.7", - "license": "MIT", + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.9.tgz", + "integrity": "sha512-SffgN+P1zdWJWSXBvJeynvEnmnZrYmtKSRW00xl8pOPFOMJjxRR9u0frSxJpPR6Y4V+k54blJjGW7FgxbTI7bQ==", "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -2455,15 +2456,17 @@ } }, "node_modules/@redis/search": { - "version": "1.1.2", - "license": "MIT", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", + "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/time-series": { - "version": "1.0.4", - "license": "MIT", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -8656,18 +8659,16 @@ } }, "node_modules/redis": { - "version": "4.6.6", - "license": "MIT", - "workspaces": [ - "./packages/*" - ], + "version": "4.6.8", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", + "integrity": "sha512-S7qNkPUYrsofQ0ztWlTHSaK0Qqfl1y+WMIxrzeAGNG+9iUZB4HGeBgkHxE6uJJ6iXrkvLd1RVJ2nvu6H1sAzfQ==", "dependencies": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.7", + "@redis/client": "1.5.9", "@redis/graph": "1.1.0", "@redis/json": "1.0.4", - "@redis/search": "1.1.2", - "@redis/time-series": "1.0.4" + "@redis/search": "1.1.3", + "@redis/time-series": "1.0.5" } }, "node_modules/repeat-string": { @@ -11539,7 +11540,9 @@ "requires": {} }, "@redis/client": { - "version": "1.5.7", + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.9.tgz", + "integrity": "sha512-SffgN+P1zdWJWSXBvJeynvEnmnZrYmtKSRW00xl8pOPFOMJjxRR9u0frSxJpPR6Y4V+k54blJjGW7FgxbTI7bQ==", "requires": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -11555,11 +11558,15 @@ "requires": {} }, "@redis/search": { - "version": "1.1.2", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", + "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", "requires": {} }, "@redis/time-series": { - "version": "1.0.4", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", "requires": {} }, "@sideway/address": { @@ -15479,14 +15486,16 @@ } }, "redis": { - "version": "4.6.6", + "version": "4.6.8", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", + "integrity": "sha512-S7qNkPUYrsofQ0ztWlTHSaK0Qqfl1y+WMIxrzeAGNG+9iUZB4HGeBgkHxE6uJJ6iXrkvLd1RVJ2nvu6H1sAzfQ==", "requires": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.7", + "@redis/client": "1.5.9", "@redis/graph": "1.1.0", "@redis/json": "1.0.4", - "@redis/search": "1.1.2", - "@redis/time-series": "1.0.4" + "@redis/search": "1.1.3", + "@redis/time-series": "1.0.5" } }, "repeat-string": { diff --git a/package.json b/package.json index 1aaed13d0..a86483193 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "pug": "3.0.2", "pug-load": "3.0.0", "recursive-readdir": "2.2.3", - "redis": "4.6.6", + "redis": "4.6.8", "secure-compare": "3.0.1", "semver": "7.5.1", "serve-favicon": "2.5.0", From faf029339dd279b4f223b2685d935c672031b435 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Tue, 29 Aug 2023 16:32:19 -0400 Subject: [PATCH 160/209] GH-152: Add an Org Owner Card for members --- business/organization.ts | 32 ++++++++++++++++++++++++++++++++ routes/org/index.ts | 3 ++- routes/org/join.ts | 28 ++-------------------------- views/nih/mixins.pug | 30 ++++++++++++++++++++++++++++++ views/org/index.pug | 3 +++ views/org/publicView.pug | 25 +------------------------ 6 files changed, 70 insertions(+), 51 deletions(-) diff --git a/business/organization.ts b/business/organization.ts index 96792724f..b25945d04 100644 --- a/business/organization.ts +++ b/business/organization.ts @@ -846,6 +846,38 @@ export class Organization { return this.getMembers(memberOptions); } + async getOwnersCardData() { + const [linkedOrgAdmins, unlinkedOrgAdmins] = await Promise.all([ + this.getLinkedMembers({ role: OrganizationMembershipRoleQuery.Admin }), + this.getUnlinkedMembers({ role: OrganizationMembershipRoleQuery.Admin }), + ]); + + // clean up admin data for the front end + const organizationAdmins = Array.prototype + .concat(linkedOrgAdmins, unlinkedOrgAdmins) + .reduce((acc, admin) => { + const { member, link } = admin; + + // linked and unlinked admins return slightly different data structures + const login = member ? member.login : admin.login; + const avatar_url = member ? member.avatar_url : admin.avatar_url; + // fallback to corporateUsername if corporateMailAddress is not available + const mailAddress = link ? link.corporateMailAddress || link.corporateUsername : undefined; + const primaryName = link ? link.corporateDisplayName || link.corporateUsername : login; + + acc.push({ + login, + mailAddress, + avatar_url, + primaryName, + }); + + return acc; + }, []); + + return organizationAdmins; + } + async getAuditLog(options?: IGetOrganizationAuditLogOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this._operations); diff --git a/routes/org/index.ts b/routes/org/index.ts index cff5edcd7..28281c3b1 100644 --- a/routes/org/index.ts +++ b/routes/org/index.ts @@ -6,7 +6,6 @@ import express, { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); - import { getProviders } from '../../transitional'; import { IAggregateUserSummary } from '../../business/user/aggregate'; import { TeamJoinApprovalEntity } from '../../entities/teamJoinApproval/teamJoinApproval'; @@ -97,6 +96,7 @@ router.get( const organization = req.organization; const username = req.individualContext.getGitHubIdentity().username; const individualContext = req.individualContext; + const organizationAdmins = await organization.getOwnersCardData(); const results = { orgUser: organization.memberFromEntity(await organization.getDetails()), isMembershipPublic: await organization.checkPublicMembership(username), @@ -105,6 +105,7 @@ router.get( isSudoer: false, // if (results.isAdministrator && results.isAdministrator === true) { results.isSudoer = true; teamsMaintainedHash: null, pendingApprovals: null as TeamJoinApprovalEntity[], + organizationAdmins, }; results.organizationOverview = await individualContext.aggregations.getAggregatedOrganizationOverview( organization diff --git a/routes/org/join.ts b/routes/org/join.ts index ec1612520..30c4435d8 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -86,36 +86,12 @@ async function showOrgJoinDetails(req: ReposAppRequest) { // this implementation as close to the default org get route as possible const { individualContext, organization } = req; - const [linkedOrgAdmins, unlinkedOrgAdmins, orgDetails, organizationOverview] = await Promise.all([ - organization.getLinkedMembers({ role: OrganizationMembershipRoleQuery.Admin }), - organization.getUnlinkedMembers({ role: OrganizationMembershipRoleQuery.Admin }), + const [orgDetails, organizationOverview, organizationAdmins] = await Promise.all([ organization.getDetails(), individualContext.aggregations.getAggregatedOrganizationOverview(organization), + organization.getOwnersCardData(), ]); - // clean up admin data for the front end - const organizationAdmins = Array.prototype - .concat(linkedOrgAdmins, unlinkedOrgAdmins) - .reduce((acc, admin) => { - const { member, link } = admin; - - // linked and unlinked admins return slightly different data structures - const login = member ? member.login : admin.login; - const avatar_url = member ? member.avatar_url : admin.avatar_url; - // fallback to corporateUsername if corporateMailAddress is not available - const mailAddress = link ? link.corporateMailAddress || link.corporateUsername : undefined; - const primaryName = link ? link.corporateDisplayName || link.corporateUsername : login; - - acc.push({ - login, - mailAddress, - avatar_url, - primaryName, - }); - - return acc; - }, []); - const results = { orgUser: organization.memberFromEntity(orgDetails), orgDetails, //org details from GitHub diff --git a/views/nih/mixins.pug b/views/nih/mixins.pug index c5a084825..3c339d889 100644 --- a/views/nih/mixins.pug +++ b/views/nih/mixins.pug @@ -20,3 +20,33 @@ mixin repositoryAdminCards(admins, maxCards = 5) a(href='/people?q=' + admin.login)= admin.login - var title = admin.adminType == "Org Admin" ? organization.name + ' organization owner' : repo.name + 'direct repo owner' .label.label-info(title=title, style='margin-left: 5px; cursor: default')= admin.adminType + + +//- Renders organization owner card +//- admins: user objects with login, avatar_url, primaryName +//- maxCards: Maximum number of cards to render +mixin orgAdminCards(organizationAdmins, maxCards = 5) + ul.list-unstyled + - var admins = organizationAdmins + - var cardsToShow = Math.min(admins.length, maxCards) + - for (var i = 0; i < cardsToShow; i++) + - var admin = admins[i] + li(style='vertical-align:top;width:370px') + ul.list-inline + if admin.avatar_url + li(style='vertical-align:top;margin-top:12px;padding-right:3px'): img( + alt=admin.login, + src=admin.avatar_url + '&s=96', + style='width:36px;height:36px;') + li + ul.list-unstyled(style='margin-right:16px') + li: h5(style='margin-bottom:.3em') + a(href='/people?q=' + admin.login)= admin.primaryName + .label.label-info(title=organization.name + ' organization owner', style='margin-left: 5px; cursor: default') Owner + ul.list-inline + if admin.primaryName != admin.login + li: p(style='font-size: .8em') + a(href='https://github.com/' + admin.login, target='_new', style='color: black; text-decoration:none')= admin.login + if admin.mailAddress + li: a(href='mailto:' + admin.mailAddress, title='Send email to ' + admin.mailAddress) + != octicon('mail', 16) diff --git a/views/org/index.pug b/views/org/index.pug index aa123c23c..d086d3ab0 100644 --- a/views/org/index.pug +++ b/views/org/index.pug @@ -260,6 +260,9 @@ block content h2 | ∞  small Public + hr + h3 Owners + +orgAdminCards(accountInfo.organizationAdmins, 5) hr p diff --git a/views/org/publicView.pug b/views/org/publicView.pug index 64cafa2f1..01714fb6b 100644 --- a/views/org/publicView.pug +++ b/views/org/publicView.pug @@ -129,27 +129,4 @@ block content != octicon('alert', 17) = 'Invitation Required' p Access to this organization requires an invitation from one of the following administrators. - ul.list-unstyled - - var admins = organizationAdmins - - var adminCount = admins.length - - for (var i = 0; i < adminCount; i++) - - var admin = admins[i] - li(style='vertical-align:top;width:370px') - ul.list-inline - if admin.avatar_url - li(style='vertical-align:top;margin-top:12px;padding-right:3px'): img( - alt=admin.login, - src=admin.avatar_url + '&s=96', - style='width:36px;height:36px;') - li - ul.list-unstyled(style='margin-right:16px') - li: h5(style='margin-bottom:.3em') - a(href='/people?q=' + admin.login)= admin.primaryName - .label.label-info(title=organization.name + ' organization owner', style='margin-left: 5px; cursor: default') Owner - ul.list-inline - if admin.primaryName != admin.login - li: p(style='font-size: .8em') - a(href='https://github.com/' + admin.login, target='_new', style='color: black; text-decoration:none')= admin.login - if admin.mailAddress - li: a(href='mailto:' + admin.mailAddress, title='Send email to ' + admin.mailAddress) - != octicon('mail', 16) + +orgAdminCards(organizationAdmins, 5) From 02e1cedb02102da3d4928a79d3c77df55a317098 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 1 Sep 2023 11:52:58 -0400 Subject: [PATCH 161/209] Show org owners as well as direct owners. --- routes/org/repos.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/org/repos.ts b/routes/org/repos.ts index 84bdd66b5..33b06df44 100644 --- a/routes/org/repos.ts +++ b/routes/org/repos.ts @@ -448,7 +448,7 @@ router.get( currentManagementChain, repo, repository, - repoAdmins: await repository.getAdmins(), + repoAdmins: await repository.getAdmins(false, false), // permissions: slicePermissionsForView(filterSystemTeams(teamsFilterType.systemTeamsExcluded, systemTeams, permissions)), // systemPermissions: slicePermissionsForView(filterSystemTeams(teamsFilterType.systemTeamsOnly, systemTeams, permissions)), // collaborators: sliceCollaboratorsForView(collaborators), From 536959c79e7909bc6907e142c8dcb8dceaecea21 Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 1 Sep 2023 12:06:04 -0400 Subject: [PATCH 162/209] Conditionally show the repository admins header. --- views/repos/repo.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/repos/repo.pug b/views/repos/repo.pug index 251a67f1e..da2e35ae1 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -231,8 +231,8 @@ block content hr - h4 Repository Admins if repoAdmins + h4 Repository Admins +repositoryAdminCards(repoAdmins) //- Disabling this function as it is high risk: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement //- if repoPermissions.allowAdministration && repo.private === true From 440a30a605770847d78e044b49da68fa38cbf39b Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 3 Nov 2023 10:59:39 -0400 Subject: [PATCH 163/209] Add pingInterval to the Redis configuration. --- middleware/initialize.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/middleware/initialize.ts b/middleware/initialize.ts index 49801b92c..94b562460 100644 --- a/middleware/initialize.ts +++ b/middleware/initialize.ts @@ -590,6 +590,7 @@ async function connectRedis( port: config.redis.port ? Number(config.redis.port) : config.redis.tls ? 6380 : 6379, password: config.redis.key, tls: !!config.redis.tls, + pingInterval: 5 * 60 * 1000, // Ping Each 5min. https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-best-practices-connection#idle-timeout }, // name }; From 4c99d1340eef93b24242c9c32c151fde07ff45ab Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 3 Nov 2023 13:45:33 -0400 Subject: [PATCH 164/209] Move the pingInterval setting in to the root connection params. (#373) --- middleware/initialize.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/middleware/initialize.ts b/middleware/initialize.ts index 94b562460..b249d29bd 100644 --- a/middleware/initialize.ts +++ b/middleware/initialize.ts @@ -590,9 +590,8 @@ async function connectRedis( port: config.redis.port ? Number(config.redis.port) : config.redis.tls ? 6380 : 6379, password: config.redis.key, tls: !!config.redis.tls, - pingInterval: 5 * 60 * 1000, // Ping Each 5min. https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-best-practices-connection#idle-timeout }, - // name + pingInterval: 5 * 60 * 1000, // Ping Each 5min. https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-best-practices-connection#idle-timeout }; debug(`connecting to ${purpose} Redis ${redisConfig.host || redisConfig.tls}`); const redisClient: RedisClientType = createClient(redisOptions); From e1ad84ba6c30166666deb3b8bdb9e422781fac9d Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:49:26 -0500 Subject: [PATCH 165/209] Update main_nihgithubportal.yml remove unused step for deploy --- .github/workflows/main_nihgithubportal.yml | 36 +--------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 00dadfcae..60f5d13d1 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -30,41 +30,7 @@ jobs: npm run build cd .. npm run test --if-present - - - name: get orgs from graphql - run: | - gh api graphql -f ent=nih -f query='query($ent: String!) { - enterprise(slug: $ent) { - organizations(first: 100) { - nodes { - description - login - databaseId - id - name - } - } - } - }' >> raw.json - cat raw.json - env: - GITHUB_TOKEN: ${{ secrets.ENT_READ_PAT}} - - - name: run powershell script to create env orgs json - run: | - ./.github/scripts/Create-EnvOrgs.ps1 - cat orgs.json - ls - shell: pwsh - - - name: check file - run: | - cat orgs.json - ls -lah - rm env-orgs.json - cat orgs.json >> env-orgs.json - cat env-orgs.json - + - name: zip application folders run: | echo $PWD From e8bb11cca8dc1be9e97574e05b065586eb18cecc Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Tue, 12 Dec 2023 10:17:24 -0500 Subject: [PATCH 166/209] Use the upstream dockerfile. --- Dockerfile | 52 ++++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/Dockerfile b/Dockerfile index 936943628..43e749481 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,8 +9,6 @@ FROM $IMAGE_NAME AS build ARG NPM_TOKEN -# Make Git available for NPM and rsync in the build image -RUN apk add --update git && rm -rf /var/cache/apk/* RUN tdnf -y update --quiet # We used to also make Git available for NPM and rsync in build @@ -18,33 +16,20 @@ RUN tdnf -y update --quiet # tdnf -y install ca-certificates git --quiet && \ WORKDIR /build -COPY package.json . -COPY package-lock.json . - -# Only if needed, copy .npmrc files into the container -# COPY Dockerfile.npmrc /build/.npmrc - -# If you are doing local development and OK with your private tokens in the contains (CAREFUL): -# DO NOT RECOMMEND: -# COPY .npmrc /build/.npmrc - -# RUN npm install --production --verbose && mv node_modules production_node_modules -RUN npm install --production && mv node_modules production_node_modules COPY . . -# Only if needed, copy .npmrc files into the container, again... -# COPY Dockerfile.npmrc /build/.npmrc +# Only if needed, copy file with NPM_TOKEN arg +# COPY .npmrc.arg /build/.npmrc -# Dev dependencies -# RUN npm install --verbose && rm -rf .npmrc -RUN npm install && rm -rf .npmrc - -# TypeScript build +# RUN npm install --ignore-scripts --production --verbose +RUN npm ci RUN npm run-script build +RUN mv node_modules production_node_modules +RUN rm -f .npmrc # The open source project build needs: build the site assets sub-project -RUN cd default-assets-package && npm install && npm run build +RUN cd default-assets-package && npm ci && npm run build FROM $IMAGE_NAME AS run @@ -57,24 +42,23 @@ EXPOSE 3000 WORKDIR /usr/src/repos -RUN addgroup oss && adduser -D -G oss oss && chown -R oss:oss . - # Production Node.js modules -COPY --from=build --chown=oss:oss /build/production_node_modules ./node_modules +COPY --from=build /build/production_node_modules ./node_modules # People not using painless config may need -COPY --from=build --chown=oss:oss /build/data ./data +COPY --from=build /build/data ./data # Copy built assets, app, config map -COPY --from=build --chown=oss:oss /build/dist ./ +COPY --from=build /build/dist ./ # The open source project build needs: default assets should be placed -COPY --from=build --chown=oss:oss /build/default-assets-package ./default-assets-package +COPY --from=build /build/default-assets-package ./default-assets-package + +COPY --from=build /build/config ./config +COPY --from=build /build/views ./views +COPY --from=build /build/package.json ./package.json -COPY --from=build --chown=oss:oss /build/config ./config -COPY --from=build --chown=oss:oss /build/views ./views -COPY --from=build --chown=oss:oss /build/package.json ./package.json +# Only if needed, copy our environment +# COPY --from=build /build/.environment ./.environment -# Host the app -USER oss -ENTRYPOINT ["npm", "run-script", "start-in-container"] \ No newline at end of file +ENTRYPOINT ["npm", "run-script", "start-in-container"] From 8f80b0c6081cf62e407d91a51e0a8ba2232b58a9 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Thu, 18 Jan 2024 09:06:30 -0500 Subject: [PATCH 167/209] fix dockerfile and merge confclits --- Dockerfile | 2 +- routes/org/index.ts | 4 ---- routes/org/join.ts | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1994326d1..a3f30f081 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ COPY . . # Only if needed, copy file with NPM_TOKEN arg # COPY .npmrc.arg /build/.npmrc -# RUN npm install --ignore-scripts --production --verbose +RUN npm install --ignore-scripts --production --verbose RUN npm ci RUN npm run-script build RUN mv node_modules production_node_modules diff --git a/routes/org/index.ts b/routes/org/index.ts index 94bf433c4..474745f2c 100644 --- a/routes/org/index.ts +++ b/routes/org/index.ts @@ -6,12 +6,8 @@ import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -<<<<<<< HEAD -import { getProviders } from '../../transitional'; -======= import { getProviders } from '../../lib/transitional'; ->>>>>>> upstream/main import { IAggregateUserSummary } from '../../business/user/aggregate'; import { TeamJoinApprovalEntity } from '../../business/entities/teamJoinApproval/teamJoinApproval'; import { Team } from '../../business'; diff --git a/routes/org/join.ts b/routes/org/join.ts index b18f40eb1..c136320ea 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -10,12 +10,8 @@ import asyncHandler from 'express-async-handler'; const router: Router = Router(); import querystring from 'querystring'; -<<<<<<< HEAD -import { CreateError, getProviders } from '../../transitional'; -======= import { CreateError, getProviders } from '../../lib/transitional'; ->>>>>>> upstream/main import { IndividualContext } from '../../business/user'; import { sleep, storeOriginalUrlAsReferrer, wrapError } from '../../lib/utils'; import RequireActiveGitHubSession from '../../middleware/github/requireActiveSession'; From d5568b8c836a71625d18f7cb4f43198f0eb6796e Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:10:06 -0500 Subject: [PATCH 168/209] update svg icon name --- views/people/index.pug | 2 +- views/repos/index.pug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/views/people/index.pug b/views/people/index.pug index 5266558b8..edaf41e3d 100644 --- a/views/people/index.pug +++ b/views/people/index.pug @@ -51,7 +51,7 @@ block content //-ul.nav.nav-pills li(class=(search.sort === 'Alphabet' ? 'active' : ''), title='Alphabetically sorted') a(href='?sort=Alphabet&tag=' + (tag ? tag : '') + (query.phrase ? '&q=' + query.phrase : '')) - != octicon('text-size', 20) + != octicon('typography', 20) | Name form.form-horizontal#entitySearch(style='margin-top:24px') diff --git a/views/repos/index.pug b/views/repos/index.pug index 8ffce2683..ca7406137 100644 --- a/views/repos/index.pug +++ b/views/repos/index.pug @@ -81,7 +81,7 @@ block content li(class=(search.sort === 'Alphabet' ? 'active' : ''), title='Sort by repo name') a(href='?sort=Alphabet&tag=' + (specificTeamId ? '&teamRepos=' + specificTeamId : '') + (tag ? tag : '') + (query.tt ? '&tt=' + query.tt : '') + (query.phrase ? '&q=' + query.phrase : '')) //- i.glyphicon.glyphicon-sort-by-alphabet - != octicon('text-size', 20) + != octicon('typography', 20) | Name //-i.glyphicon.glyphicon-triangle-bottom li(class=(search.sort === 'Updated' ? 'active' : '')) From 24cd6e9912628ba878e211593bdc6740e0a0989e Mon Sep 17 00:00:00 2001 From: Tyler Garner Date: Fri, 19 Jan 2024 16:04:23 -0500 Subject: [PATCH 169/209] Update package-lock.json issue breaking ci. --- package-lock.json | 13110 ++++++++++++-------------------------------- 1 file changed, 3369 insertions(+), 9741 deletions(-) diff --git a/package-lock.json b/package-lock.json index c791a2020..5e48390e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "opensource-management-portal", "version": "7.1.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -128,8 +128,9 @@ }, "node_modules/@ampproject/remapping": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -139,13 +140,14 @@ } }, "node_modules/@azure/abort-controller": { - "version": "1.0.4", - "license": "MIT", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", "dependencies": { - "tslib": "^2.0.0" + "tslib": "^2.2.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/core-amqp": { @@ -169,13 +171,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/core-asynciterator-polyfill": { - "version": "1.0.2", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/core-auth": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.5.0.tgz", @@ -190,24 +185,50 @@ } }, "node_modules/@azure/core-client": { - "version": "1.5.0", - "license": "MIT", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.7.3.tgz", + "integrity": "sha512-kleJ1iUTxcO32Y06dH9Pfi9K4U+Tlb111WXEnbt7R/ne+NLRwppZiTGJuTD5VVoxTMK5NTbEtm5t2vcdNCFe2g==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/core-http": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.4.tgz", + "integrity": "sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-asynciterator-polyfill": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.5.0", "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.5.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/@azure/core-http-compat": { "version": "1.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-1.3.0.tgz", + "integrity": "sha512-ZN9avruqbQ5TxopzG3ih3KRy52n8OAbitX3fnZT5go4hzu0J+KVPSzkL+Wt3hpJpdG8WIfg1sBD1tWkgUdEpBA==", "dependencies": { "@azure/abort-controller": "^1.0.4", "@azure/core-client": "^1.3.0", @@ -217,22 +238,36 @@ "node": ">=12.0.0" } }, + "node_modules/@azure/core-http/node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "dependencies": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/core-lro": { - "version": "2.2.4", - "license": "MIT", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.5.4.tgz", + "integrity": "sha512-3GJiMVH7/10bulzOKGrrLeG/uCBH/9VtxqaMcB9lIqAeamI/xYQSHJL/KcsLDuH+yTjYpro/u6D/MuRe4dN70Q==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.2.0", "@azure/logger": "^1.0.0", "tslib": "^2.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/@azure/core-paging": { "version": "1.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.5.0.tgz", + "integrity": "sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==", "dependencies": { "tslib": "^2.2.0" }, @@ -241,39 +276,28 @@ } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.10.1", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.13.0.tgz", + "integrity": "sha512-a62aP/wppgmnfIkJLfcB4ssPBcH94WzrzPVJ3tlJt050zX4lfmtnvy95D3igDo3f31StO+9BgPrzvkj4aOxnoA==", "dependencies": { - "@azure/abort-controller": "^1.0.0", + "@azure/abort-controller": "^1.1.0", "@azure/core-auth": "^1.4.0", "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.0.0", + "@azure/core-util": "^1.3.0", "@azure/logger": "^1.0.0", - "form-data": "^4.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@azure/core-rest-pipeline/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { "tslib": "^2.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" } }, "node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "license": "MIT", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", "dependencies": { - "@opentelemetry/api": "^1.0.1", "tslib": "^2.2.0" }, "engines": { @@ -281,21 +305,23 @@ } }, "node_modules/@azure/core-util": { - "version": "1.2.0", - "license": "MIT", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.6.1.tgz", + "integrity": "sha512-h5taHeySlsV9qxuK64KZxy4iln1BtMYlNt5jbuEFN3UFSAd1EwKg/Gjl5a6tZ/W8t6li3xPnutOx7zbDyXnPmQ==", "dependencies": { "@azure/abort-controller": "^1.0.0", "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@azure/core-xml": { - "version": "1.3.3", - "license": "MIT", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.4.tgz", + "integrity": "sha512-B1xI79Ur/u+KR69fGTcsMNj8KDjBSqAy0Ys6Byy4Qm1CqoUy7gCT5A7Pej0EBWRskuH6bpCwrAnosfmQEalkcg==", "dependencies": { - "fast-xml-parser": "^4.0.8", + "fast-xml-parser": "^4.2.4", "tslib": "^2.2.0" }, "engines": { @@ -325,19 +351,10 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/cosmos/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/data-tables": { "version": "13.2.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-13.2.2.tgz", + "integrity": "sha512-Dq2Aq0mMMF0BPzYQKdBY/OtO7VemP/foh6z+mJpUO1hRL+65C1rGQUJf20LJHotSyU8wHb4HJzOs+Z50GXSy1w==", "dependencies": { "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", @@ -353,16 +370,6 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/data-tables/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/identity": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.0.0.tgz", @@ -387,19 +394,10 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/identity/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/keyvault-secrets": { "version": "4.7.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.7.0.tgz", + "integrity": "sha512-YvlFXRQ+SI5NT4GtSFbb6HGo6prW3yzDab8tr6vga2/SjDQew3wJsCAAr/xwZz6XshFXCYEX26CDKmPf+SJKJg==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -417,56 +415,47 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/keyvault-secrets/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/logger": { - "version": "1.0.3", - "license": "MIT", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz", + "integrity": "sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==", "dependencies": { "tslib": "^2.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/@azure/msal-browser": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.6.0.tgz", - "integrity": "sha512-FrFBJXRJMyWXjAjg4cUNZwEKktzfzD/YD9+S1kj2ors67hKoveam4aL0bZuCZU/jTiHTn0xDQGQh2ksCMXTXtA==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.7.0.tgz", + "integrity": "sha512-ktDB/Gf7UDgYBJOnoIlh70lxIo4e1/D2UgHuayB4RntN1IlusfTtIVH3k8NpJMdl+38tfTXIaUoR+qlr5voZEg==", "dependencies": { - "@azure/msal-common": "14.5.0" + "@azure/msal-common": "14.6.0" }, "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-common": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.5.0.tgz", - "integrity": "sha512-Gx5rZbiZV/HiZ2nEKfjfAF/qDdZ4/QWxMvMo2jhIFVz528dVKtaZyFAOtsX2Ak8+TQvRsGCaEfuwJFuXB6tu1A==", + "version": "14.6.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.6.0.tgz", + "integrity": "sha512-AGusT/JvxdzJIYi5u0n97cmhd3pUT6UuI6rEkT5iDeT2FGcV0/EB8pk+dy6GLPpYg9vhDCuyoYrEZGd+2UeCCQ==", "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-node": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.6.0.tgz", - "integrity": "sha512-RWAWCYYrSldIYC47oWtofIun41e6SB9TBYgGYsezq6ednagwo9ZRFyRsvl1NabmdTkdDDXRAABIdveeN2Gtd8w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.6.1.tgz", + "integrity": "sha512-wYwz83pWatTNWUCkTi3cAOXbchad5FnZz/pbZz7b8Z6FuEqohXcTtg6BLip9SmcjN6FlbwUdJIZYOof2v1Gnrg==", "dependencies": { - "@azure/msal-common": "14.5.0", + "@azure/msal-common": "14.6.0", "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, "engines": { - "node": "16|| 18 || 20" + "node": ">=16" } }, "node_modules/@azure/opentelemetry-instrumentation-azure-sdk": { @@ -485,17 +474,6 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/opentelemetry-instrumentation-azure-sdk/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/service-bus": { "version": "7.9.3", "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.9.3.tgz", @@ -524,27 +502,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/service-bus/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/service-bus/node_modules/@azure/core-util": { - "version": "1.3.2", - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@azure/storage-blob": { "version": "12.17.0", "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.17.0.tgz", @@ -563,38 +520,16 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/storage-blob/node_modules/@azure/core-http": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@azure/storage-blob/node_modules/xml2js": { - "version": "0.5.0", - "license": "MIT", + "node_modules/@azure/storage-blob/node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/storage-queue": { @@ -613,107 +548,142 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/storage-queue/node_modules/@azure/core-http": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@azure/storage-queue/node_modules/xml2js": { - "version": "0.5.0", - "license": "MIT", + "node_modules/@azure/storage-queue/node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=12.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.21.4", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.21.7", + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, - "node_modules/@babel/core": { - "version": "7.21.8", + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "node": ">=4" } }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.21.5", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.21.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -723,102 +693,108 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.5", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.21.5", + "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, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", + "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, - "license": "MIT", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.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", + "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, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.5", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-simple-access": "^7.21.5", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-plugin-utils": { @@ -831,69 +807,76 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.21.5", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.21.5" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", + "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, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "license": "MIT", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "license": "MIT", + "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==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.5", + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", + "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -902,8 +885,9 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -913,8 +897,9 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -924,39 +909,29 @@ "node": ">=4" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -965,8 +940,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.8", - "license": "MIT", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -976,8 +952,9 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -987,8 +964,9 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -998,8 +976,9 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -1009,8 +988,9 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1020,8 +1000,9 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1046,8 +1027,9 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1057,8 +1039,9 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1068,8 +1051,9 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1079,8 +1063,9 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1090,8 +1075,9 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1101,8 +1087,9 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1112,8 +1099,9 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1140,32 +1128,34 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", - "debug": "^4.1.0", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@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.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -1174,18 +1164,20 @@ }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.21.5", - "license": "MIT", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1327,15 +1319,15 @@ "dev": true }, "node_modules/@cspell/dict-companies": { - "version": "3.0.29", - "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.0.29.tgz", - "integrity": "sha512-F/8XnkqjU7jmSDAcD3LSSX+WxCVUWPssqlO4lzGMIK3MNIUt+d48eSIt3pFAIB/Z9y0ojoLHUtWX9HJ1ZtGrXQ==", + "version": "3.0.31", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.0.31.tgz", + "integrity": "sha512-hKVpV/lcGKP4/DpEPS8P4osPvFH/YVLJaDn9cBIOH6/HSmL5LbFgJNKpMGaYRbhm2FEX56MKE3yn/MNeNYuesQ==", "dev": true }, "node_modules/@cspell/dict-cpp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.1.0.tgz", - "integrity": "sha512-23gd41gsFhXYvVMYXiXOQlYp8othU2JjB6JbH2sWHlmwokiCG9yuWwrN/nVfrt45fzq/VyAurl58AXfx7ctAJA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.1.1.tgz", + "integrity": "sha512-Qy9fNsR/5RcQ6G85gDKFjvzh0AdgAilLQeSXPtqY21Fx1kCjUqdVVJYMmHUREgcxH6ptAxtn5knTWU4PIhQtOw==", "dev": true }, "node_modules/@cspell/dict-cryptocurrencies": { @@ -1435,9 +1427,9 @@ "dev": true }, "node_modules/@cspell/dict-gaming-terms": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.0.4.tgz", - "integrity": "sha512-hbDduNXlk4AOY0wFxcDMWBPpm34rpqJBeqaySeoUH70eKxpxm+dvjpoRLJgyu0TmymEICCQSl6lAHTHSDiWKZg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.0.5.tgz", + "integrity": "sha512-C3riccZDD3d9caJQQs1+MPfrUrQ+0KHdlj9iUR1QD92FgTOF6UxoBpvHUUZ9YSezslcmpFQK4xQQ5FUGS7uWfw==", "dev": true }, "node_modules/@cspell/dict-git": { @@ -1513,9 +1505,9 @@ "dev": true }, "node_modules/@cspell/dict-npm": { - "version": "5.0.14", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.0.14.tgz", - "integrity": "sha512-k0kC7/W2qG5YII+SW6s+JtvKrkZg651vizi5dv/5G2HmJaeLNgDqBVeeDk/uV+ntBorM66XG4BPMjSxoaIlC5w==", + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.0.15.tgz", + "integrity": "sha512-sX0X5YWNW54F4baW7b5JJB6705OCBIZtUqjOghlJNORS5No7QY1IX1zc5FxNNu4gsaCZITAmfMi4ityXEsEThA==", "dev": true }, "node_modules/@cspell/dict-php": { @@ -1558,9 +1550,9 @@ "dev": true }, "node_modules/@cspell/dict-rust": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.1.tgz", - "integrity": "sha512-xJSSzHDK2z6lSVaOmMxl3PTOtfoffaxMo7fTcbZUF+SCJzfKbO6vnN9TCGX2sx1RHFDz66Js6goz6SAZQdOwaw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.2.tgz", + "integrity": "sha512-RhziKDrklzOntxAbY3AvNR58wnFGIo3YS8+dNeLY36GFuWOvXDHFStYw5Pod4f/VXbO/+1tXtywCC4zWfB2p1w==", "dev": true }, "node_modules/@cspell/dict-scala": { @@ -1570,9 +1562,9 @@ "dev": true }, "node_modules/@cspell/dict-software-terms": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-3.3.15.tgz", - "integrity": "sha512-1qqMGFi1TUNq9gQj4FTLPTlqVzQLXrj80MsKoXVpysr+823kMWesQAjqHiPg+MYsQ3DlTcpGWcjq/EbYonqueQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-3.3.16.tgz", + "integrity": "sha512-ixorEP80LGxAU+ODVSn/CYIDjV0XAlZ2VrBu7CT+PwUFJ7h8o3JX1ywKB4qnt0hHru3JjWFtBoBThmZdrXnREQ==", "dev": true }, "node_modules/@cspell/dict-sql": { @@ -1628,8 +1620,9 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -1639,8 +1632,9 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1648,8 +1642,9 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -1692,6 +1687,28 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { "version": "8.56.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", @@ -1703,37 +1720,44 @@ }, "node_modules/@hapi/boom": { "version": "10.0.1", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-10.0.1.tgz", + "integrity": "sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==", "dependencies": { "@hapi/hoek": "^11.0.2" } }, "node_modules/@hapi/boom/node_modules/@hapi/hoek": { - "version": "11.0.2", - "license": "BSD-3-Clause" + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz", + "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==" }, "node_modules/@hapi/bourne": { "version": "3.0.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-3.0.0.tgz", + "integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==" }, "node_modules/@hapi/hoek": { "version": "10.0.1", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-10.0.1.tgz", + "integrity": "sha512-CvlW7jmOhWzuqOqiJQ3rQVLMcREh0eel4IBnxDx2FAcK8g7qoJRQK4L1CPBASoCY6y8e6zuCy3f2g+HWdkzcMw==" }, "node_modules/@hapi/topo": { "version": "5.1.0", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@hapi/topo/node_modules/@hapi/hoek": { "version": "9.3.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "node_modules/@hapi/wreck": { "version": "18.0.1", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-18.0.1.tgz", + "integrity": "sha512-OLHER70+rZxvDl75xq3xXOfd3e8XIvz8fWY0dqg92UvhZ29zo24vQgfqgHSYhB5ZiuFpSLeriOisAlxAo/1jWg==", "dependencies": { "@hapi/boom": "^10.0.1", "@hapi/bourne": "^3.0.0", @@ -1741,27 +1765,51 @@ } }, "node_modules/@hapi/wreck/node_modules/@hapi/hoek": { - "version": "11.0.2", - "license": "BSD-3-Clause" + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz", + "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -1771,9 +1819,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@isaacs/cliui": { @@ -1793,18 +1841,6 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", @@ -1840,21 +1876,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -1874,8 +1895,9 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -1889,16 +1911,18 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -1909,8 +1933,9 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1921,8 +1946,9 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -1932,8 +1958,9 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -1946,8 +1973,9 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -1957,8 +1985,9 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -1980,6 +2009,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/@jest/core": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", @@ -2027,35 +2105,105 @@ } } }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "node_modules/@jest/core/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/expect-utils": { + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", @@ -2142,20 +2290,74 @@ } } }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", - "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "node_modules/@jest/reporters/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/@jest/schemas": { @@ -2240,6 +2442,68 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/@jest/types": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", @@ -2257,10 +2521,60 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2271,48 +2585,49 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true, - "license": "MIT" - }, "node_modules/@microsoft/applicationinsights-web-snippet": { "version": "1.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-snippet/-/applicationinsights-web-snippet-1.0.1.tgz", + "integrity": "sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2323,16 +2638,18 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2360,14 +2677,6 @@ "node": ">= 18" } }, - "node_modules/@octokit/auth-app/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/@octokit/auth-oauth-app": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz", @@ -2593,26 +2902,19 @@ } }, "node_modules/@opentelemetry/api": { - "version": "1.4.1", - "license": "Apache-2.0", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", + "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==", "engines": { "node": ">=8.0.0" } }, "node_modules/@opentelemetry/core": { -<<<<<<< HEAD - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.18.1.tgz", - "integrity": "sha512-kvnUqezHMhsQvdsnhnqTNfAJs3ox/isB0SVrM1dhVFw7SsB7TstuVa6fgWnN2GdPyilIFLUvvbTZoVRmx6eiRg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.20.0.tgz", + "integrity": "sha512-lSRvk5AIdD6CtgYJcJXh0wGibQ3S/8bC2qbqKs9wK8e0K1tsWV6YkGFOqVc+jIRlCbZoIBeZzDe5UI+vb94uvg==", "dependencies": { - "@opentelemetry/semantic-conventions": "1.18.1" -======= - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.19.0.tgz", - "integrity": "sha512-w42AukJh3TP8R0IZZOVJVM/kMWu8g+lm4LzT70WtuKqhwq7KVhcDzZZuZinWZa6TtQCl7Smt2wolEYzpHabOgw==", - "dependencies": { - "@opentelemetry/semantic-conventions": "1.19.0" ->>>>>>> upstream/main + "@opentelemetry/semantic-conventions": "1.20.0" }, "engines": { "node": ">=14" @@ -2640,21 +2942,12 @@ } }, "node_modules/@opentelemetry/resources": { -<<<<<<< HEAD - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.18.1.tgz", - "integrity": "sha512-JjbcQLYMttXcIabflLRuaw5oof5gToYV9fuXbcsoOeQ0BlbwUn6DAZi++PNsSz2jjPeASfDls10iaO/8BRIPRA==", - "dependencies": { - "@opentelemetry/core": "1.18.1", - "@opentelemetry/semantic-conventions": "1.18.1" -======= - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.19.0.tgz", - "integrity": "sha512-RgxvKuuMOf7nctOeOvpDjt2BpZvZGr9Y0vf7eGtY5XYZPkh2p7e2qub1S2IArdBMf9kEbz0SfycqCviOu9isqg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.20.0.tgz", + "integrity": "sha512-nOpV0vGegSq+9ze2cEDvO3BMA5pGBhmhKZiAlj+xQZjiEjPmJtdHIuBLRvptu2ahcbFJw85gIB9BYHZOvZK1JQ==", "dependencies": { - "@opentelemetry/core": "1.19.0", - "@opentelemetry/semantic-conventions": "1.19.0" ->>>>>>> upstream/main + "@opentelemetry/core": "1.20.0", + "@opentelemetry/semantic-conventions": "1.20.0" }, "engines": { "node": ">=14" @@ -2664,23 +2957,13 @@ } }, "node_modules/@opentelemetry/sdk-trace-base": { -<<<<<<< HEAD - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.18.1.tgz", - "integrity": "sha512-tRHfDxN5dO+nop78EWJpzZwHsN1ewrZRVVwo03VJa3JQZxToRDH29/+MB24+yoa+IArerdr7INFJiX/iN4gjqg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.20.0.tgz", + "integrity": "sha512-BAIZ0hUgnhdb3OBQjn1FKGz/Iwie4l+uOMKklP7FGh7PTqEAbbzDNMJKaZQh6KepF7Fq+CZDRKslD3yrYy2Tzw==", "dependencies": { - "@opentelemetry/core": "1.18.1", - "@opentelemetry/resources": "1.18.1", - "@opentelemetry/semantic-conventions": "1.18.1" -======= - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.19.0.tgz", - "integrity": "sha512-+IRvUm+huJn2KqfFW3yW/cjvRwJ8Q7FzYHoUNx5Fr0Lws0LxjMJG1uVB8HDpLwm7mg5XXH2M5MF+0jj5cM8BpQ==", - "dependencies": { - "@opentelemetry/core": "1.19.0", - "@opentelemetry/resources": "1.19.0", - "@opentelemetry/semantic-conventions": "1.19.0" ->>>>>>> upstream/main + "@opentelemetry/core": "1.20.0", + "@opentelemetry/resources": "1.20.0", + "@opentelemetry/semantic-conventions": "1.20.0" }, "engines": { "node": ">=14" @@ -2690,15 +2973,9 @@ } }, "node_modules/@opentelemetry/semantic-conventions": { -<<<<<<< HEAD - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.18.1.tgz", - "integrity": "sha512-+NLGHr6VZwcgE/2lw8zDIufOCGnzsA5CbQIMleXZTrgkBd0TanCX+MiDYJ1TOS4KL/Tqk0nFRxawnaYr6pkZkA==", -======= - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.19.0.tgz", - "integrity": "sha512-14jRpC8f5c0gPSwoZ7SbEJni1PqI+AhAE8m1bMz6v+RPM4OlP1PT2UHBJj5Qh/ALLPjhVU/aZUK3YyjTUqqQVg==", ->>>>>>> upstream/main + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.20.0.tgz", + "integrity": "sha512-3zLJJCgTKYpbqFX8drl8hOCHtdchELC+kGqlVcV4mHW1DiElTtv1Nt9EKBptTd1IfL56QkuYnWJ3DeHd2Gtu/A==", "engines": { "node": ">=14" } @@ -2714,9 +2991,9 @@ } }, "node_modules/@pkgr/core": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.0.tgz", - "integrity": "sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", "dev": true, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" @@ -2735,7 +3012,8 @@ }, "node_modules/@redis/bloom": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -2787,22 +3065,26 @@ }, "node_modules/@sideway/address": { "version": "4.1.4", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@sideway/address/node_modules/@hapi/hoek": { "version": "9.3.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "node_modules/@sideway/formula": { "version": "3.0.1", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", @@ -2842,15 +3124,17 @@ }, "node_modules/@tootallnate/once": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "engines": { "node": ">= 10" } }, "node_modules/@ts-morph/common": { "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.12.3.tgz", + "integrity": "sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==", "dev": true, - "license": "MIT", "dependencies": { "fast-glob": "^3.2.7", "minimatch": "^3.0.4", @@ -2858,25 +3142,51 @@ "path-browserify": "^1.0.1" } }, + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true }, "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "dev": true, - "license": "MIT" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -2892,9 +3202,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -2911,17 +3221,18 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { - "version": "1.19.2", - "license": "MIT", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -2933,8 +3244,9 @@ "integrity": "sha512-ZYbcE2x7yrvNFJiU7xJGrpF/ihpkM7zKgw8bha3LNJSesvTtUNxbpzaT7WXBIryf6jovisrxTBvymxMeLLj1Mg==" }, "node_modules/@types/connect": { - "version": "3.4.35", - "license": "MIT", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dependencies": { "@types/node": "*" } @@ -2969,8 +3281,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.34", - "license": "MIT", + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -2996,30 +3309,39 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, "node_modules/@types/is-buffer": { - "version": "2.0.0", - "license": "MIT", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/is-buffer/-/is-buffer-2.0.2.tgz", + "integrity": "sha512-G6OXy83Va+xEo8XgqAJYOuvOMxeey9xM5XKkvwJNmN8rVdcB+r15HvHsG86hl86JvU0y1aa7Z2ERkNFYWw9ySg==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "dev": true, - "license": "MIT" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, - "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.1", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } @@ -3041,8 +3363,9 @@ "dev": true }, "node_modules/@types/jsonwebtoken": { - "version": "9.0.2", - "license": "MIT", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", "dependencies": { "@types/node": "*" } @@ -3066,8 +3389,9 @@ "dev": true }, "node_modules/@types/mime": { - "version": "1.3.2", - "license": "MIT" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/morgan": { "version": "1.9.9", @@ -3079,9 +3403,10 @@ } }, "node_modules/@types/ms": { - "version": "0.7.31", - "dev": true, - "license": "MIT" + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true }, "node_modules/@types/node": { "version": "20.11.0", @@ -3092,23 +3417,12 @@ } }, "node_modules/@types/node-fetch": { - "version": "2.6.1", - "license": "MIT", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", "dependencies": { "@types/node": "*", - "form-data": "^3.0.0" - } - }, - "node_modules/@types/node-fetch/node_modules/form-data": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" + "form-data": "^4.0.0" } }, "node_modules/@types/node-jose": { @@ -3121,9 +3435,10 @@ } }, "node_modules/@types/oauth": { - "version": "0.9.1", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.4.tgz", + "integrity": "sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3135,9 +3450,10 @@ "dev": true }, "node_modules/@types/parse-json": { - "version": "4.0.0", - "dev": true, - "license": "MIT" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true }, "node_modules/@types/passport": { "version": "1.0.16", @@ -3170,9 +3486,10 @@ } }, "node_modules/@types/passport-oauth2": { - "version": "1.4.11", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.15.tgz", + "integrity": "sha512-9cUTP/HStNSZmhxXGuRrBJfEWzIEJRub2eyJu3CvkA+8HAMc9W3aKdFhVq+Qz1hi42qn+GvSAnz3zwacDSYWpw==", "dev": true, - "license": "MIT", "dependencies": { "@types/express": "*", "@types/oauth": "*", @@ -3190,58 +3507,6 @@ "pg-types": "^4.0.1" } }, - "node_modules/@types/pg/node_modules/pg-types": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "pg-numeric": "1.0.2", - "postgres-array": "~3.0.1", - "postgres-bytea": "~3.0.0", - "postgres-date": "~2.0.1", - "postgres-interval": "^3.0.0", - "postgres-range": "^1.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@types/pg/node_modules/postgres-array": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/@types/pg/node_modules/postgres-bytea": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "obuf": "~1.1.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/pg/node_modules/postgres-date": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/@types/pg/node_modules/postgres-interval": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", @@ -3249,12 +3514,14 @@ "dev": true }, "node_modules/@types/qs": { - "version": "6.9.7", - "license": "MIT" + "version": "6.9.11", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "license": "MIT" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/recursive-readdir": { "version": "2.2.4", @@ -3272,18 +3539,21 @@ "dev": true }, "node_modules/@types/send": { - "version": "0.17.1", - "license": "MIT", + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.13.10", - "license": "MIT", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dependencies": { - "@types/mime": "^1", + "@types/http-errors": "*", + "@types/mime": "*", "@types/node": "*" } }, @@ -3299,13 +3569,15 @@ "dev": true }, "node_modules/@types/stack-utils": { - "version": "2.0.1", - "dev": true, - "license": "MIT" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true }, "node_modules/@types/tunnel": { "version": "0.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", + "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", "dependencies": { "@types/node": "*" } @@ -3317,17 +3589,19 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.24", + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, - "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "dev": true, - "license": "MIT" + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.18.1", @@ -3477,30 +3751,6 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.18.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", @@ -3551,7 +3801,8 @@ }, "node_modules/accepts": { "version": "1.3.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -3561,9 +3812,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "bin": { "acorn": "bin/acorn" }, @@ -3589,16 +3840,18 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { "version": "6.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dependencies": { "debug": "4" }, @@ -3650,22 +3903,24 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.1", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { - "version": "4.3.0", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" @@ -3686,7 +3941,8 @@ }, "node_modules/app-root-path": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", "engines": { "node": ">= 6.0.0" } @@ -3722,8 +3978,6 @@ } } }, -<<<<<<< HEAD -======= "node_modules/applicationinsights/node_modules/@azure/core-rest-pipeline": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz", @@ -3756,27 +4010,21 @@ "node": ">=14.0.0" } }, - "node_modules/applicationinsights/node_modules/@opentelemetry/api": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", - "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==", - "engines": { - "node": ">=8.0.0" - } - }, ->>>>>>> upstream/main "node_modules/arg": { "version": "4.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "node_modules/argparse": { "version": "2.0.1", - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-flatten": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/array-timsort": { "version": "1.0.3", @@ -3795,15 +4043,23 @@ }, "node_modules/asap": { "version": "2.0.6", - "license": "MIT" + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "node_modules/assert-never": { "version": "1.2.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, "node_modules/async-hook-jl": { "version": "1.7.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", + "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", "dependencies": { "stack-chain": "^1.3.7" }, @@ -3813,7 +4069,8 @@ }, "node_modules/async-listener": { "version": "0.6.10", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", "dependencies": { "semver": "^5.3.0", "shimmer": "^1.1.0" @@ -3823,15 +4080,17 @@ } }, "node_modules/async-listener/node_modules/semver": { - "version": "5.7.1", - "license": "ISC", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "bin": { "semver": "bin/semver" } }, "node_modules/async-prompt": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/async-prompt/-/async-prompt-1.0.1.tgz", + "integrity": "sha512-AdeC4NCuD0RxpbWm6pexY/AWMasHzMe+/zvdxdsAvpMmuz4in7N8OrKP7YzbRPYhUS+hibZNdUablgfE6Uj8UA==", "dependencies": { "keypress": "~0.2.1" }, @@ -3841,7 +4100,8 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -3885,10 +4145,60 @@ "@babel/core": "^7.8.0" } }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -3900,6 +4210,31 @@ "node": ">=8" } }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", @@ -3917,8 +4252,9 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -3955,7 +4291,8 @@ }, "node_modules/babel-walk": { "version": "3.0.0-canary-5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", "dependencies": { "@babel/types": "^7.9.6" }, @@ -3965,10 +4302,13 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -3982,19 +4322,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/base64url": { "version": "3.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", "engines": { "node": ">=6.0.0" } }, "node_modules/basic-auth": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "dependencies": { "safe-buffer": "5.1.2" }, @@ -4003,24 +4344,14 @@ } }, "node_modules/before-after-hook": { - "version": "2.2.2", - "license": "Apache-2.0" - }, -<<<<<<< HEAD - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "dev": true, - "engines": { - "node": ">=0.6" - } + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" }, -======= ->>>>>>> upstream/main "node_modules/body-parser": { "version": "1.20.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -4042,37 +4373,31 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "license": "MIT" - }, - "node_modules/body-parser/node_modules/on-finished": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "license": "MIT", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -4081,7 +4406,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "funding": [ { @@ -4091,14 +4418,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -4109,8 +4439,9 @@ }, "node_modules/bs-logger": { "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, - "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -4134,6 +4465,8 @@ }, "node_modules/buffer": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -4148,7 +4481,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -4156,7 +4488,8 @@ }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "node_modules/buffer-from": { "version": "1.1.2", @@ -4166,7 +4499,8 @@ }, "node_modules/buffer-writer": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", "engines": { "node": ">=4" } @@ -4185,18 +4519,20 @@ }, "node_modules/builtins": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, - "license": "MIT", "dependencies": { "semver": "^7.0.0" } }, "node_modules/bunyan": { "version": "1.8.15", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", + "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", "engines": [ "node >=0.10.0" ], - "license": "MIT", "bin": { "bunyan": "bin/bunyan" }, @@ -4209,14 +4545,16 @@ }, "node_modules/bytes": { "version": "3.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } }, "node_modules/cache-manager": { "version": "3.6.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-3.6.3.tgz", + "integrity": "sha512-dS4DnV6c6cQcVH5OxzIU1XZaACXwvVIiUPkFytnRmLOACuBGv3GQgRQ1RJGRRw4/9DF14ZK2RFlZu1TUgDniMg==", "dependencies": { "async": "3.2.3", "lodash.clonedeep": "^4.5.0", @@ -4225,7 +4563,19 @@ }, "node_modules/cache-manager/node_modules/async": { "version": "3.2.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + }, + "node_modules/cache-manager/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, "node_modules/call-bind": { "version": "1.0.5", @@ -4242,22 +4592,26 @@ }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001486", + "version": "1.0.30001579", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", + "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==", "dev": true, "funding": [ { @@ -4272,19 +4626,15 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/chalk": { - "version": "4.1.2", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" @@ -4305,18 +4655,6 @@ "url": "https://github.com/chalk/chalk-template?sponsor=1" } }, - "node_modules/chalk-template/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -4328,13 +4666,16 @@ }, "node_modules/character-parser": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", "dependencies": { "is-regex": "^1.0.3" } }, "node_modules/ci-info": { - "version": "3.8.0", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -4342,7 +4683,6 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], - "license": "MIT", "engines": { "node": ">=8" } @@ -4413,6 +4753,48 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -4442,6 +4824,18 @@ "node": ">=8" } }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -4461,7 +4855,8 @@ }, "node_modules/cls-hooked": { "version": "4.2.2", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", + "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", "dependencies": { "async-hook-jl": "^1.7.6", "emitter-listener": "^1.0.1", @@ -4472,15 +4867,17 @@ } }, "node_modules/cls-hooked/node_modules/semver": { - "version": "5.7.1", - "license": "ISC", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "bin": { "semver": "bin/semver" } }, "node_modules/cluster-key-slot": { "version": "1.1.2", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", "engines": { "node": ">=0.10.0" } @@ -4497,8 +4894,9 @@ }, "node_modules/code-block-writer": { "version": "11.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", + "integrity": "sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==", + "dev": true }, "node_modules/collect-v8-coverage": { "version": "1.0.2", @@ -4508,23 +4906,23 @@ }, "node_modules/color-contrast-checker": { "version": "2.1.0", - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/color-contrast-checker/-/color-contrast-checker-2.1.0.tgz", + "integrity": "sha512-6Y0aIEej3pwZTVlicIqVzhO6T4izDWouaIXnYoDdTuFFAMQ9nnN0dgHNP9J94jRnH6asjPq1/wzUKxwoNbWtRQ==" }, "node_modules/color-convert": { - "version": "2.0.1", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "color-name": "1.1.3" } }, "node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/colorette": { "version": "2.0.20", @@ -4534,7 +4932,8 @@ }, "node_modules/combined-stream": { "version": "1.0.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4569,7 +4968,8 @@ }, "node_modules/compressible": { "version": "2.0.18", - "license": "MIT", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -4579,7 +4979,8 @@ }, "node_modules/compression": { "version": "1.7.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -4595,25 +4996,29 @@ }, "node_modules/compression/node_modules/bytes": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "engines": { "node": ">= 0.8" } }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/concat-map": { "version": "0.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/configstore": { "version": "6.0.0", @@ -4634,21 +5039,10 @@ "url": "https://github.com/yeoman/configstore?sponsor=1" } }, - "node_modules/configstore/node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, "node_modules/connect-redis": { "version": "7.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-7.1.0.tgz", + "integrity": "sha512-UaqO1EirWjON2ENsyau7N5lbkrdYBpS6mYlXSeff/OYXsd6EGZ+SXSmNPoljL2PSua8fgjAEaldSA73PMZQ9Eg==", "engines": { "node": ">=16" }, @@ -4658,7 +5052,8 @@ }, "node_modules/constantinople": { "version": "4.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", "dependencies": { "@babel/parser": "^7.6.0", "@babel/types": "^7.6.1" @@ -4666,7 +5061,8 @@ }, "node_modules/content-disposition": { "version": "0.5.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dependencies": { "safe-buffer": "5.2.1" }, @@ -4676,6 +5072,8 @@ }, "node_modules/content-disposition/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -4689,19 +5087,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/content-type": { "version": "1.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { "node": ">= 0.6" } }, "node_modules/continuation-local-storage": { "version": "3.2.1", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", "dependencies": { "async-listener": "^0.6.0", "emitter-listener": "^1.1.1" @@ -4709,19 +5108,22 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true }, "node_modules/cookie": { "version": "0.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "license": "MIT" + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-util-is": { "version": "1.0.3", @@ -4731,7 +5133,8 @@ }, "node_modules/cors": { "version": "2.8.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -4740,6 +5143,31 @@ "node": ">= 0.10" } }, + "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/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -4761,10 +5189,60 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/create-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/create-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/create-require": { "version": "1.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -4975,331 +5453,58 @@ "node": ">=18" } }, - "node_modules/cspell/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": ">=12" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/cspell/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } } }, - "node_modules/cspell/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, + "node_modules/deeks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/deeks/-/deeks-2.6.1.tgz", + "integrity": "sha512-PZrpz5xLo2JPZa3L+kqMMMdZU5pRwMysTM1xd6pLhNtgQw4Iq3wbF2QWaQTVh+HRq9Yg4rcjDIJ+scfGLxmsjQ==", "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 12" } }, - "node_modules/cspell/node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "engines": { - "node": ">=16.0.0" + "node": ">=0.10.0" } }, - "node_modules/cspell/node_modules/flat-cache": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.0.tgz", - "integrity": "sha512-EryKbCE/wxpxKniQlyas6PY1I9vwtF3uCBweX+N8KYTCn3Y12RTGtQAJ/bd5pl7kxUAc8v/R3Ake/N17OZiFqA==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/cspell/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cspell/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cspell/node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cspell/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", - "dev": true, - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deeks": { - "version": "2.6.0", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, -<<<<<<< HEAD - "node_modules/default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "dependencies": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/default-browser/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/default-browser/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, -======= ->>>>>>> upstream/main "node_modules/define-data-property": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", @@ -5315,32 +5520,37 @@ }, "node_modules/define-lazy-prop": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "engines": { "node": ">=8" } }, "node_modules/delayed-stream": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { "node": ">= 0.8" } }, "node_modules/deprecation": { "version": "2.3.1", - "license": "ISC" + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" }, "node_modules/destroy": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -5373,8 +5583,9 @@ }, "node_modules/diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -5401,16 +5612,18 @@ } }, "node_modules/doc-path": { - "version": "3.0.6", - "license": "MIT", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-3.1.0.tgz", + "integrity": "sha512-Pv2hLQbUM8du5681lTWIYk0OtVBmNhMAeZNGeFhMMJBIR89Nw4XesBwee1Xtlfk83n71tn0Y6VsJOn4d3qIiTw==", "engines": { "node": ">=12" } }, "node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -5420,7 +5633,8 @@ }, "node_modules/doctypes": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" }, "node_modules/dot-prop": { "version": "6.0.1", @@ -5450,8 +5664,9 @@ }, "node_modules/dtrace-provider": { "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", "hasInstallScript": true, - "license": "BSD-2-Clause", "optional": true, "dependencies": { "nan": "^2.14.0" @@ -5468,23 +5683,27 @@ }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "dependencies": { "safe-buffer": "^5.0.1" } }, "node_modules/ee-first": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.392", - "dev": true, - "license": "ISC" + "version": "1.4.639", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.639.tgz", + "integrity": "sha512-CkKf3ZUVZchr+zDpAlNLEEy2NJJ9T64ULWaDgy3THXXlPVPkLu3VOs9Bac44nebVtdwl2geSj6AxTtGDOxoXhg==", + "dev": true }, "node_modules/emitter-listener": { "version": "1.1.2", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", "dependencies": { "shimmer": "^1.2.0" } @@ -5509,7 +5728,8 @@ }, "node_modules/encodeurl": { "version": "1.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } @@ -5528,31 +5748,36 @@ }, "node_modules/error-ex": { "version": "1.3.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es6-promise": { "version": "4.2.8", - "license": "MIT" + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "node_modules/escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -5687,17 +5912,39 @@ "eslint": ">=7.0.0" } }, - "node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint-plugin-prettier" @@ -5745,6 +5992,139 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/eslint/node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -5764,8 +6144,9 @@ }, "node_modules/esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -5776,8 +6157,9 @@ }, "node_modules/esquery": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -5808,15 +6190,17 @@ }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } @@ -5829,7 +6213,8 @@ }, "node_modules/events": { "version": "3.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "engines": { "node": ">=0.8.x" } @@ -5884,7 +6269,8 @@ }, "node_modules/express": { "version": "4.18.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -5929,7 +6315,8 @@ }, "node_modules/express-session": { "version": "1.17.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", "dependencies": { "cookie": "0.4.2", "cookie-signature": "1.0.6", @@ -5946,24 +6333,29 @@ }, "node_modules/express-session/node_modules/cookie": { "version": "0.4.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "engines": { "node": ">= 0.6" } }, "node_modules/express-session/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/express-session/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express-session/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -5977,16 +6369,17 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/express-sslify": { "version": "1.2.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/express-sslify/-/express-sslify-1.2.0.tgz", + "integrity": "sha512-OOf2B3MxAVjEXPPWl4Z19wA2oMH+RCULJVhejPwuhiDDClr9QczZz5ycABLSnnN+oY8JcLs32ghs9cxOj0vi+w==" }, "node_modules/express/node_modules/body-parser": { "version": "1.20.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -6008,28 +6401,21 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "license": "MIT" - }, - "node_modules/express/node_modules/on-finished": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express/node_modules/raw-body": { "version": "2.5.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -6042,6 +6428,8 @@ }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -6055,8 +6443,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -6065,9 +6452,10 @@ "dev": true }, "node_modules/fast-diff": { - "version": "1.2.0", - "dev": true, - "license": "Apache-2.0" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true }, "node_modules/fast-equals": { "version": "5.0.1", @@ -6096,8 +6484,9 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -6107,7 +6496,8 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -6117,21 +6507,23 @@ }, "node_modules/fast-safe-stringify": { "version": "2.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "node_modules/fast-xml-parser": { - "version": "4.2.2", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.3.tgz", + "integrity": "sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg==", "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" } ], - "license": "MIT", "dependencies": { "strnum": "^1.0.5" }, @@ -6140,9 +6532,10 @@ } }, "node_modules/fastq": { - "version": "1.15.0", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -6157,24 +6550,27 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, - "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-size": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/file-size/-/file-size-1.0.0.tgz", + "integrity": "sha512-tLIdonWTpABkU6Axg2yGChYdrOsy4V8xcm0IcyAP8fSsu6jiXLm5pgs083e4sq5fzNRZuAYolUbZyYmPvCKfwQ==" }, "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==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6184,7 +6580,8 @@ }, "node_modules/finalhandler": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -6200,29 +6597,22 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "license": "MIT" - }, - "node_modules/finalhandler/node_modules/on-finished": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -6247,17 +6637,17 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.0.tgz", + "integrity": "sha512-EryKbCE/wxpxKniQlyas6PY1I9vwtF3uCBweX+N8KYTCn3Y12RTGtQAJ/bd5pl7kxUAc8v/R3Ake/N17OZiFqA==", "dev": true, "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4", + "rimraf": "^5.0.5" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { @@ -6267,20 +6657,15 @@ "dev": true }, "node_modules/follow-redirects": { -<<<<<<< HEAD - "version": "1.15.2", -======= - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", ->>>>>>> upstream/main + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -6328,7 +6713,8 @@ }, "node_modules/form-data": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -6340,21 +6726,24 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "version": "0.5.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } }, "node_modules/fs.realpath": { "version": "1.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -6380,7 +6769,8 @@ }, "node_modules/generic-pool": { "version": "3.9.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", "engines": { "node": ">= 4" } @@ -6396,8 +6786,9 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -6439,8 +6830,9 @@ }, "node_modules/get-package-type": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -6483,16 +6875,18 @@ }, "node_modules/github-username-regex": { "version": "1.0.0", - "license": "CC0-1.0" + "resolved": "https://registry.npmjs.org/github-username-regex/-/github-username-regex-1.0.0.tgz", + "integrity": "sha512-EqDVkN0/5MQyDPOSDLInVRRXdeISRfcN1UW/1FUqD2knV1HHw8DndMB3UPNn5lO51DvRnjzbLXwWqNNV86PLOw==" }, "node_modules/glob": { - "version": "7.2.0", - "license": "ISC", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -6505,8 +6899,9 @@ }, "node_modules/glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -6514,6 +6909,26 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/global-directory": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", @@ -6576,18 +6991,21 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "license": "ISC" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/graphemer": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -6625,7 +7043,8 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, @@ -6635,7 +7054,8 @@ }, "node_modules/has-tostringtag": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dependencies": { "has-symbols": "^1.0.2" }, @@ -6659,7 +7079,8 @@ }, "node_modules/hsts": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", + "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", "dependencies": { "depd": "2.0.0" }, @@ -6675,7 +7096,8 @@ }, "node_modules/http-errors": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -6689,7 +7111,8 @@ }, "node_modules/http-proxy-agent": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -6700,8 +7123,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "license": "MIT", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dependencies": { "agent-base": "6", "debug": "4" @@ -6721,8 +7145,9 @@ }, "node_modules/husky": { "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true, - "license": "MIT", "bin": { "husky": "lib/bin.js" }, @@ -6735,7 +7160,8 @@ }, "node_modules/iconv-lite": { "version": "0.4.24", - "license": "MIT", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -6745,6 +7171,8 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -6758,8 +7186,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/ignore": { "version": "5.3.0", @@ -6772,8 +7199,9 @@ }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6787,8 +7215,9 @@ }, "node_modules/import-fresh/node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -6798,8 +7227,9 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -6846,15 +7276,17 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", - "license": "ISC", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6862,7 +7294,8 @@ }, "node_modules/inherits": { "version": "2.0.4", - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "4.1.1", @@ -6875,7 +7308,8 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "engines": { "node": ">= 0.10" } @@ -6897,10 +7331,13 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-buffer": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "funding": [ { "type": "github", @@ -6915,7 +7352,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "engines": { "node": ">=4" } @@ -6959,7 +7395,8 @@ }, "node_modules/is-docker": { "version": "2.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "bin": { "is-docker": "cli.js" }, @@ -6972,7 +7409,8 @@ }, "node_modules/is-expression": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", "dependencies": { "acorn": "^7.1.1", "object-assign": "^4.1.1" @@ -6980,7 +7418,8 @@ }, "node_modules/is-expression/node_modules/acorn": { "version": "7.4.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "bin": { "acorn": "bin/acorn" }, @@ -6990,8 +7429,9 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7033,8 +7473,9 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -7044,8 +7485,9 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -7061,19 +7503,22 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-promise": { "version": "2.2.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "node_modules/is-regex": { "version": "1.1.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -7119,7 +7564,8 @@ }, "node_modules/is-wsl": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dependencies": { "is-docker": "^2.0.0" }, @@ -7129,38 +7575,33 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/istanbul-lib-report": { @@ -7293,6 +7734,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-cli": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", @@ -7326,6 +7816,55 @@ } } }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-config": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", @@ -7371,6 +7910,55 @@ } } }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -7386,6 +7974,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-docblock": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", @@ -7414,6 +8051,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-environment-node": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", @@ -7467,8 +8153,9 @@ }, "node_modules/jest-junit": { "version": "16.0.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", + "integrity": "sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "mkdirp": "^1.0.4", "strip-ansi": "^6.0.1", @@ -7479,6 +8166,27 @@ "node": ">=10.12.0" } }, + "node_modules/jest-junit/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-junit/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-leak-detector": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", @@ -7507,6 +8215,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-message-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", @@ -7527,9 +8284,58 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "dependencies": { @@ -7600,6 +8406,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-runner": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", @@ -7632,6 +8487,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-runtime": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", @@ -7665,6 +8569,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-snapshot": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", @@ -7696,6 +8649,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", @@ -7713,6 +8715,55 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-validate": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", @@ -7730,6 +8781,21 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -7742,26 +8808,109 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-worker": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", @@ -7792,19 +8941,21 @@ } }, "node_modules/joi": { - "version": "17.9.2", - "license": "BSD-3-Clause", + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.0.tgz", + "integrity": "sha512-HSLsmSmXz+PV9PYoi3p7cgIbj06WnEBNT28n+bbBNcPZXZFqCzzvGqpTBPujx/Z0nh1+KNQPDrNgdmQ8dq0qYw==", "dependencies": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.4", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } }, "node_modules/joi/node_modules/@hapi/hoek": { "version": "9.3.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "node_modules/jose": { "version": "4.15.4", @@ -7816,16 +8967,19 @@ }, "node_modules/js-stringify": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { "argparse": "^2.0.1" }, @@ -7835,12 +8989,14 @@ }, "node_modules/jsbi": { "version": "3.2.5", - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.2.5.tgz", + "integrity": "sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ==" }, "node_modules/jsesc": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -7849,11 +9005,12 @@ } }, "node_modules/json-2-csv": { - "version": "3.18.0", - "license": "MIT", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-3.20.0.tgz", + "integrity": "sha512-IbqUB+yaycVNB/q2fiY5kyRjy5kRiEXqvNvGlxM5L0Bfi0RdvklVHc4t9MfeYF1GsZVpZWDBs9LdWmSjsQ8jvg==", "dependencies": { - "deeks": "2.6.0", - "doc-path": "3.0.6" + "deeks": "2.6.1", + "doc-path": "3.1.0" }, "engines": { "node": ">= 12" @@ -7867,12 +9024,14 @@ }, "node_modules/json-parse-better-errors": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -7882,13 +9041,15 @@ }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/json5": { "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -7898,7 +9059,8 @@ }, "node_modules/jsonc": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jsonc/-/jsonc-2.0.0.tgz", + "integrity": "sha512-B281bLCT2TRMQa+AQUQY5AGcqSOXBOKaYGP4wDzoA/+QswUfN8sODektbPEs9Baq7LGKun5jQbNFpzwGuVYKhw==", "dependencies": { "fast-safe-stringify": "^2.0.6", "graceful-fs": "^4.1.15", @@ -7913,7 +9075,8 @@ }, "node_modules/jsonc/node_modules/mkdirp": { "version": "0.5.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dependencies": { "minimist": "^1.2.6" }, @@ -7923,7 +9086,8 @@ }, "node_modules/jsonc/node_modules/parse-json": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -7955,7 +9119,8 @@ }, "node_modules/jsonwebtoken/node_modules/jwa": { "version": "1.4.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -7964,7 +9129,8 @@ }, "node_modules/jsonwebtoken/node_modules/jws": { "version": "3.2.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" @@ -7980,7 +9146,8 @@ }, "node_modules/jstransformer": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", "dependencies": { "is-promise": "^2.0.0", "promise": "^7.0.1" @@ -7988,7 +9155,8 @@ }, "node_modules/jwa": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -8013,7 +9181,8 @@ }, "node_modules/jws": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" @@ -8021,7 +9190,8 @@ }, "node_modules/keypress": { "version": "0.2.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", + "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==" }, "node_modules/keyv": { "version": "4.5.4", @@ -8043,7 +9213,8 @@ }, "node_modules/language-map": { "version": "1.5.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/language-map/-/language-map-1.5.0.tgz", + "integrity": "sha512-n7gFZpe+DwEAX9cXVTw43i3wiudWDDtSn28RmdnS/HCPr284dQI/SztsamWanRr75oSlKSaGbV2nmWCTzGCoVg==" }, "node_modules/leven": { "version": "3.1.0", @@ -8077,12 +9248,15 @@ } }, "node_modules/limiter": { - "version": "1.1.5" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, "node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "node_modules/linkify-it": { "version": "5.0.0", @@ -8120,18 +9294,6 @@ "url": "https://opencollective.com/lint-staged" } }, - "node_modules/lint-staged/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/lint-staged/node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -8201,9 +9363,9 @@ } }, "node_modules/lint-staged/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, "dependencies": { "path-key": "^4.0.0" @@ -8285,8 +9447,9 @@ }, "node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -8299,11 +9462,13 @@ }, "node_modules/lodash": { "version": "4.17.21", - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, "node_modules/lodash.includes": { "version": "4.3.0", @@ -8337,13 +9502,15 @@ }, "node_modules/lodash.memoize": { "version": "4.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true }, "node_modules/lodash.merge": { "version": "4.6.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "node_modules/lodash.once": { "version": "4.1.1", @@ -8384,18 +9551,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/log-update/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", @@ -8439,21 +9594,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/log-update/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/log-update/node_modules/type-fest": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", @@ -8467,17 +9607,16 @@ } }, "node_modules/long": { - "version": "5.2.0", - "license": "Apache-2.0" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "engines": { - "node": ">=10" + "node": "14 || >=16.14" } }, "node_modules/lru-memoizer": { @@ -8528,8 +9667,9 @@ }, "node_modules/make-error": { "version": "1.3.6", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -8598,8 +9738,9 @@ }, "node_modules/markdownlint-cli2-formatter-default": { "version": "0.0.4", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.4.tgz", + "integrity": "sha512-xm2rM0E+sWgjpPn1EesPXx5hIyrN2ddUnUwnbCsD/ONxYtw3PX6LydvdH6dciWAoFDpwzbHM1TO7uHfcMd6IYg==", "dev": true, - "license": "MIT", "peerDependencies": { "markdownlint-cli2": ">=0.0.4" } @@ -8680,18 +9821,21 @@ }, "node_modules/media-typer": { "version": "0.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } }, "node_modules/memory-cache": { "version": "0.2.0", - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", + "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==" }, "node_modules/merge-descriptors": { "version": "1.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/merge-stream": { "version": "2.0.0", @@ -8701,23 +9845,26 @@ }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/methods": { "version": "1.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -8728,7 +9875,8 @@ }, "node_modules/mime": { "version": "1.6.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "bin": { "mime": "cli.js" }, @@ -8738,14 +9886,16 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { "mime-db": "1.52.0" }, @@ -8763,18 +9913,27 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "license": "ISC", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { - "version": "1.2.6", - "license": "MIT" + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/minipass": { "version": "7.0.4", @@ -8787,8 +9946,9 @@ }, "node_modules/mkdirp": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -8802,21 +9962,17 @@ "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" }, "node_modules/moment": { -<<<<<<< HEAD - "version": "2.29.4", - "license": "MIT", -======= "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", ->>>>>>> upstream/main "engines": { "node": "*" } }, "node_modules/morgan": { "version": "1.10.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", @@ -8830,22 +9986,37 @@ }, "node_modules/morgan/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/morgan/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, "node_modules/ms": { "version": "2.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mv": { "version": "2.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", "optional": true, "dependencies": { "mkdirp": "~0.5.1", @@ -8856,9 +10027,20 @@ "node": ">=0.8.0" } }, + "node_modules/mv/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/mv/node_modules/glob": { "version": "6.0.4", - "license": "ISC", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", "optional": true, "dependencies": { "inflight": "^1.0.4", @@ -8871,9 +10053,22 @@ "node": "*" } }, + "node_modules/mv/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/mv/node_modules/mkdirp": { "version": "0.5.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "optional": true, "dependencies": { "minimist": "^1.2.6" @@ -8884,7 +10079,8 @@ }, "node_modules/mv/node_modules/rimraf": { "version": "2.4.5", - "license": "ISC", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", "optional": true, "dependencies": { "glob": "^6.0.1" @@ -8894,18 +10090,21 @@ } }, "node_modules/nan": { - "version": "2.15.0", - "license": "MIT", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", "optional": true }, "node_modules/natural-compare": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/ncp": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", "optional": true, "bin": { "ncp": "bin/ncp" @@ -8913,18 +10112,21 @@ }, "node_modules/negotiator": { "version": "0.6.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "engines": { "node": ">= 0.6" } }, "node_modules/node-abort-controller": { "version": "3.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" }, "node_modules/node-fetch": { - "version": "2.6.11", - "license": "MIT", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -8940,25 +10142,10 @@ } } }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-forge": { "version": "1.3.1", - "license": "(BSD-3-Clause OR GPL-2.0)", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "engines": { "node": ">= 6.13.0" } @@ -8971,7 +10158,8 @@ }, "node_modules/node-jose": { "version": "2.2.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.2.0.tgz", + "integrity": "sha512-XPCvJRr94SjLrSIm4pbYHKLEaOsDvJCpyFw/6V/KK/IXmyZ6SFBzAUDO9HQf4DB/nTEFcRGH87mNciOP23kFjw==", "dependencies": { "base64url": "^3.0.1", "buffer": "^6.0.3", @@ -8985,16 +10173,22 @@ } }, "node_modules/node-jose/node_modules/uuid": { - "version": "9.0.0", - "license": "MIT", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/node-releases": { - "version": "2.0.10", - "dev": true, - "license": "MIT" + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true }, "node_modules/nodemailer": { "version": "6.9.8", @@ -9027,37 +10221,43 @@ }, "node_modules/oauth": { "version": "0.9.15", - "license": "MIT" + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" }, "node_modules/object-assign": { "version": "4.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.12.3", - "license": "MIT", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-path": { "version": "0.11.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz", + "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==", "engines": { "node": ">= 10.12.0" } }, "node_modules/obuf": { "version": "1.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true }, "node_modules/on-finished": { - "version": "2.3.0", - "license": "MIT", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, @@ -9067,14 +10267,16 @@ }, "node_modules/on-headers": { "version": "1.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } @@ -9095,8 +10297,9 @@ } }, "node_modules/open": { - "version": "8.4.0", - "license": "MIT", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -9128,8 +10331,9 @@ }, "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -9142,8 +10346,9 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -9156,19 +10361,22 @@ }, "node_modules/p-try": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/packet-reader": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, "node_modules/pako": { - "version": "2.0.4", - "license": "(MIT AND Zlib)" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" }, "node_modules/parent-module": { "version": "2.0.0", @@ -9184,8 +10392,9 @@ }, "node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -9201,7 +10410,8 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "engines": { "node": ">= 0.8" } @@ -9225,7 +10435,8 @@ }, "node_modules/passport-azure-ad": { "version": "4.3.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/passport-azure-ad/-/passport-azure-ad-4.3.5.tgz", + "integrity": "sha512-LBpXEght7hCMuMNFK4oegdN0uPBa3lpDMy71zQoB0zPg1RrGwdzpjwTiN1WzN0hY77fLyjz9tBr3TGAxnSgtEg==", "dependencies": { "async": "^3.2.3", "base64url": "^3.0.0", @@ -9243,13 +10454,10 @@ "node": ">= 8.0.0" } }, - "node_modules/passport-azure-ad/node_modules/async": { - "version": "3.2.4", - "license": "MIT" - }, "node_modules/passport-azure-ad/node_modules/jwa": { "version": "1.4.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -9258,7 +10466,8 @@ }, "node_modules/passport-azure-ad/node_modules/jws": { "version": "3.2.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" @@ -9283,7 +10492,8 @@ }, "node_modules/passport-github": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/passport-github/-/passport-github-1.1.0.tgz", + "integrity": "sha512-XARXJycE6fFh/dxF+Uut8OjlwbFEXgbPVj/+V+K7cvriRK7VcAOm+NgBmbiLM9Qv3SSxEAV+V6fIk89nYHXa8A==", "dependencies": { "passport-oauth2": "1.x.x" }, @@ -9292,8 +10502,9 @@ } }, "node_modules/passport-oauth2": { - "version": "1.6.1", - "license": "MIT", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz", + "integrity": "sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==", "dependencies": { "base64url": "3.x.x", "oauth": "0.9.x", @@ -9311,41 +10522,48 @@ }, "node_modules/passport-strategy": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", "engines": { "node": ">= 0.4.0" } }, "node_modules/path-browserify": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true }, "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "license": "MIT" + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { "version": "1.10.1", @@ -9363,29 +10581,24 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/path-to-regexp": { "version": "0.1.7", - "license": "MIT" + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pause": { - "version": "0.0.1" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" }, "node_modules/pg": { "version": "8.11.3", @@ -9428,19 +10641,22 @@ }, "node_modules/pg-escape": { "version": "0.2.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/pg-escape/-/pg-escape-0.2.0.tgz", + "integrity": "sha512-QfXcpxyN9vT+kvexQpTeNyiwCxs4LPXLAV/C0EeLTJPCF61swhGdDlnHcuDgxJudgKGfQYiCkegg0GsSKSvvEg==" }, "node_modules/pg-int8": { "version": "1.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", "engines": { "node": ">=4.0.0" } }, "node_modules/pg-numeric": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", "dev": true, - "license": "ISC", "engines": { "node": ">=4" } @@ -9455,11 +10671,31 @@ }, "node_modules/pg-protocol": { "version": "1.6.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" }, "node_modules/pg-types": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", + "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", + "dev": true, + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.0.1", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pg/node_modules/pg-types": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", @@ -9471,22 +10707,60 @@ "node": ">=4" } }, + "node_modules/pg/node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/pg/node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg/node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg/node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pgpass": { "version": "1.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", "dependencies": { "split2": "^4.1.0" } }, "node_modules/picocolors": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -9496,8 +10770,9 @@ }, "node_modules/pidtree": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "dev": true, - "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -9506,9 +10781,10 @@ } }, "node_modules/pirates": { - "version": "4.0.5", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } @@ -9578,40 +10854,49 @@ } }, "node_modules/postgres-array": { - "version": "2.0.0", - "license": "MIT", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=12" } }, "node_modules/postgres-bytea": { - "version": "1.0.0", - "license": "MIT", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dev": true, + "dependencies": { + "obuf": "~1.1.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, "node_modules/postgres-date": { - "version": "1.0.7", - "license": "MIT", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", + "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, "node_modules/postgres-interval": { - "version": "1.2.0", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, "node_modules/postgres-range": { "version": "1.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", + "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", + "dev": true }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -9639,8 +10924,9 @@ }, "node_modules/prettier-linter-helpers": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, - "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -9662,31 +10948,23 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/priorityqueuejs": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz", + "integrity": "sha512-lg++21mreCEOuGWTbO5DnJKAdxfjrdN0S9ysoW9SzdSJvbkWpkaDdpG/cdsPCsEnoLUwmd9m3WcZhngW7yKA2g==" }, "node_modules/process": { "version": "0.11.10", - "license": "MIT", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "engines": { "node": ">= 0.6.0" } }, "node_modules/promise": { "version": "7.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dependencies": { "asap": "~2.0.3" } @@ -9706,7 +10984,8 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "license": "MIT", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -9717,7 +10996,8 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/pseudomap": { "version": "1.0.2", @@ -9726,7 +11006,8 @@ }, "node_modules/pug": { "version": "3.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", "dependencies": { "pug-code-gen": "^3.0.2", "pug-filters": "^4.0.0", @@ -9740,7 +11021,8 @@ }, "node_modules/pug-attrs": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", "dependencies": { "constantinople": "^4.0.1", "js-stringify": "^1.0.2", @@ -9749,7 +11031,8 @@ }, "node_modules/pug-code-gen": { "version": "3.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", @@ -9763,11 +11046,13 @@ }, "node_modules/pug-error": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" }, "node_modules/pug-filters": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", "dependencies": { "constantinople": "^4.0.1", "jstransformer": "1.0.0", @@ -9778,7 +11063,8 @@ }, "node_modules/pug-lexer": { "version": "5.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", "dependencies": { "character-parser": "^2.2.0", "is-expression": "^4.0.0", @@ -9787,7 +11073,8 @@ }, "node_modules/pug-linker": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", "dependencies": { "pug-error": "^2.0.0", "pug-walk": "^2.0.0" @@ -9795,7 +11082,8 @@ }, "node_modules/pug-load": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", "dependencies": { "object-assign": "^4.1.1", "pug-walk": "^2.0.0" @@ -9803,7 +11091,8 @@ }, "node_modules/pug-parser": { "version": "6.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", "dependencies": { "pug-error": "^2.0.0", "token-stream": "1.0.0" @@ -9811,18 +11100,21 @@ }, "node_modules/pug-runtime": { "version": "3.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" }, "node_modules/pug-strip-comments": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", "dependencies": { "pug-error": "^2.0.0" } }, "node_modules/pug-walk": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" }, "node_modules/punycode": { "version": "2.3.1", @@ -9860,7 +11152,8 @@ }, "node_modules/qs": { "version": "6.11.0", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { "side-channel": "^1.0.4" }, @@ -9873,6 +11166,8 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -9887,26 +11182,28 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/random-bytes": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", "engines": { "node": ">= 0.8" } }, "node_modules/range-parser": { "version": "1.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.5.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -9919,12 +11216,14 @@ }, "node_modules/react-is": { "version": "18.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, "node_modules/recursive-readdir": { "version": "2.2.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dependencies": { "minimatch": "^3.0.5" }, @@ -9932,6 +11231,26 @@ "node": ">=6.0.0" } }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/redis": { "version": "4.6.12", "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.12.tgz", @@ -9977,10 +11296,11 @@ } }, "node_modules/resolve": { - "version": "1.22.2", - "license": "MIT", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -10005,8 +11325,9 @@ }, "node_modules/resolve-from": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -10047,17 +11368,18 @@ }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", "dev": true }, "node_modules/rhea": { @@ -10087,13 +11409,40 @@ } }, "node_modules/rimraf": { - "version": "3.0.2", - "license": "ISC", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -10101,6 +11450,8 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -10116,34 +11467,40 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safe-json-stringify": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", "optional": true }, "node_modules/safer-buffer": { "version": "2.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sax": { - "version": "1.2.4", - "license": "ISC" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" }, "node_modules/secure-compare": { "version": "3.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==" }, "node_modules/semaphore": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", + "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==", "engines": { "node": ">=0.8.0" } @@ -10162,9 +11519,21 @@ "node": ">=10" } }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.18.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -10186,32 +11555,26 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "license": "MIT" - }, - "node_modules/send/node_modules/on-finished": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/serve-favicon": { "version": "2.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==", "dependencies": { "etag": "~1.8.1", "fresh": "0.5.2", @@ -10225,15 +11588,18 @@ }, "node_modules/serve-favicon/node_modules/ms": { "version": "2.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, "node_modules/serve-favicon/node_modules/safe-buffer": { "version": "5.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "node_modules/serve-static": { "version": "1.15.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -10245,14 +11611,15 @@ } }, "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", + "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", "dependencies": { "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -10260,12 +11627,14 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -10275,19 +11644,22 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shimmer": { "version": "1.2.1", - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" }, "node_modules/side-channel": { "version": "1.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -10299,12 +11671,14 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "node_modules/simple-oauth2": { "version": "5.0.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/simple-oauth2/-/simple-oauth2-5.0.0.tgz", + "integrity": "sha512-8291lo/z5ZdpmiOFzOs1kF3cxn22bMj5FFH+DNUppLJrpoIlM1QnFiE7KpshHu3J3i21TVcx4yW+gXYjdCKDLQ==", "dependencies": { "@hapi/hoek": "^10.0.1", "@hapi/wreck": "^18.0.0", @@ -10320,8 +11694,9 @@ }, "node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -10374,25 +11749,29 @@ } }, "node_modules/split2": { - "version": "4.1.0", - "license": "ISC", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "engines": { "node": ">= 10.x" } }, "node_modules/sprintf-js": { "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "node_modules/stack-chain": { "version": "1.3.7", - "license": "MIT" + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", + "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==" }, "node_modules/stack-utils": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, - "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -10402,22 +11781,25 @@ }, "node_modules/stack-utils/node_modules/escape-string-regexp": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/statuses": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { "node": ">= 0.8" } }, "node_modules/stoppable": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", "engines": { "node": ">=4", "npm": ">=6" @@ -10425,8 +11807,9 @@ }, "node_modules/string-argv": { "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.6.19" } @@ -10444,6 +11827,27 @@ "node": ">=10" } }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string-width": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", @@ -10476,6 +11880,15 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -10491,19 +11904,19 @@ "node": ">=8" } }, - "node_modules/string-width/node_modules/ansi-regex": { + "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/string-width/node_modules/strip-ansi": { + "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", @@ -10518,10 +11931,12 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-ansi": { + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -10529,22 +11944,19 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { "node": ">=8" } }, "node_modules/strip-bom": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "engines": { "node": ">=8" } @@ -10560,7 +11972,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "engines": { "node": ">=8" }, @@ -10570,12 +11983,14 @@ }, "node_modules/strnum": { "version": "1.0.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" }, "node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -10585,7 +12000,8 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "engines": { "node": ">= 0.4" }, @@ -10594,21 +12010,12 @@ } }, "node_modules/synckit": { -<<<<<<< HEAD - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.6.tgz", - "integrity": "sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA==", - "dev": true, - "dependencies": { - "@pkgr/utils": "^2.4.2", -======= "version": "0.8.8", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", "dev": true, "dependencies": { "@pkgr/core": "^0.1.0", ->>>>>>> upstream/main "tslib": "^2.6.2" }, "engines": { @@ -10620,8 +12027,9 @@ }, "node_modules/test-exclude": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -10631,18 +12039,43 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/text-table": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/throat": { "version": "6.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" }, "node_modules/tmp": { "version": "0.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dependencies": { "rimraf": "^3.0.0" }, @@ -10652,11 +12085,26 @@ }, "node_modules/tmp-promise": { "version": "3.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", "dependencies": { "tmp": "^0.2.0" } }, + "node_modules/tmp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -10665,15 +12113,17 @@ }, "node_modules/to-fast-properties": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -10683,19 +12133,27 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "engines": { "node": ">=0.6" } }, "node_modules/token-stream": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/true-myth": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/true-myth/-/true-myth-4.1.1.tgz", + "integrity": "sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg==", "dev": true, - "license": "MIT", "engines": { "node": "10.* || >= 12.*" } @@ -10757,23 +12215,19 @@ }, "node_modules/ts-morph": { "version": "13.0.3", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-13.0.3.tgz", + "integrity": "sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw==", "dev": true, - "license": "MIT", "dependencies": { "@ts-morph/common": "~0.12.3", "code-block-writer": "^11.0.0" } }, "node_modules/ts-node": { -<<<<<<< HEAD - "version": "10.9.1", -======= "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", ->>>>>>> upstream/main "dev": true, - "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -10814,8 +12268,9 @@ }, "node_modules/ts-prune": { "version": "0.10.3", + "resolved": "https://registry.npmjs.org/ts-prune/-/ts-prune-0.10.3.tgz", + "integrity": "sha512-iS47YTbdIcvN8Nh/1BFyziyUqmjXz7GVzWu02RaZXqb+e/3Qe1B7IQ4860krOeCGUeJmterAlaM2FRH0Ue0hjw==", "dev": true, - "license": "MIT", "dependencies": { "commander": "^6.2.1", "cosmiconfig": "^7.0.1", @@ -10830,31 +12285,9 @@ }, "node_modules/ts-prune/node_modules/commander": { "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/ts-prune/node_modules/cosmiconfig": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "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/ts-prune/node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", "engines": { "node": ">= 6" } @@ -10866,7 +12299,8 @@ }, "node_modules/tunnel": { "version": "0.0.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "engines": { "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } @@ -10906,7 +12340,8 @@ }, "node_modules/type-is": { "version": "1.6.18", - "license": "MIT", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -10945,7 +12380,8 @@ }, "node_modules/uid-safe": { "version": "2.1.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", "dependencies": { "random-bytes": "~1.0.0" }, @@ -10955,7 +12391,8 @@ }, "node_modules/uid2": { "version": "0.0.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", + "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==" }, "node_modules/undici-types": { "version": "5.26.5", @@ -10990,32 +12427,31 @@ } }, "node_modules/universal-github-app-jwt": { -<<<<<<< HEAD - "version": "1.1.1", - "license": "MIT", -======= "version": "1.1.2", "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.2.tgz", "integrity": "sha512-t1iB2FmLFE+yyJY9+3wMx0ejB+MQpEVkH0gQv7dR6FZyltyq+ZZO0uDpbopxhrZ3SLEO4dCEkIujOMldEQ2iOA==", ->>>>>>> upstream/main "dependencies": { "@types/jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.2" } }, "node_modules/universal-user-agent": { - "version": "6.0.0", - "license": "ISC" + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" }, "node_modules/unpipe": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -11031,7 +12467,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -11066,22 +12501,25 @@ }, "node_modules/utils-merge": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { "version": "8.3.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true }, "node_modules/v8-to-istanbul": { "version": "9.2.0", @@ -11098,7 +12536,9 @@ } }, "node_modules/valid-url": { - "version": "1.0.9" + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" }, "node_modules/validator": { "version": "13.11.0", @@ -11110,14 +12550,16 @@ }, "node_modules/vary": { "version": "1.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } }, "node_modules/void-elements": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", "engines": { "node": ">=0.10.0" } @@ -11136,7 +12578,8 @@ }, "node_modules/walk-back": { "version": "5.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.0.tgz", + "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==", "engines": { "node": ">=12.17" } @@ -11150,10 +12593,25 @@ "makeerror": "1.0.12" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -11184,7 +12642,8 @@ }, "node_modules/with": { "version": "7.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", "dependencies": { "@babel/parser": "^7.9.6", "@babel/types": "^7.9.6", @@ -11230,6 +12689,48 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -11259,16 +12760,16 @@ "node": ">=8" } }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">=8" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { @@ -11283,35 +12784,21 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", - "license": "ISC" + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { - "version": "4.0.2", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "node_modules/xdg-basedir": { @@ -11328,19 +12815,34 @@ }, "node_modules/xml": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", + "dev": true + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } }, "node_modules/xmlbuilder": { "version": "11.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "engines": { "node": ">=4.0" } }, "node_modules/xtend": { "version": "4.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "engines": { "node": ">=0.4" } @@ -11356,7 +12858,8 @@ }, "node_modules/yallist": { "version": "4.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { "version": "2.3.4", @@ -11387,12 +12890,22 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "license": "ISC", "engines": { "node": ">=12" } }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -11422,18 +12935,32 @@ "node": ">=8" } }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yn": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -11441,7904 +12968,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, - "@ampproject/remapping": { - "version": "2.2.1", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@azure/abort-controller": { - "version": "1.0.4", - "requires": { - "tslib": "^2.0.0" - } - }, - "@azure/core-amqp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@azure/core-amqp/-/core-amqp-4.1.0.tgz", - "integrity": "sha512-tjnviDypSAgjGBZCPw+sH7vDWz27N+z0xtQewp7+xH17/eb67VH4sApl3XHuxVBro6Y6pOfxCDpqFenOoGWz6Q==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "buffer": "^6.0.0", - "events": "^3.0.0", - "process": "^0.11.10", - "rhea": "^3.0.0", - "rhea-promise": "^3.0.0", - "tslib": "^2.2.0", - "util": "^0.12.1" - } - }, - "@azure/core-asynciterator-polyfill": { - "version": "1.0.2" - }, - "@azure/core-auth": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.5.0.tgz", - "integrity": "sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-util": "^1.1.0", - "tslib": "^2.2.0" - } - }, - "@azure/core-client": { - "version": "1.5.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-asynciterator-polyfill": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.5.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - } - }, - "@azure/core-http-compat": { - "version": "1.3.0", - "requires": { - "@azure/abort-controller": "^1.0.4", - "@azure/core-client": "^1.3.0", - "@azure/core-rest-pipeline": "^1.3.0" - } - }, - "@azure/core-lro": { - "version": "2.2.4", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - } - }, - "@azure/core-paging": { - "version": "1.5.0", - "requires": { - "tslib": "^2.2.0" - } - }, - "@azure/core-rest-pipeline": { - "version": "1.10.1", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.4.0", - "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "form-data": "^4.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/core-tracing": { - "version": "1.0.0-preview.13", - "requires": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" - } - }, - "@azure/core-util": { - "version": "1.2.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - } - }, - "@azure/core-xml": { - "version": "1.3.3", - "requires": { - "fast-xml-parser": "^4.0.8", - "tslib": "^2.2.0" - } - }, - "@azure/cosmos": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.0.0.tgz", - "integrity": "sha512-/Z27p1+FTkmjmm8jk90zi/HrczPHw2t8WecFnsnTe4xGocWl0Z4clP0YlLUTJPhRLWYa5upwD9rMvKJkS1f1kg==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.2.0", - "@azure/core-tracing": "^1.0.0", - "debug": "^4.1.1", - "fast-json-stable-stringify": "^2.1.0", - "jsbi": "^3.1.3", - "node-abort-controller": "^3.0.0", - "priorityqueuejs": "^1.0.0", - "semaphore": "^1.0.5", - "tslib": "^2.2.0", - "universal-user-agent": "^6.0.0", - "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/data-tables": { - "version": "13.2.2", - "requires": { - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.0.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-xml": "^1.0.0", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/identity": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.0.0.tgz", - "integrity": "sha512-gtPYxIL0kI39Dw4t3HvlbfhOdXqKD2MqDgynlklF0j728j51dcKgRo6FLX0QzpBw/1gGfLxjMXqq3nKOSQ2lmA==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.5.0", - "@azure/core-client": "^1.4.0", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^3.5.0", - "@azure/msal-node": "^2.5.1", - "events": "^3.0.0", - "jws": "^4.0.0", - "open": "^8.0.0", - "stoppable": "^1.1.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/keyvault-secrets": { - "version": "4.7.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.5.0", - "@azure/core-http-compat": "^1.3.0", - "@azure/core-lro": "^2.2.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.8.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/logger": { - "version": "1.0.3", - "requires": { - "tslib": "^2.2.0" - } - }, - "@azure/msal-browser": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.6.0.tgz", - "integrity": "sha512-FrFBJXRJMyWXjAjg4cUNZwEKktzfzD/YD9+S1kj2ors67hKoveam4aL0bZuCZU/jTiHTn0xDQGQh2ksCMXTXtA==", - "requires": { - "@azure/msal-common": "14.5.0" - } - }, - "@azure/msal-common": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.5.0.tgz", - "integrity": "sha512-Gx5rZbiZV/HiZ2nEKfjfAF/qDdZ4/QWxMvMo2jhIFVz528dVKtaZyFAOtsX2Ak8+TQvRsGCaEfuwJFuXB6tu1A==" - }, - "@azure/msal-node": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.6.0.tgz", - "integrity": "sha512-RWAWCYYrSldIYC47oWtofIun41e6SB9TBYgGYsezq6ednagwo9ZRFyRsvl1NabmdTkdDDXRAABIdveeN2Gtd8w==", - "requires": { - "@azure/msal-common": "14.5.0", - "jsonwebtoken": "^9.0.0", - "uuid": "^8.3.0" - } - }, - "@azure/opentelemetry-instrumentation-azure-sdk": { - "version": "1.0.0-beta.5", - "resolved": "https://registry.npmjs.org/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz", - "integrity": "sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==", - "requires": { - "@azure/core-tracing": "^1.0.0", - "@azure/logger": "^1.0.0", - "@opentelemetry/api": "^1.4.1", - "@opentelemetry/core": "^1.15.2", - "@opentelemetry/instrumentation": "^0.41.2", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/service-bus": { - "version": "7.9.3", - "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.9.3.tgz", - "integrity": "sha512-6g37YpVTzRHI75BkYPiB4zqbYhQHM1Jvd+sNfRCbXeRW5FLsWoXgFVTw3Jv5kkMMX1pUNtrkaQhEoeTwtm5v3w==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-amqp": "^4.1.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.0.0", - "@azure/core-paging": "^1.4.0", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.1.1", - "@azure/core-xml": "^1.0.0", - "@azure/logger": "^1.0.0", - "@types/is-buffer": "^2.0.0", - "buffer": "^6.0.0", - "is-buffer": "^2.0.3", - "jssha": "^3.1.0", - "long": "^5.2.0", - "process": "^0.11.10", - "rhea-promise": "^3.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - }, - "@azure/core-util": { - "version": "1.3.2", - "requires": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - } - } - } - }, - "@azure/storage-blob": { - "version": "12.17.0", - "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.17.0.tgz", - "integrity": "sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-http": "^3.0.0", - "@azure/core-lro": "^2.2.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "events": "^3.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-http": { - "version": "3.0.1", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" - } - }, - "xml2js": { - "version": "0.5.0", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - } - } - }, - "@azure/storage-queue": { - "version": "12.16.0", - "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.16.0.tgz", - "integrity": "sha512-HzwzMsNAh2PwLtx9WfXndj9elUr6duDFak5CjM6BxdWhLqf37VywPCWmEzjxuFfrq30c1T34+MjMXnN6YgqRUw==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-http": "^3.0.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-http": { - "version": "3.0.1", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" - } - }, - "xml2js": { - "version": "0.5.0", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - } - } - }, - "@babel/code-frame": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.21.7", - "dev": true - }, - "@babel/core": { - "version": "7.21.8", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.9.0", - "dev": true - }, - "semver": { - "version": "6.3.0", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/types": "^7.21.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "semver": { - "version": "6.3.0", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.21.5", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.21.0", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/types": "^7.21.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-simple-access": "^7.21.5", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/types": "^7.21.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.21.5" - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1" - }, - "@babel/helper-validator-option": { - "version": "7.21.0", - "dev": true - }, - "@babel/helpers": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.21.8" - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/template": { - "version": "7.20.7", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - } - }, - "@babel/traverse": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.21.5", - "requires": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@cspell/cspell-bundled-dicts": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.3.2.tgz", - "integrity": "sha512-3ubOgz1/MDixJbq//0rQ2omB3cSdhVJDviERZeiREGz4HOq84aaK1Fqbw5SjNZHvhpoq+AYXm6kJbIAH8YhKgg==", - "dev": true, - "requires": { - "@cspell/dict-ada": "^4.0.2", - "@cspell/dict-aws": "^4.0.1", - "@cspell/dict-bash": "^4.1.3", - "@cspell/dict-companies": "^3.0.29", - "@cspell/dict-cpp": "^5.0.10", - "@cspell/dict-cryptocurrencies": "^5.0.0", - "@cspell/dict-csharp": "^4.0.2", - "@cspell/dict-css": "^4.0.12", - "@cspell/dict-dart": "^2.0.3", - "@cspell/dict-django": "^4.1.0", - "@cspell/dict-docker": "^1.1.7", - "@cspell/dict-dotnet": "^5.0.0", - "@cspell/dict-elixir": "^4.0.3", - "@cspell/dict-en_us": "^4.3.13", - "@cspell/dict-en-common-misspellings": "^2.0.0", - "@cspell/dict-en-gb": "1.1.33", - "@cspell/dict-filetypes": "^3.0.3", - "@cspell/dict-fonts": "^4.0.0", - "@cspell/dict-fsharp": "^1.0.1", - "@cspell/dict-fullstack": "^3.1.5", - "@cspell/dict-gaming-terms": "^1.0.4", - "@cspell/dict-git": "^3.0.0", - "@cspell/dict-golang": "^6.0.5", - "@cspell/dict-haskell": "^4.0.1", - "@cspell/dict-html": "^4.0.5", - "@cspell/dict-html-symbol-entities": "^4.0.0", - "@cspell/dict-java": "^5.0.6", - "@cspell/dict-k8s": "^1.0.2", - "@cspell/dict-latex": "^4.0.0", - "@cspell/dict-lorem-ipsum": "^4.0.0", - "@cspell/dict-lua": "^4.0.3", - "@cspell/dict-makefile": "^1.0.0", - "@cspell/dict-node": "^4.0.3", - "@cspell/dict-npm": "^5.0.14", - "@cspell/dict-php": "^4.0.5", - "@cspell/dict-powershell": "^5.0.3", - "@cspell/dict-public-licenses": "^2.0.5", - "@cspell/dict-python": "^4.1.11", - "@cspell/dict-r": "^2.0.1", - "@cspell/dict-ruby": "^5.0.2", - "@cspell/dict-rust": "^4.0.1", - "@cspell/dict-scala": "^5.0.0", - "@cspell/dict-software-terms": "^3.3.15", - "@cspell/dict-sql": "^2.1.3", - "@cspell/dict-svelte": "^1.0.2", - "@cspell/dict-swift": "^2.0.1", - "@cspell/dict-typescript": "^3.1.2", - "@cspell/dict-vue": "^3.0.0" - } - }, - "@cspell/cspell-json-reporter": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.3.2.tgz", - "integrity": "sha512-gHSz4jXMJPcxx+lOGfXhHuoyenAWQ8PVA/atHFrWYKo1LzKTbpkEkrsDnlX8QNJubc3EMH63Uy+lOIaFDVyHiQ==", - "dev": true, - "requires": { - "@cspell/cspell-types": "8.3.2" - } - }, - "@cspell/cspell-pipe": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.3.2.tgz", - "integrity": "sha512-GZmDwvQGOjQi3IjD4k9xXeVTDANczksOsgVKb3v2QZk9mR4Qj8c6Uarjd4AgSiIhu/wBliJfzr5rWFJu4X2VfQ==", - "dev": true - }, - "@cspell/cspell-resolver": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.3.2.tgz", - "integrity": "sha512-w2Tmb95bzdEz9L4W5qvsP5raZbyEzKL7N2ksU/+yh8NEJcTuExmAl/nMnb3aIk7m2b+kPHnMOcJuwfUMLmyv4A==", - "dev": true, - "requires": { - "global-directory": "^4.0.1" - } - }, - "@cspell/cspell-service-bus": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.3.2.tgz", - "integrity": "sha512-skTHNyVi74//W/O+f4IauDhm6twA9S2whkylonsIzPxEl4Pn3y2ZEMXNki/MWUwZfDIzKKSxlcREH61g7zCvhg==", - "dev": true - }, - "@cspell/cspell-types": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.3.2.tgz", - "integrity": "sha512-qS/gWd9ItOrN6ZX5pwC9lJjnBoyiAyhxYq0GUXuV892LQvwrBmECGk6KhsA1lPW7JJS7o57YTAS1jmXnmXMEpg==", - "dev": true - }, - "@cspell/dict-ada": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.0.2.tgz", - "integrity": "sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==", - "dev": true - }, - "@cspell/dict-aws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.1.tgz", - "integrity": "sha512-NXO+kTPQGqaaJKa4kO92NAXoqS+i99dQzf3/L1BxxWVSBS3/k1f3uhmqIh7Crb/n22W793lOm0D9x952BFga3Q==", - "dev": true - }, - "@cspell/dict-bash": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.1.3.tgz", - "integrity": "sha512-tOdI3QVJDbQSwPjUkOiQFhYcu2eedmX/PtEpVWg0aFps/r6AyjUQINtTgpqMYnYuq8O1QUIQqnpx21aovcgZCw==", - "dev": true - }, - "@cspell/dict-companies": { - "version": "3.0.29", - "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.0.29.tgz", - "integrity": "sha512-F/8XnkqjU7jmSDAcD3LSSX+WxCVUWPssqlO4lzGMIK3MNIUt+d48eSIt3pFAIB/Z9y0ojoLHUtWX9HJ1ZtGrXQ==", - "dev": true - }, - "@cspell/dict-cpp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.1.0.tgz", - "integrity": "sha512-23gd41gsFhXYvVMYXiXOQlYp8othU2JjB6JbH2sWHlmwokiCG9yuWwrN/nVfrt45fzq/VyAurl58AXfx7ctAJA==", - "dev": true - }, - "@cspell/dict-cryptocurrencies": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.0.tgz", - "integrity": "sha512-Z4ARIw5+bvmShL+4ZrhDzGhnc9znaAGHOEMaB/GURdS/jdoreEDY34wdN0NtdLHDO5KO7GduZnZyqGdRoiSmYA==", - "dev": true - }, - "@cspell/dict-csharp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.2.tgz", - "integrity": "sha512-1JMofhLK+4p4KairF75D3A924m5ERMgd1GvzhwK2geuYgd2ZKuGW72gvXpIV7aGf52E3Uu1kDXxxGAiZ5uVG7g==", - "dev": true - }, - "@cspell/dict-css": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.12.tgz", - "integrity": "sha512-vGBgPM92MkHQF5/2jsWcnaahOZ+C6OE/fPvd5ScBP72oFY9tn5GLuomcyO0z8vWCr2e0nUSX1OGimPtcQAlvSw==", - "dev": true - }, - "@cspell/dict-dart": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.0.3.tgz", - "integrity": "sha512-cLkwo1KT5CJY5N5RJVHks2genFkNCl/WLfj+0fFjqNR+tk3tBI1LY7ldr9piCtSFSm4x9pO1x6IV3kRUY1lLiw==", - "dev": true - }, - "@cspell/dict-data-science": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-1.0.11.tgz", - "integrity": "sha512-TaHAZRVe0Zlcc3C23StZqqbzC0NrodRwoSAc8dis+5qLeLLnOCtagYQeROQvDlcDg3X/VVEO9Whh4W/z4PAmYQ==", - "dev": true - }, - "@cspell/dict-django": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.0.tgz", - "integrity": "sha512-bKJ4gPyrf+1c78Z0Oc4trEB9MuhcB+Yg+uTTWsvhY6O2ncFYbB/LbEZfqhfmmuK/XJJixXfI1laF2zicyf+l0w==", - "dev": true - }, - "@cspell/dict-docker": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.7.tgz", - "integrity": "sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==", - "dev": true - }, - "@cspell/dict-dotnet": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-dotnet/-/dict-dotnet-5.0.0.tgz", - "integrity": "sha512-EOwGd533v47aP5QYV8GlSSKkmM9Eq8P3G/eBzSpH3Nl2+IneDOYOBLEUraHuiCtnOkNsz0xtZHArYhAB2bHWAw==", - "dev": true - }, - "@cspell/dict-elixir": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-elixir/-/dict-elixir-4.0.3.tgz", - "integrity": "sha512-g+uKLWvOp9IEZvrIvBPTr/oaO6619uH/wyqypqvwpmnmpjcfi8+/hqZH8YNKt15oviK8k4CkINIqNhyndG9d9Q==", - "dev": true - }, - "@cspell/dict-en_us": { - "version": "4.3.13", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.13.tgz", - "integrity": "sha512-T6lHiGCjloGNE0d8CogF+efJZPCAP8zdzn+KnlI0Bmjaz5nvG2LTX7CXl1zkOl1nYYev0FuIk9WJ9YPVRjcFbQ==", - "dev": true - }, - "@cspell/dict-en-common-misspellings": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.0.tgz", - "integrity": "sha512-NOg8dlv37/YqLkCfBs5OXeJm/Wcfb/CzeOmOZJ2ZXRuxwsNuolb4TREUce0yAXRqMhawahY5TSDRJJBgKjBOdw==", - "dev": true - }, - "@cspell/dict-en-gb": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz", - "integrity": "sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==", - "dev": true - }, - "@cspell/dict-filetypes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.3.tgz", - "integrity": "sha512-J9UP+qwwBLfOQ8Qg9tAsKtSY/WWmjj21uj6zXTI9hRLD1eG1uUOLcfVovAmtmVqUWziPSKMr87F6SXI3xmJXgw==", - "dev": true - }, - "@cspell/dict-fonts": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-fonts/-/dict-fonts-4.0.0.tgz", - "integrity": "sha512-t9V4GeN/m517UZn63kZPUYP3OQg5f0OBLSd3Md5CU3eH1IFogSvTzHHnz4Wqqbv8NNRiBZ3HfdY/pqREZ6br3Q==", - "dev": true - }, - "@cspell/dict-fsharp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-fsharp/-/dict-fsharp-1.0.1.tgz", - "integrity": "sha512-23xyPcD+j+NnqOjRHgW3IU7Li912SX9wmeefcY0QxukbAxJ/vAN4rBpjSwwYZeQPAn3fxdfdNZs03fg+UM+4yQ==", - "dev": true - }, - "@cspell/dict-fullstack": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-fullstack/-/dict-fullstack-3.1.5.tgz", - "integrity": "sha512-6ppvo1dkXUZ3fbYn/wwzERxCa76RtDDl5Afzv2lijLoijGGUw5yYdLBKJnx8PJBGNLh829X352ftE7BElG4leA==", - "dev": true - }, - "@cspell/dict-gaming-terms": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.0.4.tgz", - "integrity": "sha512-hbDduNXlk4AOY0wFxcDMWBPpm34rpqJBeqaySeoUH70eKxpxm+dvjpoRLJgyu0TmymEICCQSl6lAHTHSDiWKZg==", - "dev": true - }, - "@cspell/dict-git": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.0.tgz", - "integrity": "sha512-simGS/lIiXbEaqJu9E2VPoYW1OTC2xrwPPXNXFMa2uo/50av56qOuaxDrZ5eH1LidFXwoc8HROCHYeKoNrDLSw==", - "dev": true - }, - "@cspell/dict-golang": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.5.tgz", - "integrity": "sha512-w4mEqGz4/wV+BBljLxduFNkMrd3rstBNDXmoX5kD4UTzIb4Sy0QybWCtg2iVT+R0KWiRRA56QKOvBsgXiddksA==", - "dev": true - }, - "@cspell/dict-haskell": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-haskell/-/dict-haskell-4.0.1.tgz", - "integrity": "sha512-uRrl65mGrOmwT7NxspB4xKXFUenNC7IikmpRZW8Uzqbqcu7ZRCUfstuVH7T1rmjRgRkjcIjE4PC11luDou4wEQ==", - "dev": true - }, - "@cspell/dict-html": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.5.tgz", - "integrity": "sha512-p0brEnRybzSSWi8sGbuVEf7jSTDmXPx7XhQUb5bgG6b54uj+Z0Qf0V2n8b/LWwIPJNd1GygaO9l8k3HTCy1h4w==", - "dev": true - }, - "@cspell/dict-html-symbol-entities": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.0.tgz", - "integrity": "sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==", - "dev": true - }, - "@cspell/dict-java": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-java/-/dict-java-5.0.6.tgz", - "integrity": "sha512-kdE4AHHHrixyZ5p6zyms1SLoYpaJarPxrz8Tveo6gddszBVVwIUZ+JkQE1bWNLK740GWzIXdkznpUfw1hP9nXw==", - "dev": true - }, - "@cspell/dict-k8s": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.2.tgz", - "integrity": "sha512-tLT7gZpNPnGa+IIFvK9SP1LrSpPpJ94a/DulzAPOb1Q2UBFwdpFd82UWhio0RNShduvKG/WiMZf/wGl98pn+VQ==", - "dev": true - }, - "@cspell/dict-latex": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-latex/-/dict-latex-4.0.0.tgz", - "integrity": "sha512-LPY4y6D5oI7D3d+5JMJHK/wxYTQa2lJMSNxps2JtuF8hbAnBQb3igoWEjEbIbRRH1XBM0X8dQqemnjQNCiAtxQ==", - "dev": true - }, - "@cspell/dict-lorem-ipsum": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.0.tgz", - "integrity": "sha512-1l3yjfNvMzZPibW8A7mQU4kTozwVZVw0AvFEdy+NcqtbxH+TvbSkNMqROOFWrkD2PjnKG0+Ea0tHI2Pi6Gchnw==", - "dev": true - }, - "@cspell/dict-lua": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-lua/-/dict-lua-4.0.3.tgz", - "integrity": "sha512-lDHKjsrrbqPaea13+G9s0rtXjMO06gPXPYRjRYawbNmo4E/e3XFfVzeci3OQDQNDmf2cPOwt9Ef5lu2lDmwfJg==", - "dev": true - }, - "@cspell/dict-makefile": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-makefile/-/dict-makefile-1.0.0.tgz", - "integrity": "sha512-3W9tHPcSbJa6s0bcqWo6VisEDTSN5zOtDbnPabF7rbyjRpNo0uHXHRJQF8gAbFzoTzBBhgkTmrfSiuyQm7vBUQ==", - "dev": true - }, - "@cspell/dict-node": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-4.0.3.tgz", - "integrity": "sha512-sFlUNI5kOogy49KtPg8SMQYirDGIAoKBO3+cDLIwD4MLdsWy1q0upc7pzGht3mrjuyMiPRUV14Bb0rkVLrxOhg==", - "dev": true - }, - "@cspell/dict-npm": { - "version": "5.0.14", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.0.14.tgz", - "integrity": "sha512-k0kC7/W2qG5YII+SW6s+JtvKrkZg651vizi5dv/5G2HmJaeLNgDqBVeeDk/uV+ntBorM66XG4BPMjSxoaIlC5w==", - "dev": true - }, - "@cspell/dict-php": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.0.5.tgz", - "integrity": "sha512-9r8ao7Z/mH9Z8pSB7yLtyvcCJWw+/MnQpj7xGVYzIV7V2ZWDRjXZAMgteHMJ37m8oYz64q5d4tiipD300QSetQ==", - "dev": true - }, - "@cspell/dict-powershell": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-powershell/-/dict-powershell-5.0.3.tgz", - "integrity": "sha512-lEdzrcyau6mgzu1ie98GjOEegwVHvoaWtzQnm1ie4DyZgMr+N6D0Iyj1lzvtmt0snvsDFa5F2bsYzf3IMKcpcA==", - "dev": true - }, - "@cspell/dict-public-licenses": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.5.tgz", - "integrity": "sha512-91HK4dSRri/HqzAypHgduRMarJAleOX5NugoI8SjDLPzWYkwZ1ftuCXSk+fy8DLc3wK7iOaFcZAvbjmnLhVs4A==", - "dev": true - }, - "@cspell/dict-python": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.1.11.tgz", - "integrity": "sha512-XG+v3PumfzUW38huSbfT15Vqt3ihNb462ulfXifpQllPok5OWynhszCLCRQjQReV+dgz784ST4ggRxW452/kVg==", - "dev": true, - "requires": { - "@cspell/dict-data-science": "^1.0.11" - } - }, - "@cspell/dict-r": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-r/-/dict-r-2.0.1.tgz", - "integrity": "sha512-KCmKaeYMLm2Ip79mlYPc8p+B2uzwBp4KMkzeLd5E6jUlCL93Y5Nvq68wV5fRLDRTf7N1LvofkVFWfDcednFOgA==", - "dev": true - }, - "@cspell/dict-ruby": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-ruby/-/dict-ruby-5.0.2.tgz", - "integrity": "sha512-cIh8KTjpldzFzKGgrqUX4bFyav5lC52hXDKo4LbRuMVncs3zg4hcSf4HtURY+f2AfEZzN6ZKzXafQpThq3dl2g==", - "dev": true - }, - "@cspell/dict-rust": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.1.tgz", - "integrity": "sha512-xJSSzHDK2z6lSVaOmMxl3PTOtfoffaxMo7fTcbZUF+SCJzfKbO6vnN9TCGX2sx1RHFDz66Js6goz6SAZQdOwaw==", - "dev": true - }, - "@cspell/dict-scala": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-scala/-/dict-scala-5.0.0.tgz", - "integrity": "sha512-ph0twaRoV+ylui022clEO1dZ35QbeEQaKTaV2sPOsdwIokABPIiK09oWwGK9qg7jRGQwVaRPEq0Vp+IG1GpqSQ==", - "dev": true - }, - "@cspell/dict-software-terms": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-3.3.15.tgz", - "integrity": "sha512-1qqMGFi1TUNq9gQj4FTLPTlqVzQLXrj80MsKoXVpysr+823kMWesQAjqHiPg+MYsQ3DlTcpGWcjq/EbYonqueQ==", - "dev": true - }, - "@cspell/dict-sql": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.1.3.tgz", - "integrity": "sha512-SEyTNKJrjqD6PAzZ9WpdSu6P7wgdNtGV2RV8Kpuw1x6bV+YsSptuClYG+JSdRExBTE6LwIe1bTklejUp3ZP8TQ==", - "dev": true - }, - "@cspell/dict-svelte": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-svelte/-/dict-svelte-1.0.2.tgz", - "integrity": "sha512-rPJmnn/GsDs0btNvrRBciOhngKV98yZ9SHmg8qI6HLS8hZKvcXc0LMsf9LLuMK1TmS2+WQFAan6qeqg6bBxL2Q==", - "dev": true - }, - "@cspell/dict-swift": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-swift/-/dict-swift-2.0.1.tgz", - "integrity": "sha512-gxrCMUOndOk7xZFmXNtkCEeroZRnS2VbeaIPiymGRHj5H+qfTAzAKxtv7jJbVA3YYvEzWcVE2oKDP4wcbhIERw==", - "dev": true - }, - "@cspell/dict-typescript": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.1.2.tgz", - "integrity": "sha512-lcNOYWjLUvDZdLa0UMNd/LwfVdxhE9rKA+agZBGjL3lTA3uNvH7IUqSJM/IXhJoBpLLMVEOk8v1N9xi+vDuCdA==", - "dev": true - }, - "@cspell/dict-vue": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-vue/-/dict-vue-3.0.0.tgz", - "integrity": "sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==", - "dev": true - }, - "@cspell/dynamic-import": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.3.2.tgz", - "integrity": "sha512-4t0xM5luA3yQhar2xWvYK4wQSDB2r0u8XkpzzJqd57MnJXd7uIAxI0awGUrDXukadRaCo0tDIlMUBemH48SNVg==", - "dev": true, - "requires": { - "import-meta-resolve": "^4.0.0" - } - }, - "@cspell/strong-weak-map": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.3.2.tgz", - "integrity": "sha512-Mte/2000ap278kRYOUhiGWI7MNr1+A7WSWJmlcdP4CAH5SO20sZI3/cyZLjJJEyapdhK5vaP1L5J9sUcVDHd3A==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", - "dev": true - }, - "@hapi/boom": { - "version": "10.0.1", - "requires": { - "@hapi/hoek": "^11.0.2" - }, - "dependencies": { - "@hapi/hoek": { - "version": "11.0.2" - } - } - }, - "@hapi/bourne": { - "version": "3.0.0" - }, - "@hapi/hoek": { - "version": "10.0.1" - }, - "@hapi/topo": { - "version": "5.1.0", - "requires": { - "@hapi/hoek": "^9.0.0" - }, - "dependencies": { - "@hapi/hoek": { - "version": "9.3.0" - } - } - }, - "@hapi/wreck": { - "version": "18.0.1", - "requires": { - "@hapi/boom": "^10.0.1", - "@hapi/bourne": "^3.0.0", - "@hapi/hoek": "^11.0.2" - }, - "dependencies": { - "@hapi/hoek": { - "version": "11.0.2" - } - } - }, - "@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true - }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - } - } - } - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "dev": true - }, - "@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - } - }, - "@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "requires": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - } - }, - "@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "requires": { - "jest-get-type": "^29.6.3" - } - }, - "@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - } - }, - "@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - } - }, - "@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", - "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - } - } - } - }, - "@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.27.8" - } - }, - "@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "requires": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - } - }, - "@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.18", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true - } - } - }, - "@microsoft/applicationinsights-web-snippet": { - "version": "1.0.1" - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@octokit/auth-app": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.0.3.tgz", - "integrity": "sha512-9N7IlBAKEJR3tJgPSubCxIDYGXSdc+2xbkjYpk9nCyqREnH8qEMoMhiEB1WgoA9yTFp91El92XNXAi+AjuKnfw==", - "requires": { - "@octokit/auth-oauth-app": "^7.0.0", - "@octokit/auth-oauth-user": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "deprecation": "^2.3.1", - "lru-cache": "^10.0.0", - "universal-github-app-jwt": "^1.1.2", - "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==" - } - } - }, - "@octokit/auth-oauth-app": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz", - "integrity": "sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg==", - "requires": { - "@octokit/auth-oauth-device": "^6.0.0", - "@octokit/auth-oauth-user": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/types": "^12.0.0", - "@types/btoa-lite": "^1.0.0", - "btoa-lite": "^1.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/auth-oauth-device": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.0.1.tgz", - "integrity": "sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw==", - "requires": { - "@octokit/oauth-methods": "^4.0.0", - "@octokit/request": "^8.0.0", - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/auth-oauth-user": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.0.1.tgz", - "integrity": "sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw==", - "requires": { - "@octokit/auth-oauth-device": "^6.0.0", - "@octokit/oauth-methods": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/types": "^12.0.0", - "btoa-lite": "^1.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==" - }, - "@octokit/core": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.2.tgz", - "integrity": "sha512-cZUy1gUvd4vttMic7C0lwPed8IYXWYp8kHIMatyhY8t8n3Cpw2ILczkV5pGMPqef7v0bLo0pOHrEHarsau2Ydg==", - "requires": { - "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.0.0", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/endpoint": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", - "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", - "requires": { - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/graphql": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", - "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", - "requires": { - "@octokit/request": "^8.0.1", - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/oauth-authorization-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", - "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==" - }, - "@octokit/oauth-methods": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-4.0.1.tgz", - "integrity": "sha512-1NdTGCoBHyD6J0n2WGXg9+yDLZrRNZ0moTEex/LSPr49m530WNKcCfXDghofYptr3st3eTii+EHoG5k/o+vbtw==", - "requires": { - "@octokit/oauth-authorization-url": "^6.0.2", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "btoa-lite": "^1.0.0" - } - }, - "@octokit/openapi-types": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz", - "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw==" - }, - "@octokit/plugin-paginate-graphql": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-4.0.0.tgz", - "integrity": "sha512-7HcYW5tP7/Z6AETAPU14gp5H5KmCPT3hmJrS/5tO7HIgbwenYmgw4OY9Ma54FDySuxMwD+wsJlxtuGWwuZuItA==", - "requires": {} - }, - "@octokit/plugin-paginate-rest": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz", - "integrity": "sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg==", - "requires": { - "@octokit/types": "^12.4.0" - } - }, - "@octokit/plugin-request-log": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", - "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", - "requires": {} - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.2.0.tgz", - "integrity": "sha512-ePbgBMYtGoRNXDyKGvr9cyHjQ163PbwD0y1MkDJCpkO2YH4OeXX40c4wYHKikHGZcpGPbcRLuy0unPUuafco8Q==", - "requires": { - "@octokit/types": "^12.3.0" - } - }, - "@octokit/request": { - "version": "8.1.6", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", - "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", - "requires": { - "@octokit/endpoint": "^9.0.0", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/request-error": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", - "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", - "requires": { - "@octokit/types": "^12.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/rest": { - "version": "20.0.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", - "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", - "requires": { - "@octokit/core": "^5.0.0", - "@octokit/plugin-paginate-rest": "^9.0.0", - "@octokit/plugin-request-log": "^4.0.0", - "@octokit/plugin-rest-endpoint-methods": "^10.0.0" - } - }, - "@octokit/types": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.4.0.tgz", - "integrity": "sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ==", - "requires": { - "@octokit/openapi-types": "^19.1.0" - } - }, - "@opentelemetry/api": { - "version": "1.4.1" - }, - "@opentelemetry/core": { -<<<<<<< HEAD - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.18.1.tgz", - "integrity": "sha512-kvnUqezHMhsQvdsnhnqTNfAJs3ox/isB0SVrM1dhVFw7SsB7TstuVa6fgWnN2GdPyilIFLUvvbTZoVRmx6eiRg==", - "requires": { - "@opentelemetry/semantic-conventions": "1.18.1" -======= - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.19.0.tgz", - "integrity": "sha512-w42AukJh3TP8R0IZZOVJVM/kMWu8g+lm4LzT70WtuKqhwq7KVhcDzZZuZinWZa6TtQCl7Smt2wolEYzpHabOgw==", - "requires": { - "@opentelemetry/semantic-conventions": "1.19.0" ->>>>>>> upstream/main - } - }, - "@opentelemetry/instrumentation": { - "version": "0.41.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz", - "integrity": "sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==", - "requires": { - "@types/shimmer": "^1.0.2", - "import-in-the-middle": "1.4.2", - "require-in-the-middle": "^7.1.1", - "semver": "^7.5.1", - "shimmer": "^1.2.1" - } - }, - "@opentelemetry/resources": { -<<<<<<< HEAD - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.18.1.tgz", - "integrity": "sha512-JjbcQLYMttXcIabflLRuaw5oof5gToYV9fuXbcsoOeQ0BlbwUn6DAZi++PNsSz2jjPeASfDls10iaO/8BRIPRA==", - "requires": { - "@opentelemetry/core": "1.18.1", - "@opentelemetry/semantic-conventions": "1.18.1" - } - }, - "@opentelemetry/sdk-trace-base": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.18.1.tgz", - "integrity": "sha512-tRHfDxN5dO+nop78EWJpzZwHsN1ewrZRVVwo03VJa3JQZxToRDH29/+MB24+yoa+IArerdr7INFJiX/iN4gjqg==", - "requires": { - "@opentelemetry/core": "1.18.1", - "@opentelemetry/resources": "1.18.1", - "@opentelemetry/semantic-conventions": "1.18.1" - } - }, - "@opentelemetry/semantic-conventions": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.18.1.tgz", - "integrity": "sha512-+NLGHr6VZwcgE/2lw8zDIufOCGnzsA5CbQIMleXZTrgkBd0TanCX+MiDYJ1TOS4KL/Tqk0nFRxawnaYr6pkZkA==" -======= - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.19.0.tgz", - "integrity": "sha512-RgxvKuuMOf7nctOeOvpDjt2BpZvZGr9Y0vf7eGtY5XYZPkh2p7e2qub1S2IArdBMf9kEbz0SfycqCviOu9isqg==", - "requires": { - "@opentelemetry/core": "1.19.0", - "@opentelemetry/semantic-conventions": "1.19.0" - } - }, - "@opentelemetry/sdk-trace-base": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.19.0.tgz", - "integrity": "sha512-+IRvUm+huJn2KqfFW3yW/cjvRwJ8Q7FzYHoUNx5Fr0Lws0LxjMJG1uVB8HDpLwm7mg5XXH2M5MF+0jj5cM8BpQ==", - "requires": { - "@opentelemetry/core": "1.19.0", - "@opentelemetry/resources": "1.19.0", - "@opentelemetry/semantic-conventions": "1.19.0" - } - }, - "@opentelemetry/semantic-conventions": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.19.0.tgz", - "integrity": "sha512-14jRpC8f5c0gPSwoZ7SbEJni1PqI+AhAE8m1bMz6v+RPM4OlP1PT2UHBJj5Qh/ALLPjhVU/aZUK3YyjTUqqQVg==" ->>>>>>> upstream/main - }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true - }, - "@pkgr/core": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.0.tgz", - "integrity": "sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ==", - "dev": true - }, - "@primer/octicons": { - "version": "19.8.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.8.0.tgz", - "integrity": "sha512-Imze/fyW41Io5fN+27T5EAeXJrgBjMbz6nzU+wYbRylXvIAjLPUvaJPVoStiFlgSU+TjTUJqg5A9rgMDzTyMCg==", - "requires": { - "object-assign": "^4.1.1" - } - }, - "@redis/bloom": { - "version": "1.2.0", - "requires": {} - }, - "@redis/client": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.13.tgz", - "integrity": "sha512-epkUM9D0Sdmt93/8Ozk43PNjLi36RZzG+d/T1Gdu5AI8jvghonTeLYV69WVWdilvFo+PYxbP0TZ0saMvr6nscQ==", - "requires": { - "cluster-key-slot": "1.1.2", - "generic-pool": "3.9.0", - "yallist": "4.0.0" - } - }, - "@redis/graph": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", - "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", - "requires": {} - }, - "@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", - "requires": {} - }, - "@redis/search": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", - "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", - "requires": {} - }, - "@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "requires": {} - }, - "@sideway/address": { - "version": "4.1.4", - "requires": { - "@hapi/hoek": "^9.0.0" - }, - "dependencies": { - "@hapi/hoek": { - "version": "9.3.0" - } - } - }, - "@sideway/formula": { - "version": "3.0.1" - }, - "@sideway/pinpoint": { - "version": "2.0.0" - }, - "@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "@sindresorhus/merge-streams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", - "dev": true - }, - "@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - } - }, - "@tootallnate/once": { - "version": "2.0.0" - }, - "@ts-morph/common": { - "version": "0.12.3", - "dev": true, - "requires": { - "fast-glob": "^3.2.7", - "minimatch": "^3.0.4", - "mkdirp": "^1.0.4", - "path-browserify": "^1.0.1" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "dev": true - }, - "@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "requires": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.7" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/btoa-lite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.2.tgz", - "integrity": "sha512-ZYbcE2x7yrvNFJiU7xJGrpF/ihpkM7zKgw8bha3LNJSesvTtUNxbpzaT7WXBIryf6jovisrxTBvymxMeLLj1Mg==" - }, - "@types/connect": { - "version": "3.4.35", - "requires": { - "@types/node": "*" - } - }, - "@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, - "requires": { - "@types/ms": "*" - } - }, - "@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.34", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "@types/express-session": { - "version": "1.17.10", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.10.tgz", - "integrity": "sha512-U32bC/s0ejXijw5MAzyaV4tuZopCh/K7fPoUDyNbsRXHvPSeymygYD1RFL99YOLhF5PNOkzswvOTRaVHdL1zMw==", - "dev": true, - "requires": { - "@types/express": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/is-buffer": { - "version": "2.0.0", - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "29.5.11", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", - "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", - "dev": true, - "requires": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "@types/jsonwebtoken": { - "version": "9.0.2", - "requires": { - "@types/node": "*" - } - }, - "@types/lodash": { - "version": "4.14.202", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", - "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", - "dev": true - }, - "@types/luxon": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.0.tgz", - "integrity": "sha512-PEVoA4MOfSsFNaPrZjIUGUZujBDxnO/tj2A2N9KfzlR+pNgpBdDuk0TmRvSMAVUP5q4q8IkMEZ8UOp3MIr+QgA==", - "dev": true - }, - "@types/memory-cache": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@types/memory-cache/-/memory-cache-0.2.5.tgz", - "integrity": "sha512-OIKRDDZUFeKT/rsko7/CGnR5qE8xTU8ogzyaaSDSHGkKwlSB/E6RopSF5fReo89khCAcGIoqSi723tDqUe6gYw==", - "dev": true - }, - "@types/mime": { - "version": "1.3.2" - }, - "@types/morgan": { - "version": "1.9.9", - "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.9.tgz", - "integrity": "sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/ms": { - "version": "0.7.31", - "dev": true - }, - "@types/node": { - "version": "20.11.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", - "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/node-fetch": { - "version": "2.6.1", - "requires": { - "@types/node": "*", - "form-data": "^3.0.0" - }, - "dependencies": { - "form-data": { - "version": "3.0.1", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } - } - }, - "@types/node-jose": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@types/node-jose/-/node-jose-1.1.13.tgz", - "integrity": "sha512-QjMd4yhwy1EvSToQn0YI3cD29YhyfxFwj7NecuymjLys2/P0FwxWnkgBlFxCai6Y3aBCe7rbwmqwJJawxlgcXw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/oauth": { - "version": "0.9.1", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/object-path": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/@types/object-path/-/object-path-0.11.4.tgz", - "integrity": "sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "dev": true - }, - "@types/passport": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz", - "integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==", - "dev": true, - "requires": { - "@types/express": "*" - } - }, - "@types/passport-azure-ad": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/passport-azure-ad/-/passport-azure-ad-4.3.5.tgz", - "integrity": "sha512-dzWBDye7VvzWgKQbxImEvT0x1b0Vi37AYZrjN/XitTkstHsegDT97Wha5Aknoh4vPpv68DdaxZ4defK8YIk7kA==", - "dev": true, - "requires": { - "@types/express": "*", - "@types/passport": "*" - } - }, - "@types/passport-github": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@types/passport-github/-/passport-github-1.1.12.tgz", - "integrity": "sha512-VJpMEIH+cOoXB694QgcxuvWy2wPd1Oq3gqrg2Y9DMVBYs9TmH9L14qnqPDZsNMZKBDH+SvqRsGZj9SgHYeDgcA==", - "dev": true, - "requires": { - "@types/express": "*", - "@types/passport": "*", - "@types/passport-oauth2": "*" - } - }, - "@types/passport-oauth2": { - "version": "1.4.11", - "dev": true, - "requires": { - "@types/express": "*", - "@types/oauth": "*", - "@types/passport": "*" - } - }, - "@types/pg": { - "version": "8.10.9", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.9.tgz", - "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", - "dev": true, - "requires": { - "@types/node": "*", - "pg-protocol": "*", - "pg-types": "^4.0.1" - }, - "dependencies": { - "pg-types": { - "version": "4.0.1", - "dev": true, - "requires": { - "pg-int8": "1.0.1", - "pg-numeric": "1.0.2", - "postgres-array": "~3.0.1", - "postgres-bytea": "~3.0.0", - "postgres-date": "~2.0.1", - "postgres-interval": "^3.0.0", - "postgres-range": "^1.1.1" - } - }, - "postgres-array": { - "version": "3.0.2", - "dev": true - }, - "postgres-bytea": { - "version": "3.0.0", - "dev": true, - "requires": { - "obuf": "~1.1.2" - } - }, - "postgres-date": { - "version": "2.0.1", - "dev": true - }, - "postgres-interval": { - "version": "3.0.0", - "dev": true - } - } - }, - "@types/pug": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", - "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", - "dev": true - }, - "@types/qs": { - "version": "6.9.7" - }, - "@types/range-parser": { - "version": "1.2.4" - }, - "@types/recursive-readdir": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@types/recursive-readdir/-/recursive-readdir-2.2.4.tgz", - "integrity": "sha512-84REEGT3lcgopvpkmGApzmU5UEG0valme5rQS/KGiguTkJ70/Au8UYZTyrzoZnY9svuX9351+1uvrRPzWDD/uw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", - "dev": true - }, - "@types/send": { - "version": "0.17.1", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.13.10", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/shimmer": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.0.5.tgz", - "integrity": "sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==" - }, - "@types/simple-oauth2": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@types/simple-oauth2/-/simple-oauth2-5.0.7.tgz", - "integrity": "sha512-8JbWVJbiTSBQP/7eiyGKyXWAqp3dKQZpaA+pdW16FCi32ujkzRMG8JfjoAzdWt6W8U591ZNdHcPtP2D7ILTKuA==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "dev": true - }, - "@types/tunnel": { - "version": "0.0.3", - "requires": { - "@types/node": "*" - } - }, - "@types/validator": { - "version": "13.11.8", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.8.tgz", - "integrity": "sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ==", - "dev": true - }, - "@types/yargs": { - "version": "17.0.24", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", - "integrity": "sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/type-utils": "6.18.1", - "@typescript-eslint/utils": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/parser": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.1.tgz", - "integrity": "sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/typescript-estree": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", - "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1" - } - }, - "@typescript-eslint/type-utils": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.1.tgz", - "integrity": "sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "6.18.1", - "@typescript-eslint/utils": "6.18.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/types": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", - "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", - "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "@typescript-eslint/utils": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", - "integrity": "sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/typescript-estree": "6.18.1", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", - "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.18.1", - "eslint-visitor-keys": "^3.4.1" - } - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==" - }, - "acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "requires": {} - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.2.0", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "app-root-path": { - "version": "3.1.0" - }, - "applicationinsights": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.9.2.tgz", - "integrity": "sha512-wlDiD7v0BQNM8oNzsf9C836R5ze25u+CuCEZsbA5xMIXYYBxkqkWE/mo9GFJM7rsKaiGqpxEwWmePHKD2Lwy2w==", - "requires": { - "@azure/core-auth": "^1.5.0", - "@azure/core-rest-pipeline": "1.10.1", - "@azure/core-util": "1.2.0", - "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.5", - "@microsoft/applicationinsights-web-snippet": "^1.0.1", - "@opentelemetry/api": "^1.7.0", - "@opentelemetry/core": "^1.19.0", - "@opentelemetry/sdk-trace-base": "^1.19.0", - "@opentelemetry/semantic-conventions": "^1.19.0", - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "1.1.1", -<<<<<<< HEAD - "diagnostic-channel-publishers": "1.0.7" -======= - "diagnostic-channel-publishers": "1.0.8" - }, - "dependencies": { - "@azure/core-rest-pipeline": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz", - "integrity": "sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.4.0", - "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "form-data": "^4.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - } - }, - "@azure/core-util": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.2.0.tgz", - "integrity": "sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - } - }, - "@opentelemetry/api": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", - "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==" - } ->>>>>>> upstream/main - } - }, - "arg": { - "version": "4.1.3", - "dev": true - }, - "argparse": { - "version": "2.0.1" - }, - "array-flatten": { - "version": "1.1.1" - }, - "array-timsort": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", - "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "asap": { - "version": "2.0.6" - }, - "assert-never": { - "version": "1.2.1" - }, - "async-hook-jl": { - "version": "1.7.6", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1" - } - } - }, - "async-prompt": { - "version": "1.0.1", - "requires": { - "keypress": "~0.2.1" - } - }, - "asynckit": { - "version": "0.4.0" - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", - "requires": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "requires": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "babel-walk": { - "version": "3.0.0-canary-5", - "requires": { - "@babel/types": "^7.9.6" - } - }, - "balanced-match": { - "version": "1.0.2" - }, - "base64-js": { - "version": "1.5.1" - }, - "base64url": { - "version": "3.0.1" - }, - "basic-auth": { - "version": "2.0.1", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "before-after-hook": { - "version": "2.2.2" - }, -<<<<<<< HEAD - "big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "dev": true - }, -======= ->>>>>>> upstream/main - "body-parser": { - "version": "1.20.2", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browserslist": { - "version": "4.21.5", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" - } - }, - "bs-logger": { - "version": "0.2.6", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==" - }, - "buffer": { - "version": "6.0.3", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1" - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-writer": { - "version": "2.0.0" - }, - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true - }, - "builtins": { - "version": "5.0.1", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "bunyan": { - "version": "1.8.15", - "requires": { - "dtrace-provider": "~0.8", - "moment": "^2.19.3", - "mv": "~2", - "safe-json-stringify": "~1" - } - }, - "bytes": { - "version": "3.1.2" - }, - "cache-manager": { - "version": "3.6.3", - "requires": { - "async": "3.2.3", - "lodash.clonedeep": "^4.5.0", - "lru-cache": "6.0.0" - }, - "dependencies": { - "async": { - "version": "3.2.3" - } - } - }, - "call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "requires": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - } - }, - "callsites": { - "version": "3.1.0", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001486", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chalk-template": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", - "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", - "dev": true, - "requires": { - "chalk": "^5.2.0" - }, - "dependencies": { - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - } - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "character-parser": { - "version": "2.2.0", - "requires": { - "is-regex": "^1.0.3" - } - }, - "ci-info": { - "version": "3.8.0", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" - }, - "clear-module": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz", - "integrity": "sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==", - "dev": true, - "requires": { - "parent-module": "^2.0.0", - "resolve-from": "^5.0.0" - } - }, - "cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, - "requires": { - "restore-cursor": "^4.0.0" - } - }, - "cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", - "dev": true, - "requires": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - } - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1" - } - } - }, - "cluster-key-slot": { - "version": "1.1.2" - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "code-block-writer": { - "version": "11.0.3", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true - }, - "color-contrast-checker": { - "version": "2.1.0" - }, - "color-convert": { - "version": "2.0.1", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "dev": true - }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true - }, - "comment-json": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz", - "integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==", - "dev": true, - "requires": { - "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", - "esprima": "^4.0.1", - "has-own-prop": "^2.0.0", - "repeat-string": "^1.6.1" - } - }, - "compressible": { - "version": "2.0.18", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "bytes": { - "version": "3.0.0" - }, - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - } - } - }, - "concat-map": { - "version": "0.0.1" - }, - "configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "dev": true, - "requires": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - }, - "dependencies": { - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - } - } - }, - "connect-redis": { - "version": "7.1.0", - "requires": {} - }, - "constantinople": { - "version": "4.0.1", - "requires": { - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.1" - } - }, - "content-disposition": { - "version": "0.5.4", - "requires": { - "safe-buffer": "5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "content-type": { - "version": "1.0.5" - }, - "continuation-local-storage": { - "version": "3.2.1", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "convert-source-map": { - "version": "2.0.0", - "dev": true - }, - "cookie": { - "version": "0.5.0" - }, - "cookie-signature": { - "version": "1.0.6" - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "cors": { - "version": "2.8.5", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - } - }, - "create-require": { - "version": "1.1.1", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "dev": true, - "requires": { - "type-fest": "^1.0.1" - }, - "dependencies": { - "type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true - } - } - }, - "cspell": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.3.2.tgz", - "integrity": "sha512-V8Ub3RO/a5lwSsltW/ib3Z3G/sczKtSpBBN1JChzbSCfEgaY2mJY8JW0BpkSV+Ug6uJitpXNOOaxa3Xr489i7g==", - "dev": true, - "requires": { - "@cspell/cspell-json-reporter": "8.3.2", - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-types": "8.3.2", - "@cspell/dynamic-import": "8.3.2", - "chalk": "^5.3.0", - "chalk-template": "^1.1.0", - "commander": "^11.1.0", - "cspell-gitignore": "8.3.2", - "cspell-glob": "8.3.2", - "cspell-io": "8.3.2", - "cspell-lib": "8.3.2", - "fast-glob": "^3.3.2", - "fast-json-stable-stringify": "^2.1.0", - "file-entry-cache": "^8.0.0", - "get-stdin": "^9.0.0", - "semver": "^7.5.4", - "strip-ansi": "^7.1.0", - "vscode-uri": "^3.0.8" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - }, - "file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "requires": { - "flat-cache": "^4.0.0" - } - }, - "flat-cache": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.0.tgz", - "integrity": "sha512-EryKbCE/wxpxKniQlyas6PY1I9vwtF3uCBweX+N8KYTCn3Y12RTGtQAJ/bd5pl7kxUAc8v/R3Ake/N17OZiFqA==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.4", - "rimraf": "^5.0.5" - } - }, - "glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "requires": { - "glob": "^10.3.7" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "cspell-config-lib": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.3.2.tgz", - "integrity": "sha512-Wc98XhBNLwDxnxCzMtgRJALI9a69cu3C5Gf1rGjNTKSFo9JYiQmju0Ur3z25Pkx9Sa86f+2IjvNCf33rUDSoBQ==", - "dev": true, - "requires": { - "@cspell/cspell-types": "8.3.2", - "comment-json": "^4.2.3", - "yaml": "^2.3.4" - } - }, - "cspell-dictionary": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.3.2.tgz", - "integrity": "sha512-xyK95hO2BMPFxIo8zBwGml8035qOxSBdga1BMhwW/p2wDrQP8S4Cdm/54//tCDmKn6uRkFQvyOfWGaX2l8WMEg==", - "dev": true, - "requires": { - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-types": "8.3.2", - "cspell-trie-lib": "8.3.2", - "fast-equals": "^5.0.1", - "gensequence": "^6.0.0" - } - }, - "cspell-gitignore": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.3.2.tgz", - "integrity": "sha512-3Qc9P5BVvl/cg//s2s+zIMGKcoH5v7oOtRgwn4UQry8yiyo19h0tiTKkSR574FMhF5NtcShTnwIwPSIXVBPFHA==", - "dev": true, - "requires": { - "cspell-glob": "8.3.2", - "find-up-simple": "^1.0.0" - } - }, - "cspell-glob": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.3.2.tgz", - "integrity": "sha512-KtIFxE+3l5dGEofND4/CdZffXP8XN1+XGQKxJ96lIzWsc01mkotfhxTkla6mgvfH039t7BsY/SWv0460KyGslQ==", - "dev": true, - "requires": { - "micromatch": "^4.0.5" - } - }, - "cspell-grammar": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.3.2.tgz", - "integrity": "sha512-tYCkOmRzJe1a6/R+8QGSwG7TwTgznLPqsHtepKzLmnS4YX54VXjKRI9zMARxXDzUVfyCSVdW5MyiY/0WTNoy+A==", - "dev": true, - "requires": { - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-types": "8.3.2" - } - }, - "cspell-io": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.3.2.tgz", - "integrity": "sha512-WYpKsyBCQP0SY4gXnhW5fPuxcYchKYKG1PIXVV3ezFU4muSgW6GuLNbGuSfwv/8YNXRgFSN0e3hYH0rdBK2Aow==", - "dev": true, - "requires": { - "@cspell/cspell-service-bus": "8.3.2" - } - }, - "cspell-lib": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.3.2.tgz", - "integrity": "sha512-wTvdaev/TyGB/ln6CVD1QbVs2D7/+QiajQ67S7yj1suLHM6YcNQQb/5sPAM8VPtj0E7PgwgPXf3bq18OtPvnFg==", - "dev": true, - "requires": { - "@cspell/cspell-bundled-dicts": "8.3.2", - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-resolver": "8.3.2", - "@cspell/cspell-types": "8.3.2", - "@cspell/dynamic-import": "8.3.2", - "@cspell/strong-weak-map": "8.3.2", - "clear-module": "^4.1.2", - "comment-json": "^4.2.3", - "configstore": "^6.0.0", - "cspell-config-lib": "8.3.2", - "cspell-dictionary": "8.3.2", - "cspell-glob": "8.3.2", - "cspell-grammar": "8.3.2", - "cspell-io": "8.3.2", - "cspell-trie-lib": "8.3.2", - "fast-equals": "^5.0.1", - "gensequence": "^6.0.0", - "import-fresh": "^3.3.0", - "resolve-from": "^5.0.0", - "vscode-languageserver-textdocument": "^1.0.11", - "vscode-uri": "^3.0.8" - } - }, - "cspell-trie-lib": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.3.2.tgz", - "integrity": "sha512-8qh2FqzkLMwzlTlvO/5Z+89fhi30rrfekocpight/BmqKbE2XFJQD7wS2ml24e7q/rdHJLXVpJbY/V5mByucCA==", - "dev": true, - "requires": { - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-types": "8.3.2", - "gensequence": "^6.0.0" - } - }, - "debug": { - "version": "4.3.4", - "requires": { - "ms": "2.1.2" - } - }, - "dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", - "dev": true, - "requires": {} - }, - "deeks": { - "version": "2.6.0" - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.3.1" - }, -<<<<<<< HEAD - "default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "requires": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "dependencies": { - "execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - } - }, - "human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - } - } - }, - "default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "requires": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - } - }, -======= ->>>>>>> upstream/main - "define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "requires": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - } - }, - "define-lazy-prop": { - "version": "2.0.0" - }, - "delayed-stream": { - "version": "1.0.0" - }, - "depd": { - "version": "2.0.0" - }, - "deprecation": { - "version": "2.3.1" - }, - "destroy": { - "version": "1.2.0" - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diagnostic-channel": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz", - "integrity": "sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==", - "requires": { - "semver": "^7.5.3" - } - }, - "diagnostic-channel-publishers": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.8.tgz", - "integrity": "sha512-HmSm9hXxSPxA9BaLGY98QU1zsdjeCk113KjAYGPCen1ZP6mhVaTPzHd6UYv5r21DnWANi+f+NyPOHruGT9jpqQ==", - "requires": {} - }, - "diff": { - "version": "4.0.2", - "dev": true - }, - "diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doc-path": { - "version": "3.0.6" - }, - "doctrine": { - "version": "3.0.0", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "doctypes": { - "version": "1.1.0" - }, - "dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" - }, - "dtrace-provider": { - "version": "0.8.8", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "ee-first": { - "version": "1.1.1" - }, - "electron-to-chromium": { - "version": "1.4.392", - "dev": true - }, - "emitter-listener": { - "version": "1.1.2", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true - }, - "emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2" - }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-promise": { - "version": "4.2.8" - }, - "escalade": { - "version": "3.1.1", - "dev": true - }, - "escape-html": { - "version": "1.0.3" - }, - "escape-string-regexp": { - "version": "4.0.0", - "dev": true - }, - "eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - } - }, - "eslint-compat-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", - "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", - "dev": true, - "requires": {} - }, - "eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "requires": {} - }, - "eslint-plugin-es-x": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz", - "integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.1.2" - } - }, - "eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.5.0", - "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", - "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" - } - }, - "eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esprima": { - "version": "4.0.1", - "dev": true - }, - "esquery": { - "version": "1.5.0", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "dev": true - }, - "etag": { - "version": "1.8.1" - }, - "eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true - }, - "events": { - "version": "3.3.0" - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - } - }, - "express": { - "version": "4.18.2", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "body-parser": { - "version": "1.20.1", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - }, - "raw-body": { - "version": "2.5.1", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "express-async-handler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", - "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" - }, - "express-session": { - "version": "1.17.3", - "requires": { - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.2.1", - "uid-safe": "~2.1.5" - }, - "dependencies": { - "cookie": { - "version": "0.4.2" - }, - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "express-sslify": { - "version": "1.2.0" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "dev": true - }, - "fast-equals": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", - "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", - "dev": true - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.1.1" - }, - "fast-xml-parser": { - "version": "4.2.2", - "requires": { - "strnum": "^1.0.5" - } - }, - "fastq": { - "version": "1.15.0", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-size": { - "version": "1.0.0" - }, - "fill-range": { - "version": "7.0.1", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.2.0", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - } - } - }, - "find-up": { - "version": "5.0.0", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "find-up-simple": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", - "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", - "dev": true - }, - "flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true - }, - "follow-redirects": { -<<<<<<< HEAD - "version": "1.15.2" -======= - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==" ->>>>>>> upstream/main - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "dependencies": { - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - } - } - }, - "form-data": { - "version": "4.0.0", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0" - }, - "fresh": { - "version": "0.5.2" - }, - "fs.realpath": { - "version": "1.0.0" - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "generic-pool": { - "version": "3.9.0" - }, - "gensequence": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-6.0.0.tgz", - "integrity": "sha512-8WwuywE9pokJRAcg2QFR/plk3cVPebSUqRPzpGQh3WQ0wIiHAw+HyOQj5IuHyUTQBHpBKFoB2JUMu9zT3vJ16Q==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "requires": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-package-type": { - "version": "0.1.0", - "dev": true - }, - "get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", - "dev": true, - "requires": { - "resolve-pkg-maps": "^1.0.0" - } - }, - "github-username-regex": { - "version": "1.0.0" - }, - "glob": { - "version": "7.2.0", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "global-directory": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", - "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", - "dev": true, - "requires": { - "ini": "4.1.1" - } - }, - "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" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.10" - }, - "graphemer": { - "version": "1.4.0", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "dev": true - }, - "has-own-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", - "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "requires": { - "get-intrinsic": "^1.2.2" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" - }, - "has-symbols": { - "version": "1.0.3" - }, - "has-tostringtag": { - "version": "1.0.0", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "hsts": { - "version": "2.2.0", - "requires": { - "depd": "2.0.0" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-proxy-agent": { - "version": "5.0.0", - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "husky": { - "version": "8.0.3", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1" - }, - "ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "parent-module": { - "version": "1.0.1", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "dev": true - } - } - }, - "import-in-the-middle": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz", - "integrity": "sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==", - "requires": { - "acorn": "^8.8.2", - "acorn-import-assertions": "^1.9.0", - "cjs-module-lexer": "^1.2.2", - "module-details-from-path": "^1.0.3" - } - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4" - }, - "ini": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1" - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1" - }, - "is-buffer": { - "version": "2.0.5" - }, - "is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "requires": { - "builtin-modules": "^3.3.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "requires": { - "hasown": "^2.0.0" - } - }, - "is-docker": { - "version": "2.2.1" - }, - "is-expression": { - "version": "4.0.0", - "requires": { - "acorn": "^7.1.1", - "object-assign": "^4.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1" - } - } - }, - "is-extglob": { - "version": "2.1.1", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "dev": true - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "dev": true - }, - "is-promise": { - "version": "2.2.2" - }, - "is-regex": { - "version": "1.1.4", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "requires": { - "which-typed-array": "^1.1.11" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "requires": { - "is-docker": "^2.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "requires": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - } - }, - "jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - } - }, - "jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "requires": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - } - }, - "jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - } - }, - "jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true - }, - "jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-junit": { - "version": "16.0.0", - "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "strip-ansi": "^6.0.1", - "uuid": "^8.3.2", - "xml": "^1.0.1" - } - }, - "jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, - "requires": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true - }, - "jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "requires": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - } - }, - "jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - } - }, - "jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - } - }, - "jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "requires": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "joi": { - "version": "17.9.2", - "requires": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - }, - "dependencies": { - "@hapi/hoek": { - "version": "9.3.0" - } - } - }, - "jose": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", - "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==" - }, - "js-stringify": { - "version": "1.0.2" - }, - "js-tokens": { - "version": "4.0.0", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "requires": { - "argparse": "^2.0.1" - } - }, - "jsbi": { - "version": "3.2.5" - }, - "jsesc": { - "version": "2.5.2", - "dev": true - }, - "json-2-csv": { - "version": "3.18.0", - "requires": { - "deeks": "2.6.0", - "doc-path": "3.0.6" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2" - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true - }, - "json5": { - "version": "2.2.3", - "dev": true - }, - "jsonc": { - "version": "2.0.0", - "requires": { - "fast-safe-stringify": "^2.0.6", - "graceful-fs": "^4.1.15", - "mkdirp": "^0.5.1", - "parse-json": "^4.0.0", - "strip-bom": "^4.0.0", - "strip-json-comments": "^3.0.1" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.6", - "requires": { - "minimist": "^1.2.6" - } - }, - "parse-json": { - "version": "4.0.0", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } - } - }, - "jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "dependencies": { - "jwa": { - "version": "1.4.1", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "jssha": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.1.tgz", - "integrity": "sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==" - }, - "jstransformer": { - "version": "1.0.0", - "requires": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" - } - }, - "jwa": { - "version": "2.0.0", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jwks-rsa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", - "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", - "requires": { - "@types/express": "^4.17.17", - "@types/jsonwebtoken": "^9.0.2", - "debug": "^4.3.4", - "jose": "^4.14.6", - "limiter": "^1.1.5", - "lru-memoizer": "^2.2.0" - } - }, - "jws": { - "version": "4.0.0", - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "keypress": { - "version": "0.2.1" - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "language-map": { - "version": "1.5.0" - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", - "dev": true - }, - "limiter": { - "version": "1.1.5" - }, - "lines-and-columns": { - "version": "1.2.4", - "dev": true - }, - "linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dev": true, - "requires": { - "uc.micro": "^2.0.0" - } - }, - "lint-staged": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", - "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", - "dev": true, - "requires": { - "chalk": "5.3.0", - "commander": "11.1.0", - "debug": "4.3.4", - "execa": "8.0.1", - "lilconfig": "3.0.0", - "listr2": "8.0.0", - "micromatch": "4.0.5", - "pidtree": "0.6.0", - "string-argv": "0.3.2", - "yaml": "2.3.4" - }, - "dependencies": { - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - }, - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - } - } - }, - "listr2": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", - "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", - "dev": true, - "requires": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", - "rfdc": "^1.3.0", - "wrap-ansi": "^9.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21" - }, - "lodash.clonedeep": { - "version": "4.5.0" - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "lodash.memoize": { - "version": "4.1.2", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "dev": true - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, - "log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", - "dev": true, - "requires": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", - "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", - "dev": true, - "requires": { - "type-fest": "^3.0.0" - } - }, - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", - "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", - "dev": true, - "requires": { - "get-east-asian-width": "^1.0.0" - } - }, - "slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", - "dev": true, - "requires": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true - } - } - }, - "long": { - "version": "5.2.0" - }, - "lru-cache": { - "version": "6.0.0", - "requires": { - "yallist": "^4.0.0" - } - }, - "lru-memoizer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", - "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", - "requires": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "~4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", - "requires": { - "pseudomap": "^1.0.1", - "yallist": "^2.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" - } - } - }, - "luxon": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", - "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==" - }, - "make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "make-error": { - "version": "1.3.6", - "dev": true - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "markdown-it": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.0.0.tgz", - "integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==", - "dev": true, - "requires": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.0.0" - } - }, - "markdownlint": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.33.0.tgz", - "integrity": "sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==", - "dev": true, - "requires": { - "markdown-it": "14.0.0", - "markdownlint-micromark": "0.1.8" - } - }, - "markdownlint-cli2": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.12.0.tgz", - "integrity": "sha512-5nddNaPY1WC7BE1mkF8fiEkRDW8XbODwqYBPL3eyvFh7tLk74no+P8JRbCjghF7ozahCW5pF0TZ3ZS30m9H1Eg==", - "dev": true, - "requires": { - "globby": "14.0.0", - "markdownlint": "0.33.0", - "markdownlint-cli2-formatter-default": "0.0.4", - "micromatch": "4.0.5", - "strip-json-comments": "5.0.1", - "yaml": "2.3.4" - }, - "dependencies": { - "globby": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", - "dev": true, - "requires": { - "@sindresorhus/merge-streams": "^1.0.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" - } - }, - "path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true - }, - "slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true - }, - "strip-json-comments": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", - "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", - "dev": true - } - } - }, - "markdownlint-cli2-formatter-default": { - "version": "0.0.4", - "dev": true, - "requires": {} - }, - "markdownlint-micromark": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.8.tgz", - "integrity": "sha512-1ouYkMRo9/6gou9gObuMDnvZM8jC/ly3QCFQyoSPCS2XV1ZClU0xpKbL1Ar3bWWRT1RnBZkWUEiNKrI2CwiBQA==", - "dev": true - }, - "mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true - }, - "media-typer": { - "version": "0.3.0" - }, - "memory-cache": { - "version": "0.2.0" - }, - "merge-descriptors": { - "version": "1.0.1" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "dev": true - }, - "methods": { - "version": "1.1.2" - }, - "micromatch": { - "version": "4.0.5", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0" - }, - "mime-db": { - "version": "1.52.0" - }, - "mime-types": { - "version": "2.1.35", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6" - }, - "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "dev": true - }, - "module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" - }, - "moment": { -<<<<<<< HEAD - "version": "2.29.4" -======= - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==" ->>>>>>> upstream/main - }, - "morgan": { - "version": "1.10.0", - "requires": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - } - } - }, - "ms": { - "version": "2.1.2" - }, - "mv": { - "version": "2.1.1", - "optional": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "optional": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "mkdirp": { - "version": "0.5.6", - "optional": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "rimraf": { - "version": "2.4.5", - "optional": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.15.0", - "optional": true - }, - "natural-compare": { - "version": "1.4.0", - "dev": true - }, - "ncp": { - "version": "2.0.0", - "optional": true - }, - "negotiator": { - "version": "0.6.3" - }, - "node-abort-controller": { - "version": "3.1.1" - }, - "node-fetch": { - "version": "2.6.11", - "requires": { - "whatwg-url": "^5.0.0" - }, - "dependencies": { - "tr46": { - "version": "0.0.3" - }, - "webidl-conversions": { - "version": "3.0.1" - }, - "whatwg-url": { - "version": "5.0.0", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } - } - }, - "node-forge": { - "version": "1.3.1" - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node-jose": { - "version": "2.2.0", - "requires": { - "base64url": "^3.0.1", - "buffer": "^6.0.3", - "es6-promise": "^4.2.8", - "lodash": "^4.17.21", - "long": "^5.2.0", - "node-forge": "^1.2.1", - "pako": "^2.0.4", - "process": "^0.11.10", - "uuid": "^9.0.0" - }, - "dependencies": { - "uuid": { - "version": "9.0.0" - } - } - }, - "node-releases": { - "version": "2.0.10", - "dev": true - }, - "nodemailer": { - "version": "6.9.8", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.8.tgz", - "integrity": "sha512-cfrYUk16e67Ks051i4CntM9kshRYei1/o/Gi8K1d+R34OIs21xdFnW7Pt7EucmVKA0LKtqUGNcjMZ7ehjl49mQ==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "oauth": { - "version": "0.9.15" - }, - "object-assign": { - "version": "4.1.1" - }, - "object-inspect": { - "version": "1.12.3" - }, - "object-path": { - "version": "0.11.8" - }, - "obuf": { - "version": "1.1.2", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2" - }, - "once": { - "version": "1.4.0", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "8.4.0", - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "p-limit": { - "version": "3.1.0", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-try": { - "version": "2.2.0", - "dev": true - }, - "packet-reader": { - "version": "1.0.0" - }, - "pako": { - "version": "2.0.4" - }, - "parent-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", - "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", - "dev": true, - "requires": { - "callsites": "^3.1.0" - } - }, - "parse-json": { - "version": "5.2.0", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parseurl": { - "version": "1.3.3" - }, - "passport": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", - "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", - "requires": { - "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" - } - }, - "passport-azure-ad": { - "version": "4.3.5", - "requires": { - "async": "^3.2.3", - "base64url": "^3.0.0", - "bunyan": "^1.8.14", - "cache-manager": "^3.6.1", - "https-proxy-agent": "^5.0.0", - "jws": "^3.1.3", - "lodash": "^4.11.2", - "node-jose": "^2.2.0", - "oauth": "0.9.15", - "passport": "^0.6.0", - "valid-url": "^1.0.6" - }, - "dependencies": { - "async": { - "version": "3.2.4" - }, - "jwa": { - "version": "1.4.1", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "passport": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", - "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", - "requires": { - "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" - } - } - } - }, - "passport-github": { - "version": "1.1.0", - "requires": { - "passport-oauth2": "1.x.x" - } - }, - "passport-oauth2": { - "version": "1.6.1", - "requires": { - "base64url": "3.x.x", - "oauth": "0.9.x", - "passport-strategy": "1.x.x", - "uid2": "0.0.x", - "utils-merge": "1.x.x" - } - }, - "passport-strategy": { - "version": "1.0.0" - }, - "path-browserify": { - "version": "1.0.1", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1" - }, - "path-key": { - "version": "3.1.1", - "dev": true - }, - "path-parse": { - "version": "1.0.7" - }, - "path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "requires": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true - } - } - }, - "path-to-regexp": { - "version": "0.1.7" - }, - "path-type": { - "version": "4.0.0", - "dev": true - }, - "pause": { - "version": "0.0.1" - }, - "pg": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", - "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", - "requires": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-cloudflare": "^1.1.1", - "pg-connection-string": "^2.6.2", - "pg-pool": "^3.6.1", - "pg-protocol": "^1.6.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" - } - }, - "pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", - "optional": true - }, - "pg-connection-string": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", - "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" - }, - "pg-escape": { - "version": "0.2.0" - }, - "pg-int8": { - "version": "1.0.1" - }, - "pg-numeric": { - "version": "1.0.2", - "dev": true - }, - "pg-pool": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", - "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", - "requires": {} - }, - "pg-protocol": { - "version": "1.6.0" - }, - "pg-types": { - "version": "2.2.0", - "requires": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - } - }, - "pgpass": { - "version": "1.0.5", - "requires": { - "split2": "^4.1.0" - } - }, - "picocolors": { - "version": "1.0.0", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "dev": true - }, - "pidtree": { - "version": "0.6.0", - "dev": true - }, - "pirates": { - "version": "4.0.5", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "postgres-array": { - "version": "2.0.0" - }, - "postgres-bytea": { - "version": "1.0.0" - }, - "postgres-date": { - "version": "1.0.7" - }, - "postgres-interval": { - "version": "1.2.0", - "requires": { - "xtend": "^4.0.0" - } - }, - "postgres-range": { - "version": "1.1.3", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", - "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", - "dev": true - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "dev": true, - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "requires": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "dev": true - } - } - }, - "priorityqueuejs": { - "version": "1.0.0" - }, - "process": { - "version": "0.11.10" - }, - "promise": { - "version": "7.3.1", - "requires": { - "asap": "~2.0.3" - } - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "proxy-addr": { - "version": "2.0.7", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "proxy-from-env": { - "version": "1.1.0" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" - }, - "pug": { - "version": "3.0.2", - "requires": { - "pug-code-gen": "^3.0.2", - "pug-filters": "^4.0.0", - "pug-lexer": "^5.0.1", - "pug-linker": "^4.0.0", - "pug-load": "^3.0.0", - "pug-parser": "^6.0.0", - "pug-runtime": "^3.0.1", - "pug-strip-comments": "^2.0.0" - } - }, - "pug-attrs": { - "version": "3.0.0", - "requires": { - "constantinople": "^4.0.1", - "js-stringify": "^1.0.2", - "pug-runtime": "^3.0.0" - } - }, - "pug-code-gen": { - "version": "3.0.2", - "requires": { - "constantinople": "^4.0.1", - "doctypes": "^1.1.0", - "js-stringify": "^1.0.2", - "pug-attrs": "^3.0.0", - "pug-error": "^2.0.0", - "pug-runtime": "^3.0.0", - "void-elements": "^3.1.0", - "with": "^7.0.0" - } - }, - "pug-error": { - "version": "2.0.0" - }, - "pug-filters": { - "version": "4.0.0", - "requires": { - "constantinople": "^4.0.1", - "jstransformer": "1.0.0", - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0", - "resolve": "^1.15.1" - } - }, - "pug-lexer": { - "version": "5.0.1", - "requires": { - "character-parser": "^2.2.0", - "is-expression": "^4.0.0", - "pug-error": "^2.0.0" - } - }, - "pug-linker": { - "version": "4.0.0", - "requires": { - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0" - } - }, - "pug-load": { - "version": "3.0.0", - "requires": { - "object-assign": "^4.1.1", - "pug-walk": "^2.0.0" - } - }, - "pug-parser": { - "version": "6.0.0", - "requires": { - "pug-error": "^2.0.0", - "token-stream": "1.0.0" - } - }, - "pug-runtime": { - "version": "3.0.1" - }, - "pug-strip-comments": { - "version": "2.0.0", - "requires": { - "pug-error": "^2.0.0" - } - }, - "pug-walk": { - "version": "2.0.0" - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true - }, - "pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "requires": { - "side-channel": "^1.0.4" - } - }, - "queue-microtask": { - "version": "1.2.3", - "dev": true - }, - "random-bytes": { - "version": "1.0.0" - }, - "range-parser": { - "version": "1.2.1" - }, - "raw-body": { - "version": "2.5.2", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "dev": true - }, - "recursive-readdir": { - "version": "2.2.3", - "requires": { - "minimatch": "^3.0.5" - } - }, - "redis": { - "version": "4.6.12", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.12.tgz", - "integrity": "sha512-41Xuuko6P4uH4VPe5nE3BqXHB7a9lkFL0J29AlxKaIfD6eWO8VO/5PDF9ad2oS+mswMsfFxaM5DlE3tnXT+P8Q==", - "requires": { - "@redis/bloom": "1.2.0", - "@redis/client": "1.5.13", - "@redis/graph": "1.1.1", - "@redis/json": "1.0.6", - "@redis/search": "1.1.6", - "@redis/time-series": "1.0.5" - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-in-the-middle": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz", - "integrity": "sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw==", - "requires": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.22.1" - } - }, - "resolve": { - "version": "1.22.2", - "requires": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "dev": true - }, - "resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true - }, - "resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true - }, - "restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "dev": true - }, - "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, - "rhea": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rhea/-/rhea-3.0.2.tgz", - "integrity": "sha512-0G1ZNM9yWin8VLvTxyISKH6KfR6gl1TW/1+5yMKPf2r1efhkzTLze09iFtT2vpDjuWIVtSmXz8r18lk/dO8qwQ==", - "requires": { - "debug": "^4.3.3" - } - }, - "rhea-promise": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rhea-promise/-/rhea-promise-3.0.1.tgz", - "integrity": "sha512-Fcqgml7lgoyi7fH1ClsSyFr/xwToijEN3rULFgrIcL+7EHeduxkWogFxNHjFzHf2YGScAckJDaDxS1RdlTUQYw==", - "requires": { - "debug": "^3.1.0", - "rhea": "^3.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "rimraf": { - "version": "3.0.2", - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.1.2" - }, - "safe-json-stringify": { - "version": "1.2.0", - "optional": true - }, - "safer-buffer": { - "version": "2.1.2" - }, - "sax": { - "version": "1.2.4" - }, - "secure-compare": { - "version": "3.0.1" - }, - "semaphore": { - "version": "1.1.0" - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "send": { - "version": "0.18.0", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0" - } - } - }, - "ms": { - "version": "2.1.3" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - } - } - }, - "serve-favicon": { - "version": "2.5.0", - "requires": { - "etag": "~1.8.1", - "fresh": "0.5.2", - "ms": "2.1.1", - "parseurl": "~1.3.2", - "safe-buffer": "5.1.1" - }, - "dependencies": { - "ms": { - "version": "2.1.1" - }, - "safe-buffer": { - "version": "5.1.1" - } - } - }, - "serve-static": { - "version": "1.15.0", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "requires": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - } - }, - "setprototypeof": { - "version": "1.2.0" - }, - "shebang-command": { - "version": "2.0.0", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "dev": true - }, - "shimmer": { - "version": "1.2.1" - }, - "side-channel": { - "version": "1.0.4", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "dev": true - }, - "simple-oauth2": { - "version": "5.0.0", - "requires": { - "@hapi/hoek": "^10.0.1", - "@hapi/wreck": "^18.0.0", - "debug": "^4.3.4", - "joi": "^17.6.4" - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "dev": true - }, - "slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "split2": { - "version": "4.1.0" - }, - "sprintf-js": { - "version": "1.0.3", - "dev": true - }, - "stack-chain": { - "version": "1.3.7" - }, - "stack-utils": { - "version": "2.0.6", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "dev": true - } - } - }, - "statuses": { - "version": "2.0.1" - }, - "stoppable": { - "version": "1.1.0" - }, - "string-argv": { - "version": "0.3.2", - "dev": true - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", - "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", - "dev": true, - "requires": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - } - } - }, - "strip-ansi": { - "version": "6.0.1", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1" - }, - "strnum": { - "version": "1.0.5" - }, - "supports-color": { - "version": "7.2.0", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0" - }, - "synckit": { -<<<<<<< HEAD - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.6.tgz", - "integrity": "sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA==", - "dev": true, - "requires": { - "@pkgr/utils": "^2.4.2", -======= - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", - "dev": true, - "requires": { - "@pkgr/core": "^0.1.0", ->>>>>>> upstream/main - "tslib": "^2.6.2" - } - }, - "test-exclude": { - "version": "6.0.0", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "dev": true - }, - "throat": { - "version": "6.0.2" - }, - "tmp": { - "version": "0.2.1", - "requires": { - "rimraf": "^3.0.0" - } - }, - "tmp-promise": { - "version": "3.0.3", - "requires": { - "tmp": "^0.2.0" - } - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0" - }, - "to-regex-range": { - "version": "5.0.1", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1" - }, - "token-stream": { - "version": "1.0.0" - }, - "true-myth": { - "version": "4.1.1", - "dev": true - }, - "ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", - "dev": true, - "requires": {} - }, - "ts-jest": { - "version": "29.1.1", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", - "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" - } - }, - "ts-morph": { - "version": "13.0.3", - "dev": true, - "requires": { - "@ts-morph/common": "~0.12.3", - "code-block-writer": "^11.0.0" - } - }, - "ts-node": { -<<<<<<< HEAD - "version": "10.9.1", -======= - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", ->>>>>>> upstream/main - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "ts-prune": { - "version": "0.10.3", - "dev": true, - "requires": { - "commander": "^6.2.1", - "cosmiconfig": "^7.0.1", - "json5": "^2.1.3", - "lodash": "^4.17.21", - "true-myth": "^4.1.0", - "ts-morph": "^13.0.1" - }, - "dependencies": { - "commander": { - "version": "6.2.1", - "dev": true - }, - "cosmiconfig": { - "version": "7.1.0", - "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" - } - }, - "yaml": { - "version": "1.10.2", - "dev": true - } - } - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "tunnel": { - "version": "0.0.6" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true - }, - "uc.micro": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.0.0.tgz", - "integrity": "sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==", - "dev": true - }, - "uid-safe": { - "version": "2.1.5", - "requires": { - "random-bytes": "~1.0.0" - } - }, - "uid2": { - "version": "0.0.4" - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true - }, - "unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "dev": true, - "requires": { - "crypto-random-string": "^4.0.0" - } - }, - "universal-github-app-jwt": { -<<<<<<< HEAD - "version": "1.1.1", -======= - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.2.tgz", - "integrity": "sha512-t1iB2FmLFE+yyJY9+3wMx0ejB+MQpEVkH0gQv7dR6FZyltyq+ZZO0uDpbopxhrZ3SLEO4dCEkIujOMldEQ2iOA==", ->>>>>>> upstream/main - "requires": { - "@types/jsonwebtoken": "^9.0.0", - "jsonwebtoken": "^9.0.2" - } - }, - "universal-user-agent": { - "version": "6.0.0" - }, - "unpipe": { - "version": "1.0.0" - }, - "update-browserslist-db": { - "version": "1.0.11", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "utils-merge": { - "version": "1.0.1" - }, - "uuid": { - "version": "8.3.2" - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "dev": true - }, - "v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - } - }, - "valid-url": { - "version": "1.0.9" - }, - "validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==" - }, - "vary": { - "version": "1.1.2" - }, - "void-elements": { - "version": "3.1.0" - }, - "vscode-languageserver-textdocument": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz", - "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==", - "dev": true - }, - "vscode-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", - "dev": true - }, - "walk-back": { - "version": "5.1.0" - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "which": { - "version": "2.0.2", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "with": { - "version": "7.0.2", - "requires": { - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "assert-never": "^1.2.1", - "babel-walk": "3.0.0-canary-5" - } - }, - "wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", - "dev": true, - "requires": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2" - }, - "write-file-atomic": { - "version": "4.0.2", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - }, - "xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", - "dev": true - }, - "xml": { - "version": "1.0.1", - "dev": true - }, - "xmlbuilder": { - "version": "11.0.1" - }, - "xtend": { - "version": "4.0.2" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0" - }, - "yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", - "dev": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "yargs-parser": { - "version": "21.1.1", - "dev": true - }, - "yn": { - "version": "3.1.1", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "dev": true - } } } From 067712a92d3a17ae99688e49be0f03ca0f7ec4be Mon Sep 17 00:00:00 2001 From: devoptimusprime Date: Tue, 13 Feb 2024 08:26:43 -0500 Subject: [PATCH 170/209] fix renamed octicons --- routes/org/index.ts | 5 ----- views/org/team/index.pug | 2 +- views/people/index.pug | 2 +- views/repos/index.pug | 4 ++-- views/repos/repo.pug | 2 +- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/routes/org/index.ts b/routes/org/index.ts index 94bf433c4..d66f45efb 100644 --- a/routes/org/index.ts +++ b/routes/org/index.ts @@ -6,12 +6,7 @@ import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -<<<<<<< HEAD -import { getProviders } from '../../transitional'; -======= - import { getProviders } from '../../lib/transitional'; ->>>>>>> upstream/main import { IAggregateUserSummary } from '../../business/user/aggregate'; import { TeamJoinApprovalEntity } from '../../business/entities/teamJoinApproval/teamJoinApproval'; import { Team } from '../../business'; diff --git a/views/org/team/index.pug b/views/org/team/index.pug index 8d1c1b683..d0e1f7329 100644 --- a/views/org/team/index.pug +++ b/views/org/team/index.pug @@ -355,7 +355,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('primitive-dot', 10) + != octicon('dot-fill', 10) = ' ' + repo.language if repo.stargazers_count li diff --git a/views/people/index.pug b/views/people/index.pug index 5266558b8..edaf41e3d 100644 --- a/views/people/index.pug +++ b/views/people/index.pug @@ -51,7 +51,7 @@ block content //-ul.nav.nav-pills li(class=(search.sort === 'Alphabet' ? 'active' : ''), title='Alphabetically sorted') a(href='?sort=Alphabet&tag=' + (tag ? tag : '') + (query.phrase ? '&q=' + query.phrase : '')) - != octicon('text-size', 20) + != octicon('typography', 20) | Name form.form-horizontal#entitySearch(style='margin-top:24px') diff --git a/views/repos/index.pug b/views/repos/index.pug index 8ffce2683..b97d557eb 100644 --- a/views/repos/index.pug +++ b/views/repos/index.pug @@ -81,7 +81,7 @@ block content li(class=(search.sort === 'Alphabet' ? 'active' : ''), title='Sort by repo name') a(href='?sort=Alphabet&tag=' + (specificTeamId ? '&teamRepos=' + specificTeamId : '') + (tag ? tag : '') + (query.tt ? '&tt=' + query.tt : '') + (query.phrase ? '&q=' + query.phrase : '')) //- i.glyphicon.glyphicon-sort-by-alphabet - != octicon('text-size', 20) + != octicon('typography', 20) | Name //-i.glyphicon.glyphicon-triangle-bottom li(class=(search.sort === 'Updated' ? 'active' : '')) @@ -248,7 +248,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('primitive-dot', 10) + != octicon('dot-fill', 10) = ' ' + repo.language if repo.stargazers_count li diff --git a/views/repos/repo.pug b/views/repos/repo.pug index ea86603d5..fb3172866 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -102,7 +102,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('primitive-dot', 10) + != octicon('dot-fill', 10) = ' ' + repo.language if repo.license && repo.license.featured && repo.license.name li From f1811f73f8ae21fa29a67239bbdd671fdc57369b Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:31:36 -0700 Subject: [PATCH 171/209] Uncommenting something probably super important. --- views/nav.pug | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/views/nav.pug b/views/nav.pug index 97ce212a6..6196acfef 100644 --- a/views/nav.pug +++ b/views/nav.pug @@ -51,13 +51,13 @@ mixin userAzure div.navbar.navbar-default.second-row-nav div.container div.navbar-header - //-button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='.nav-collapse') - //-button.navbar-toggle(type='button', data-toggle='collapse', data-target='.nav-collapse') + button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='.nav-collapse') + button.navbar-toggle(type='button', data-toggle='collapse', data-target='.nav-collapse') span.sr-only Toggle navigation span.icon-bar span.icon-bar span.icon-bar - //- a.navbar-brand(href='./')= page.folderMetadata.title + a.navbar-brand(href='./')= page.folderMetadata.title //nav.collapse.navbar-collapse.nav-collapse(role='navigation') nav(role='navigation') div.container(style='margin-top:24px;margin-bottom:12px') From 9329f756636b2c1318680b42acf4a8598567befb Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:33:11 -0700 Subject: [PATCH 172/209] One more uncomment --- views/nav.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/nav.pug b/views/nav.pug index 6196acfef..7e7c068e2 100644 --- a/views/nav.pug +++ b/views/nav.pug @@ -58,7 +58,7 @@ div.navbar.navbar-default.second-row-nav span.icon-bar span.icon-bar a.navbar-brand(href='./')= page.folderMetadata.title - //nav.collapse.navbar-collapse.nav-collapse(role='navigation') + nav.collapse.navbar-collapse.nav-collapse(role='navigation') nav(role='navigation') div.container(style='margin-top:24px;margin-bottom:12px') div.row(style=(user && !error && ossLink) ? 'margin-left:0' : 'margin-left:-30px') From c47296392465e04ac785b036a7f844a8361f6dfd Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 22 May 2024 18:30:16 +0000 Subject: [PATCH 173/209] expose the visibility property for search routes --- business/repository.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/business/repository.ts b/business/repository.ts index 1b601c459..f213ca64d 100644 --- a/business/repository.ts +++ b/business/repository.ts @@ -248,6 +248,7 @@ const safeEntityFieldsForJsonSend = [ 'stargazers_count', 'open_issues_count', 'id', + 'visibility' ]; const sortByLogin = (list) => { From 351acfcb65a9e7bad334027a5247e2fbba84a193 Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 22 May 2024 18:31:39 +0000 Subject: [PATCH 174/209] hydrate the repo model fully so expanded properties are available in the ui --- routes/reposPager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/reposPager.ts b/routes/reposPager.ts index 74156a51c..17e5c7fb2 100644 --- a/routes/reposPager.ts +++ b/routes/reposPager.ts @@ -213,7 +213,7 @@ export default asyncHandler(async function (req: IReposAppWithTeam, res: Respons await search.search(page, req.query.sort as string); - // await Promise.all(search.repos.map(repo => repo.getDetails())); + await Promise.all(search.repos.map(repo => repo.getDetails())); req.individualContext.webContext.render({ view: 'repos/', From d806a27f444d6f2204225dec7a964b4591d729ea Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 22 May 2024 18:36:34 +0000 Subject: [PATCH 175/209] add view sections to expose new properties for repo objects --- views/org/team/index.pug | 7 +++++-- views/repos/index.pug | 7 +++++-- views/repos/repo.pug | 7 +++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/views/org/team/index.pug b/views/org/team/index.pug index d0e1f7329..503250909 100644 --- a/views/org/team/index.pug +++ b/views/org/team/index.pug @@ -337,9 +337,12 @@ block content .repo(id=repo.name, style='padding-bottom:36px;display:block') h3 a(href='/' + localOrgName + '/repos/' + repo.name)= repo.name - if repo.private === true + if repo.visibility |   - .label.label-warning.shrink66(title='This is a private repository and not open source.') Private + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} + if repo.has_pages + |   + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages if repoPermissions && specificTeam = ' ' if repoPermissions.admin diff --git a/views/repos/index.pug b/views/repos/index.pug index b97d557eb..2c657276f 100644 --- a/views/repos/index.pug +++ b/views/repos/index.pug @@ -225,9 +225,12 @@ block content if showIds = repo.id + ' ' a(href='/' + localOrgName + '/repos/' + repo.name)= repo.name - if repo.private === true + if repo.visibility |   - .label.label-warning.shrink66(title='This is a private repository and not open source.') Private + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} + if repo.has_pages + |   + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages if repo.permissions && specificTeam = ' ' if repo.permissions.admin diff --git a/views/repos/repo.pug b/views/repos/repo.pug index fb3172866..fd3d575a7 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -75,9 +75,12 @@ block content - var hugeHeading = repo.name.length < 33 h1(class={huge: hugeHeading}) a(href='https://github.com/' + repo.full_name, target="_blank")= repo.name - if repo.private === true + if repo.visibility |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) Private + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} + if repo.has_pages + |   + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages h6= repo.full_name.replace('/' + repo.name, '') + ' organization' if repo.fork h6 From 2da162e5dd99a5aab7ca4ec563c7ad1b40694f1a Mon Sep 17 00:00:00 2001 From: Alex Williamson <9951123+DevOptimusPrime@users.noreply.github.com> Date: Wed, 22 May 2024 18:38:24 +0000 Subject: [PATCH 176/209] upgrade jquery dep to fix mobile ui buttons --- default-assets-package/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default-assets-package/package.json b/default-assets-package/package.json index 3ec400fe0..7990f1aff 100644 --- a/default-assets-package/package.json +++ b/default-assets-package/package.json @@ -26,7 +26,7 @@ "grunt-contrib-copy": "^1.0.0", "grunt-contrib-less": "^2.0.0", "grunt-exec": "3.0.0", - "jquery": "^3.4.0", + "jquery": "^3.5.1", "load-grunt-tasks": "^4.0.0", "octicons": "4.4.0", "timeago": "1.6.4" From d067eb6bf91bcf0d8133165aef40f3e7e4f0e380 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:07:18 -0700 Subject: [PATCH 177/209] Unbreaking new verson --- views/nav.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/nav.pug b/views/nav.pug index 7e7c068e2..0b13159d2 100644 --- a/views/nav.pug +++ b/views/nav.pug @@ -57,7 +57,7 @@ div.navbar.navbar-default.second-row-nav span.icon-bar span.icon-bar span.icon-bar - a.navbar-brand(href='./')= page.folderMetadata.title + // a.navbar-brand(href='./')= page.folderMetadata.title nav.collapse.navbar-collapse.nav-collapse(role='navigation') nav(role='navigation') div.container(style='margin-top:24px;margin-bottom:12px') From e5a0d3f061c3b5e5679beb027c8e7d784c146e63 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:32:32 -0700 Subject: [PATCH 178/209] Revert "Unbreaking new version" --- views/nav.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/nav.pug b/views/nav.pug index 0b13159d2..7e7c068e2 100644 --- a/views/nav.pug +++ b/views/nav.pug @@ -57,7 +57,7 @@ div.navbar.navbar-default.second-row-nav span.icon-bar span.icon-bar span.icon-bar - // a.navbar-brand(href='./')= page.folderMetadata.title + a.navbar-brand(href='./')= page.folderMetadata.title nav.collapse.navbar-collapse.nav-collapse(role='navigation') nav(role='navigation') div.container(style='margin-top:24px;margin-bottom:12px') From 844351aeb4479e30d20ff44f92b919b247a74adb Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:33:00 -0700 Subject: [PATCH 179/209] Revert "Staging" --- .cspell.json | 71 +- .editorconfig | 1 - .eslintrc.js | 7 +- .github/workflows/ci.yml | 4 +- .github/workflows/codeql-analysis.yml | 8 +- .github/workflows/container.yml | 4 +- .github/workflows/stale.yml | 2 +- .gitignore | 2 - ...int-cli2.jsonc => .markdownlint-cli2.jsonc | 3 +- .prettierrc.json | 1 - .secrets.env.example | 1 + .vscode/launch.json | 152 +- Dockerfile | 67 +- api/client/banner.ts | 8 +- api/client/context/administration/app.ts | 74 - .../context/administration/appInstallation.ts | 59 - api/client/context/administration/apps.ts | 128 - api/client/context/administration/index.ts | 25 +- .../administration/organization/index.ts | 9 +- .../administration/organization/settings.ts | 123 +- api/client/context/administration/types.ts | 44 - api/client/context/approvals.ts | 16 +- api/client/context/index.ts | 23 +- api/client/context/organization/index.ts | 54 +- api/client/context/organization/repo.ts | 8 +- .../context/organization/repoForkUnlock.ts | 22 +- api/client/context/organization/repos.ts | 21 +- api/client/context/organization/team.ts | 88 +- api/client/context/organization/teams.ts | 7 +- api/client/context/orgs.ts | 4 +- api/client/context/repos.ts | 7 +- api/client/context/sample.ts | 10 +- api/client/context/settings.ts | 48 - api/client/context/teams.ts | 7 +- api/client/index.ts | 20 +- api/client/linking.ts | 14 +- api/client/newOrgRepo.ts | 43 +- api/client/newRepo.ts | 6 +- api/client/news.ts | 8 +- api/client/organization/annotations.ts | 70 +- api/client/organization/index.ts | 34 +- api/client/organization/newRepoMetadata.ts | 8 +- api/client/organization/people.ts | 8 +- api/client/organization/repo.ts | 140 +- api/client/organization/repoPermissions.ts | 6 +- api/client/organization/repos.ts | 29 +- api/client/organization/team.ts | 33 +- api/client/organization/teams.ts | 16 +- api/client/organizations.ts | 161 +- api/client/people.ts | 24 +- api/client/peopleSearch.ts | 2 +- api/client/person.ts | 16 +- api/client/repos.ts | 8 +- api/client/session.ts | 6 +- api/client/teams.ts | 8 +- api/client/users.ts | 35 - api/createRepo.ts | 20 +- api/extension.ts | 30 +- api/index.ts | 24 +- api/jsonErrorHandler.ts | 5 +- api/people/index.ts | 2 +- api/people/link.ts | 6 +- api/people/links.ts | 67 +- api/people/unlink.ts | 12 +- api/webhook.ts | 8 +- app.ts | 156 + bin/www.ts | 6 +- business/account.ts | 48 +- business/application.ts | 42 +- business/collaborator.ts | 26 +- business/domains.ts | 27 +- business/enterprise.ts | 194 - .../githubApps}/appTokens.ts | 59 +- business/githubApps/index.ts | 151 + .../githubApps}/tokenManager.ts | 210 +- business/graphManager.ts | 2 +- business/operations/administration.ts | 2 +- business/operations/core.ts | 99 +- business/operations/index.ts | 328 +- business/operations/link.ts | 2 +- business/operations/unlinkMail.ts | 4 +- business/organization.ts | 301 +- business/organizationCopilot.ts | 126 - business/organizationProperties.ts | 198 - business/project.ts | 27 +- business/projectView.ts | 27 +- business/projects.ts | 27 +- business/queryCache.ts | 36 +- business/repoSearch.ts | 6 +- business/repository.ts | 243 +- business/repositoryActions.ts | 21 +- business/repositoryInvitation.ts | 77 - business/repositoryIssue.ts | 21 +- business/repositoryPermission.ts | 83 +- business/repositoryProject.ts | 22 +- business/repositoryProjectCard.ts | 19 +- business/repositoryProjectColumn.ts | 16 +- business/repositoryProperties.ts | 77 - business/repositoryPullRequest.ts | 21 +- business/team.ts | 42 +- business/teamMember.ts | 8 +- business/teamPermission.ts | 70 +- business/teamRepositoryPermission.ts | 47 +- business/user/aggregate.ts | 8 +- business/user/index.ts | 4 +- config/brand.types.ts | 1 + config/continuousDeployment.types.ts | 3 - config/debug.json | 4 +- config/debug.types.ts | 2 - config/github.operations.json | 1 + config/github.organizations.types.ts | 1 - config/npm.publishing.json | 6 + config/npm.publishing.types.ts | 17 + config/npm.types.ts | 4 +- config/webServer.json | 13 +- config/webServer.types.ts | 11 - default-assets-package/package-lock.json | 1144 +- default-assets-package/package.json | 2 +- docker-compose.yml | 2 +- docs/api.md | 10 +- docs/configuration.md | 8 +- docs/jobs.md | 20 + docs/scripts.md | 5 + docs/service-dependencies.md | 26 - .../auditLogRecord/auditLogRecord.ts | 16 +- .../auditLogRecord/auditLogRecordProvider.ts | 2 +- .../auditLogRecord/index.ts | 0 .../auditLogRecord/type.ts | 2 +- .../localExtensionKey/index.ts | 2 +- .../localExtensionKey/localExtensionKey.ts | 12 +- .../localExtensionKeyProvider.ts | 4 +- .../organizationAnnotation.ts | 24 +- .../organizationMemberCache/index.ts | 0 .../organizationMemberCache.ts | 20 +- .../organizationMemberCacheProvider.ts | 2 +- .../organizationSettings/index.ts | 0 .../organizationSetting.ts | 54 +- .../organizationSettingProvider.ts | 2 +- .../organizationSettings/type.ts | 2 +- {business/entities => entities}/repository.ts | 27 +- .../repositoryCache/index.ts | 0 .../repositoryCache/repositoryCache.ts | 18 +- .../repositoryCacheProvider.ts | 2 +- .../repositoryCollaboratorCache/index.ts | 0 .../repositoryCollaboratorCache.ts | 18 +- .../repositoryCollaboratorCacheProvider.ts | 2 +- .../repositoryMetadata/index.ts | 0 .../repositoryMetadata/repositoryMetadata.ts | 16 +- .../repositoryMetadataProvider.ts | 2 +- .../repositoryMetadata/type.ts | 2 +- .../repositoryTeamCache/index.ts | 0 .../repositoryTeamCache.ts | 18 +- .../repositoryTeamCacheProvider.ts | 2 +- .../entities => entities}/teamCache/index.ts | 2 +- .../teamCache/teamCache.ts | 16 +- .../teamCache/teamCacheProvider.ts | 2 +- .../teamJoinApproval/approvalProvider.ts | 2 +- .../teamJoinApproval/index.ts | 7 +- .../teamJoinApproval/teamJoinApproval.ts | 16 +- .../teamJoinApprovalProvider.ts | 2 +- .../teamMemberCache/index.ts | 7 +- .../teamMemberCache/teamMemberCache.ts | 18 +- .../teamMemberCacheProvider.ts | 2 +- .../entities => entities}/token/index.ts | 2 +- .../entities => entities}/token/token.ts | 32 +- .../token/tokenGenerator.ts | 0 .../token/tokenProvider.ts | 4 +- {business/entities => entities}/token/type.ts | 2 +- .../entities => entities}/userSettings.ts | 13 +- features/graphTeamSync.ts | 31 + {business/features => features}/index.ts | 0 .../newRepositories/actions/createReadme.ts | 4 +- .../newRepositories/actions/deleteFork.ts | 2 +- .../actions/downgradeCollaborator.ts | 4 +- .../actions/dropCollaborator.ts | 2 +- .../newRepositories/actions/dropTeam.ts | 2 +- .../newRepositories/actions/index.ts | 0 .../newRepositories/actions/lockdown.ts | 12 +- .../newRepositories/approve.ts | 6 +- .../newRepositories/initializeMetadata.ts | 21 +- .../newRepositories/interfaces.ts | 12 +- .../newRepositories/lockdownMail.ts | 8 +- .../newRepositories/newRepositoryLockdown.ts | 68 +- .../newRepositories/selfServiceDelete.ts | 6 +- .../newRepositories/staticFunctions.ts | 4 +- .../newRepositories/strings.ts | 0 .../validateSelfServiceDelete.ts | 8 +- .../validateSelfServiceSetup.ts | 4 +- .../publicReposFastFilter.ts | 4 +- {business/features => features}/sudo/index.ts | 11 +- {business/features => features}/sudo/noop.ts | 9 +- .../features => features}/sudo/portal.ts | 8 +- .../sudo/securityGroup.ts | 6 +- {business/features => features}/sudo/sudo.md | 9 +- {business/features => features}/sudo/teams.ts | 6 +- .../teamMemberToMaintainerUpgrade.ts | 14 +- index.ts | 97 - interfaces/app.ts | 51 +- interfaces/companySpecific/administration.ts | 2 +- interfaces/companySpecific/events/index.ts | 12 - interfaces/companySpecific/events/linking.ts | 11 - .../features/augmentApiMetadata.ts | 17 +- .../companySpecific/features/firehose.ts | 5 +- interfaces/companySpecific/features/index.ts | 18 +- .../features/organizationSudo.ts | 2 +- .../companySpecific/features/portalSudo.ts | 2 +- interfaces/companySpecific/index.ts | 1 - interfaces/companySpecific/middleware.ts | 10 +- interfaces/companySpecific/passport.ts | 2 +- .../companySpecific/routes/api/index.ts | 1 - interfaces/companySpecific/routes/index.ts | 2 +- interfaces/github/account.ts | 1 - interfaces/github/collaborators.ts | 5 +- interfaces/github/operations.ts | 35 +- interfaces/github/orgs.ts | 25 +- interfaces/github/repos.ts | 162 +- interfaces/github/rest.ts | 23 +- interfaces/github/teams.ts | 23 - interfaces/index.ts | 17 +- interfaces/middleware.ts | 11 - interfaces/providers.ts | 34 +- interfaces/queryCache.ts | 10 +- interfaces/web.ts | 8 +- test/jest.config.ts => jest.config.ts | 5 - job.ts | 182 - .../cleanupBlobCache/index.ts | 7 +- .../task.ts} | 11 +- jobs/cleanupInvites/index.ts | 13 + .../task.ts} | 45 +- jobs/cleanupKeys/index.ts | 9 + jobs/cleanupKeys/task.ts | 98 + jobs/cleanupTeamRequests.ts | 65 - jobs/cleanupTokens/index.ts | 9 + jobs/cleanupTokens/task.ts | 142 + jobs/firehose/index.ts | 13 + jobs/{firehose.ts => firehose/task.ts} | 54 +- jobs/permissions.ts | 214 - jobs/permissions/index.ts | 14 + jobs/permissions/task.ts | 155 + .../deletedRepositories.ts} | 25 +- jobs/refreshQueryCache/index.ts | 15 + .../task.ts} | 30 +- .../index.ts} | 81 +- jobs/repositories.ts | 339 +- lib/caching/blob.ts | 2 +- lib/caching/cosmosdb.ts | 6 +- lib/caching/redis.ts | 4 +- lib/campaigns.ts | 7 +- lib/config/painlessConfigAsCode.ts | 13 +- lib/cosmosSession/index.ts | 2 +- .../entityMetadataProvider.ts | 6 +- lib/entityMetadataProvider/postgres.ts | 66 +- lib/entityMetadataProvider/query.ts | 2 +- lib/entityMetadataProvider/table.ts | 2 +- lib/github/appPurposes.ts | 277 - lib/github/collections.ts | 295 +- lib/github/composite.ts | 36 +- lib/github/core.ts | 107 +- lib/github/crossOrganization.ts | 32 +- lib/github/index.ts | 107 +- lib/github/restApi.ts | 84 +- lib/graphProvider/microsoftGraphProvider.ts | 190 +- lib/linkProviders/table/tableLinkProvider.ts | 2 +- lib/mailProvider/index.ts | 43 - lib/pugViewServices.ts | 2 +- middleware/alternateApps.ts | 6 +- middleware/apiAad.ts | 46 +- middleware/apiReposAuth.ts | 7 +- middleware/apiVstsAuth.ts | 7 +- middleware/appInsights.ts | 26 +- middleware/business/administration.ts | 13 +- middleware/business/allLinks.ts | 8 +- middleware/business/authentication.ts | 28 +- .../business/corporateAdministrators.ts | 18 +- middleware/business/corporateAlias.ts | 2 +- middleware/business/corporateHierarchy.ts | 2 +- middleware/business/corporateMail.ts | 25 +- middleware/business/employeesOnly.ts | 8 +- middleware/business/organization.ts | 45 +- middleware/business/repository.ts | 34 - middleware/business/setContext.ts | 8 +- middleware/business/userSettings.ts | 41 - middleware/campaign.ts | 6 +- middleware/codespaces.ts | 4 +- middleware/companySpecificDeployment.ts | 6 +- middleware/corporateViews.ts | 2 +- middleware/correlationId.ts | 7 +- .../{errorRoutes.ts => error-routes.ts} | 15 +- middleware/errorHandler.ts | 36 +- .../github/blockEnterpriseManagedUsers.ts | 10 +- .../github/ensureOrganizationProfile.ts | 57 - middleware/github/orgPermissions.ts | 10 +- middleware/github/repoPermissions.ts | 51 +- middleware/github/requireActiveSession.ts | 7 +- middleware/github/systemWidePermissions.ts | 8 +- middleware/github/teamPermissions.ts | 14 +- middleware/healthCheck.ts | 25 +- middleware/index.ts | 22 +- middleware/initialize.ts | 236 +- middleware/jsonError.ts | 11 +- middleware/keyVault.ts | 2 +- .../{business/links.ts => links/index.ts} | 16 +- middleware/locals.ts | 7 +- middleware/logger.ts | 2 +- middleware/lowercaser.ts | 6 +- middleware/officeHyperlinks.ts | 5 +- middleware/onboarding.ts | 4 +- .../{passportConfig.ts => passport-config.ts} | 4 +- middleware/passport-routes.ts | 9 +- middleware/passport/aadRoutes.ts | 12 +- middleware/passport/aadStrategy.ts | 83 +- middleware/passport/encryptionSerializer.ts | 2 +- middleware/passport/githubRoutes.ts | 13 +- middleware/passport/githubStrategy.ts | 27 +- middleware/rawBodyParser.ts | 5 +- middleware/react.ts | 44 +- middleware/scrubbedUrl.ts | 7 +- middleware/sslify.ts | 1 - middleware/staticClientApp.ts | 5 +- middleware/staticClientApp2.ts | 9 +- middleware/staticSiteAssets.ts | 2 +- middleware/supportMultipleAuthProviders.ts | 6 +- package-lock.json | 15278 ++++++++++------ package.json | 139 +- data/pg.sql => pg.sql | 0 routes/administration/app.ts | 54 +- routes/administration/apps.ts | 57 +- routes/administration/index.ts | 8 +- routes/approvals.ts | 2 +- routes/diagnostics.ts | 14 +- routes/explore.ts | 4 +- routes/index-authenticated.ts | 56 +- routes/index-linked.ts | 10 +- routes/index.ts | 4 +- routes/link-cleanup.ts | 6 +- routes/link.ts | 18 +- routes/org/2fa.ts | 6 +- routes/org/index.ts | 21 +- routes/org/join.ts | 9 +- routes/org/leave.ts | 10 +- routes/org/membership.ts | 8 +- routes/org/newRepoSpa.ts | 6 +- routes/org/people.ts | 4 +- routes/org/profileReview.ts | 6 +- routes/org/repoAdministrativeLock.ts | 19 +- routes/org/repoWorkflowEngine.ts | 18 +- routes/org/repos.ts | 249 +- routes/org/team/approval/index.ts | 6 +- routes/org/team/approvals.ts | 14 +- routes/org/team/delete.ts | 4 +- routes/org/team/index-maintainer.ts | 6 +- routes/org/team/index.ts | 123 +- routes/org/team/leave.ts | 4 +- routes/org/team/maintainers.ts | 12 +- routes/org/team/members.ts | 16 +- routes/org/team/properties.ts | 90 +- routes/org/team/teamAdminRequired.ts | 4 +- routes/org/teams.ts | 10 +- routes/orgAdmin.ts | 62 +- routes/orgs.ts | 12 +- routes/people.ts | 8 +- routes/peopleSearch.ts | 6 +- routes/placeholders.ts | 4 +- routes/releasesSpa.ts | 2 +- routes/repos.ts | 4 +- routes/reposPager.ts | 6 +- routes/settings/approvals.ts | 16 +- routes/settings/authorizations.ts | 8 +- routes/settings/campaigns.ts | 12 +- routes/settings/contributionData.ts | 44 +- routes/settings/index.ts | 2 +- routes/settings/personalAccessTokens.ts | 16 +- routes/teams.ts | 4 +- routes/teamsPager.ts | 2 +- routes/thanks.ts | 2 +- routes/undo.ts | 16 +- routes/unlink.ts | 12 +- scripts/configuration.ts | 28 +- scripts/localEnvironment.ts | 24 +- scripts/migrateLinks/index.ts | 11 + .../{migrateLinks.ts => migrateLinks/task.ts} | 24 +- scripts/postgres/setup.ts | 2 +- lib/transitional.ts => transitional.ts | 107 +- tsconfig.json | 11 +- lib/utils.ts => utils.ts | 36 +- views/contributions/eligible.pug | 4 +- views/contributions/popular.pug | 2 + views/contributions/voting/elections.pug | 36 +- views/contributions/voting/vote.pug | 2 + views/email/fossfund-vote.pug | 17 +- views/includes/corporateRepoMetadata.pug | 1 + views/message.pug | 3 - views/nav.pug | 8 +- views/org/pending.pug | 15 +- views/org/team/index.pug | 17 +- views/organization/whois/result.pug | 6 - views/people/index.pug | 2 +- views/repos/defaultBranch.pug | 88 + views/repos/delete.pug | 5 + views/repos/history.pug | 3 + views/repos/index.pug | 11 +- views/repos/permissions.pug | 2 + views/repos/pills.pug | 1 + views/repos/repo.pug | 33 +- views/teams/index.pug | 1 + .../organizationProcessor.ts | 24 +- .../webhooks => webhooks}/tasks/auditLog.ts | 5 +- .../tasks/automaticTeams.ts | 19 +- .../webhooks => webhooks}/tasks/index.ts | 0 .../webhooks => webhooks}/tasks/member.ts | 9 +- .../webhooks => webhooks}/tasks/membership.ts | 4 +- .../tasks/organization.ts | 4 +- .../webhooks => webhooks}/tasks/repository.ts | 14 +- {business/webhooks => webhooks}/tasks/team.ts | 24 +- 414 files changed, 14486 insertions(+), 13947 deletions(-) rename .config/.markdownlint-cli2.jsonc => .markdownlint-cli2.jsonc (59%) delete mode 100644 api/client/context/administration/app.ts delete mode 100644 api/client/context/administration/appInstallation.ts delete mode 100644 api/client/context/administration/apps.ts delete mode 100644 api/client/context/administration/types.ts delete mode 100644 api/client/context/settings.ts delete mode 100644 api/client/users.ts create mode 100644 app.ts delete mode 100644 business/enterprise.ts rename {lib/github => business/githubApps}/appTokens.ts (76%) create mode 100644 business/githubApps/index.ts rename {lib/github => business/githubApps}/tokenManager.ts (65%) delete mode 100644 business/organizationCopilot.ts delete mode 100644 business/organizationProperties.ts delete mode 100644 business/repositoryInvitation.ts delete mode 100644 business/repositoryProperties.ts create mode 100644 config/npm.publishing.json create mode 100644 config/npm.publishing.types.ts create mode 100644 docs/jobs.md create mode 100644 docs/scripts.md delete mode 100644 docs/service-dependencies.md rename {business/entities => entities}/auditLogRecord/auditLogRecord.ts (94%) rename {business/entities => entities}/auditLogRecord/auditLogRecordProvider.ts (98%) rename {business/entities => entities}/auditLogRecord/index.ts (100%) rename {business/entities => entities}/auditLogRecord/type.ts (69%) rename {business/entities => entities}/localExtensionKey/index.ts (91%) rename {business/entities => entities}/localExtensionKey/localExtensionKey.ts (90%) rename {business/entities => entities}/localExtensionKey/localExtensionKeyProvider.ts (94%) rename {business/entities => entities}/organizationAnnotation.ts (90%) rename {business/entities => entities}/organizationMemberCache/index.ts (100%) rename {business/entities => entities}/organizationMemberCache/organizationMemberCache.ts (93%) rename {business/entities => entities}/organizationMemberCache/organizationMemberCacheProvider.ts (98%) rename {business/entities => entities}/organizationSettings/index.ts (100%) rename {business/entities => entities}/organizationSettings/organizationSetting.ts (89%) rename {business/entities => entities}/organizationSettings/organizationSettingProvider.ts (97%) rename {business/entities => entities}/organizationSettings/type.ts (69%) rename {business/entities => entities}/repository.ts (92%) rename {business/entities => entities}/repositoryCache/index.ts (100%) rename {business/entities => entities}/repositoryCache/repositoryCache.ts (91%) rename {business/entities => entities}/repositoryCache/repositoryCacheProvider.ts (98%) rename {business/entities => entities}/repositoryCollaboratorCache/index.ts (100%) rename {business/entities => entities}/repositoryCollaboratorCache/repositoryCollaboratorCache.ts (94%) rename {business/entities => entities}/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts (99%) rename {business/entities => entities}/repositoryMetadata/index.ts (100%) rename {business/entities => entities}/repositoryMetadata/repositoryMetadata.ts (95%) rename {business/entities => entities}/repositoryMetadata/repositoryMetadataProvider.ts (98%) rename {business/entities => entities}/repositoryMetadata/type.ts (68%) rename {business/entities => entities}/repositoryTeamCache/index.ts (100%) rename {business/entities => entities}/repositoryTeamCache/repositoryTeamCache.ts (93%) rename {business/entities => entities}/repositoryTeamCache/repositoryTeamCacheProvider.ts (98%) rename {business/entities => entities}/teamCache/index.ts (97%) rename {business/entities => entities}/teamCache/teamCache.ts (89%) rename {business/entities => entities}/teamCache/teamCacheProvider.ts (98%) rename {business/entities => entities}/teamJoinApproval/approvalProvider.ts (90%) rename {business/entities => entities}/teamJoinApproval/index.ts (63%) rename {business/entities => entities}/teamJoinApproval/teamJoinApproval.ts (96%) rename {business/entities => entities}/teamJoinApproval/teamJoinApprovalProvider.ts (98%) rename {business/entities => entities}/teamMemberCache/index.ts (95%) rename {business/entities => entities}/teamMemberCache/teamMemberCache.ts (91%) rename {business/entities => entities}/teamMemberCache/teamMemberCacheProvider.ts (99%) rename {business/entities => entities}/token/index.ts (90%) rename {business/entities => entities}/token/token.ts (92%) rename {business/entities => entities}/token/tokenGenerator.ts (100%) rename {business/entities => entities}/token/tokenProvider.ts (95%) rename {business/entities => entities}/token/type.ts (68%) rename {business/entities => entities}/userSettings.ts (92%) create mode 100644 features/graphTeamSync.ts rename {business/features => features}/index.ts (100%) rename {business/features => features}/newRepositories/actions/createReadme.ts (93%) rename {business/features => features}/newRepositories/actions/deleteFork.ts (93%) rename {business/features => features}/newRepositories/actions/downgradeCollaborator.ts (87%) rename {business/features => features}/newRepositories/actions/dropCollaborator.ts (93%) rename {business/features => features}/newRepositories/actions/dropTeam.ts (93%) rename {business/features => features}/newRepositories/actions/index.ts (100%) rename {business/features => features}/newRepositories/actions/lockdown.ts (84%) rename {business/features => features}/newRepositories/approve.ts (97%) rename {business/features => features}/newRepositories/initializeMetadata.ts (84%) rename {business/features => features}/newRepositories/interfaces.ts (86%) rename {business/features => features}/newRepositories/lockdownMail.ts (97%) rename {business/features => features}/newRepositories/newRepositoryLockdown.ts (85%) rename {business/features => features}/newRepositories/selfServiceDelete.ts (97%) rename {business/features => features}/newRepositories/staticFunctions.ts (90%) rename {business/features => features}/newRepositories/strings.ts (100%) rename {business/features => features}/newRepositories/validateSelfServiceDelete.ts (90%) rename {business/features => features}/newRepositories/validateSelfServiceSetup.ts (94%) rename {business/features => features}/publicReposFastFilter.ts (94%) rename {business/features => features}/sudo/index.ts (90%) rename {business/features => features}/sudo/noop.ts (65%) rename {business/features => features}/sudo/portal.ts (94%) rename {business/features => features}/sudo/securityGroup.ts (93%) rename {business/features => features}/sudo/sudo.md (90%) rename {business/features => features}/sudo/teams.ts (91%) rename {business/features => features}/teamMemberToMaintainerUpgrade.ts (96%) delete mode 100644 index.ts delete mode 100644 interfaces/companySpecific/events/index.ts delete mode 100644 interfaces/companySpecific/events/linking.ts delete mode 100644 interfaces/middleware.ts rename test/jest.config.ts => jest.config.ts (66%) delete mode 100644 job.ts rename middleware/types.ts => jobs/cleanupBlobCache/index.ts (50%) rename jobs/{cleanupBlobCache.ts => cleanupBlobCache/task.ts} (81%) create mode 100644 jobs/cleanupInvites/index.ts rename jobs/{cleanupInvites.ts => cleanupInvites/task.ts} (71%) create mode 100644 jobs/cleanupKeys/index.ts create mode 100644 jobs/cleanupKeys/task.ts delete mode 100644 jobs/cleanupTeamRequests.ts create mode 100644 jobs/cleanupTokens/index.ts create mode 100644 jobs/cleanupTokens/task.ts create mode 100644 jobs/firehose/index.ts rename jobs/{firehose.ts => firehose/task.ts} (89%) delete mode 100644 jobs/permissions.ts create mode 100644 jobs/permissions/index.ts create mode 100644 jobs/permissions/task.ts rename jobs/{deletedRepositoriesCache.ts => refreshQueryCache/deletedRepositories.ts} (91%) create mode 100644 jobs/refreshQueryCache/index.ts rename jobs/{refreshQueryCache.ts => refreshQueryCache/task.ts} (97%) rename jobs/{refreshUsernames.ts => refreshUsernames/index.ts} (67%) delete mode 100644 lib/github/appPurposes.ts delete mode 100644 middleware/business/repository.ts delete mode 100644 middleware/business/userSettings.ts rename middleware/{errorRoutes.ts => error-routes.ts} (74%) delete mode 100644 middleware/github/ensureOrganizationProfile.ts rename middleware/{business/links.ts => links/index.ts} (90%) rename middleware/{passportConfig.ts => passport-config.ts} (96%) rename data/pg.sql => pg.sql (100%) create mode 100644 scripts/migrateLinks/index.ts rename scripts/{migrateLinks.ts => migrateLinks/task.ts} (84%) rename lib/transitional.ts => transitional.ts (75%) rename lib/utils.ts => utils.ts (90%) create mode 100644 views/repos/defaultBranch.pug rename {business/webhooks => webhooks}/organizationProcessor.ts (88%) rename {business/webhooks => webhooks}/tasks/auditLog.ts (97%) rename {business/webhooks => webhooks}/tasks/automaticTeams.ts (95%) rename {business/webhooks => webhooks}/tasks/index.ts (100%) rename {business/webhooks => webhooks}/tasks/member.ts (92%) rename {business/webhooks => webhooks}/tasks/membership.ts (96%) rename {business/webhooks => webhooks}/tasks/organization.ts (98%) rename {business/webhooks => webhooks}/tasks/repository.ts (93%) rename {business/webhooks => webhooks}/tasks/team.ts (89%) diff --git a/.cspell.json b/.cspell.json index 83a11efe1..22e5b16fe 100644 --- a/.cspell.json +++ b/.cspell.json @@ -5,7 +5,6 @@ ".git/", ".environment/**", "**/jitStaticConfiguration.json", - "**/*Accounts.json", "**/sentiment/**", "**/thirdparty/**", "**/vendor/**", @@ -14,26 +13,22 @@ "default-assets-package/resources/repos-css/oss.css", "**/commonKnownExternalCollaborators.json", "jobs/reports/exemptRepositories.json", + "**/hotfixRepos.json", "**/demo/team.json", "**/demo/user.json", "**/*_html.ts", "**/*.ignore_data.ts", "package*.json", - ".devcontainer/nih/**", - "**/assets/*.xlsx", - "**/known.csv" + ".devcontainer/nih/**" ], "enableGlobDot": true, "useGitignore": true, "words": [ - "1es", - "1escopilot", "aadgraph", "aadid", "aadname", "aadoid", "aadupn", - "accesslevel", "accountinfo", "accountinformation", "actionperms", @@ -44,7 +39,6 @@ "actionsplatforms", "actionsupdated", "actionsused", - "actionsworkflowcount", "actorid", "adal", "additionals", @@ -62,7 +56,6 @@ "agreementversion", "alladmins", "allowunlock", - "alreadyrestored", "aosp", "apikey", "APPDIR", @@ -96,7 +89,6 @@ "blockui", "bootswatch", "bootup", - "branchname", "breakingchangereviewrequired", "browserconfig", "builddir", @@ -115,17 +107,12 @@ "CELA", "champscount", "champstatus", - "checkmarks", - "chromedriver", - "citus", - "citusdata", "classificationdelegated", "classificationnative", "classificationnativechecked", "classificationupdated", "classificationupdatedby", "classname", - "classpath", "cleanupblobs", "cleanupinvites", "cleanupkeys", @@ -147,7 +134,6 @@ "codespace", "codespaces", "collab", - "collaboratorid", "collabs", "columnbreak", "commitcomment", @@ -166,10 +152,8 @@ "contributionshareoptin", "copilotaccess", "copilotagreement", - "copilotprod", "copilotrequest", "Copybara", - "corpnet", "corporatealias", "corporatecount", "corporatedev", @@ -180,7 +164,6 @@ "corporatename", "corporateprod", "corporateusername", - "countuse", "createdat", "creategithubaccount", "creds", @@ -196,14 +179,12 @@ "DATETIME", "dbaeumer", "dcount", - "deadcode", "decisionmaker", "Decisionmaker", "Decisionmakers", "deepmerge", "defaultbranch", "deferreason", - "definitelytyped", "deislabs", "deletedetected", "deletesettingsorgname", @@ -218,8 +199,6 @@ "devstaging", "directoryname", "directowners", - "disablewave", - "distributeonly", "distro", "divisionid", "dnfmit", @@ -232,7 +211,6 @@ "dropup", "DSRE", "eastus", - "Ecosyste", "edgecase", "electionid", "eligibilityend", @@ -267,7 +245,6 @@ "enterprisevisited", "entityid", "entitytype", - "entra", "esbody", "esemail", "eshead", @@ -275,7 +252,6 @@ "eventid", "eventrecord", "eventtype", - "exceljs", "existingrepoid", "existingreponame", "fakeaccesstoken", @@ -287,11 +263,9 @@ "firstconfigured", "FIRSTRUNFILE", "flipgrid", - "fontawesome", "fontname", "forceopen", "forkscount", - "fortawesome", "FOSS", "FOSSFUND", "fossfundabout", @@ -313,8 +287,8 @@ "GHID", "GHMP", "ghname", - "ghossapis", "ghowners", + "ghossapis", "GHPI", "ghpimigrationphase", "ghrp", @@ -349,12 +323,9 @@ "haswiki", "hierarchynames", "hierarchytext", - "highcharts", "hsts", "Hsts", "HSTS", - "hubber", - "hubbers", "hubot", "IAAD", "ictext", @@ -392,18 +363,15 @@ "issuecomment", "issuesopened", "istest", - "jabberpl", "jeffwilcox", "jitgrants", "joblog", "jobname", - "json", "jsoncontribution", "jsoncreated", "jwilcox", "jwks", "JWTs", - "keybytes", "keyout", "keyvault", "KEYVAULT", @@ -418,7 +386,6 @@ "leftouter", "legalcontact", "legalentities", - "libsodium", "lightup", "linkid", "linkmanager", @@ -481,8 +448,6 @@ "monthlycontributionactivity", "msapplication", "msecnd", - "MSEULA", - "MSFTEULA", "MSFTIES", "msftmetadata", "msrc", @@ -503,8 +468,6 @@ "newrepolockremoved", "nihgithubportal", "nihdevgithubportal", - "Newtonsoft", - "NOASSERTION", "nodeapp", "nodenext", "noemail", @@ -516,10 +479,8 @@ "notifiedissueid", "npminitignore", "npminstallignore", - "npmjs", "npmrc", "nums", - "Nunit", "octicon", "odata", "offboard", @@ -550,7 +511,6 @@ "opensourcedocsprod", "opensourceprod", "opensourcepulls", - "opensourcerepoowners", "opensourcereposdev", "opensourcereposprod", "opensourcesite", @@ -579,7 +539,6 @@ "organizationlogin", "organizationmembercache", "organizationname", - "organizationrunners", "organizationsetting", "organizationsettings", "orgid", @@ -634,7 +593,6 @@ "pmownerid", "popd", "portaldescription", - "portaldev", "portalppe", "portalprod", "portalwestus", @@ -684,8 +642,6 @@ "removeothergithubaccount", "REPLYTO", "repocount", - "repodisablebranchprotections", - "repodisableoutsidecollaborators", "repoid", "repoidifyouhaveit", "repolockdown", @@ -723,8 +679,6 @@ "revokedbycorporateid", "rootdir", "rubygem", - "rubygems", - "RUNNERDATA", "runtimes", "samplescollaboratorusername", "samplescontact", @@ -736,8 +690,6 @@ "scansummary", "SCIM", "scorecardreprocessrequest", - "secretbox", - "secretless", "secretscanningonpush", "secscandata", "securityevents", @@ -774,7 +726,6 @@ "shortcutting", "shouldrestore", "showids", - "shuf", "Sida", "signin", "signoff", @@ -787,11 +738,13 @@ "specialteams", "SSIRP", "sslify", + "Sslify", "standardsredirect", "stargazerscount", "startclean", - "startofday", + "StartClean", "startright", + "StartRight", "startswith", "statechecked", "steelblue", @@ -831,8 +784,6 @@ "timezoneoffset", "tlink", "tolower", - "Toolset", - "toscalar", "totalcount", "touchedtime", "toupper", @@ -852,7 +803,6 @@ "unadopted", "unarchived", "Unauthoritative", - "Uncommited", "unconfigured", "Unconfigured", "unconfirmedorganizationname", @@ -900,22 +850,21 @@ "Wcag", "webapps", "webcontext", - "webfonts", "webhoooks", "welcomeemailsent", "whois", "Whois", "withmaintainers", "withservicetree", - "withsource", - "wixtoolset", + "workboard", + "Workboard", + "workboarding", "xamarinhq", "Xcache", "xlink", "XSTORE", "xtable", - "yamls", - "yml" + "yamls" ], "maxNumberOfProblems": 1000 } diff --git a/.editorconfig b/.editorconfig index 6375e1c4c..d7ce5c432 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,4 +9,3 @@ indent_size = 2 trim_trailing_whitespace = true charset = utf-8 end_of_line = lf -tabCompletion = on diff --git a/.eslintrc.js b/.eslintrc.js index 3c5d9899b..cf1525756 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,10 +41,5 @@ module.exports = { }, }, ], - ignorePatterns: [ - 'default-assets-package/thirdparty/**/*.js', - 'dist/**/*.js', - 'dist/**/*.d.ts', - '**/vendor/**', - ], + ignorePatterns: ['default-assets-package/thirdparty/**/*.js', 'dist/**/*.js', '**/vendor/**'], }; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44beab153..27cb497a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,10 +13,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v3 - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v3 with: cache: npm diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2eb6669f6..be69f6ca4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -15,11 +15,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v2 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java @@ -27,7 +27,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@v2 # โ„น๏ธ Command-line programs to run using the OS shell. # ๐Ÿ“š https://git.io/JvXDl @@ -41,4 +41,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index c1dd30444..179b287a5 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout ๐Ÿ›’ - uses: actions/checkout@v4 + uses: actions/checkout@v3 - name: Packages ๐Ÿ“ฆ run: | @@ -36,7 +36,7 @@ jobs: environment: name: development steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 #- uses: docker/build-push-action@v3 - name: Azure OpenID Connect โœจ diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 65f5bbf4e..350edfea4 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,7 +13,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v9 + - uses: actions/stale@v8 with: stale-issue-message: This issue has been identified as stale because it has gone 30 days with no activity. diff --git a/.gitignore b/.gitignore index d7f45ffdf..d83fe8f0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ dist/ node_modules/ .DS_Store -reports/ # Potential local development environment scripts app.yaml @@ -14,4 +13,3 @@ feedscan feedscan* ..prettierignore.swp scripts/localCodespace.ts -junit.xml diff --git a/.config/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc similarity index 59% rename from .config/.markdownlint-cli2.jsonc rename to .markdownlint-cli2.jsonc index 92bfbc2e7..7c3b70235 100644 --- a/.config/.markdownlint-cli2.jsonc +++ b/.markdownlint-cli2.jsonc @@ -5,8 +5,7 @@ "MD024": { "allow_different_nesting": true }, - "MD026": false, - "MD033": false // no inline HTML: we use inline HTML for expandable details sections + "MD026": false }, "ignores": ["**/node_modules/**"] } diff --git a/.prettierrc.json b/.prettierrc.json index f7aa09f41..32e9fdbd7 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,5 +1,4 @@ { "singleQuote": true, - "trailingComma": "es5", "printWidth": 110 } diff --git a/.secrets.env.example b/.secrets.env.example index 896300ed7..a81c4a1ee 100644 --- a/.secrets.env.example +++ b/.secrets.env.example @@ -1,3 +1,4 @@ +GITHUB_CENTRAL_OPERATIONS_TOKEN= GITHUB_CLIENT_ID= GITHUB_CLIENT_SECRET= GITHUB_CALLBACK_URL=http://localhost:3000/auth/github/callback diff --git a/.vscode/launch.json b/.vscode/launch.json index 491b43343..d1caa8213 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ { "type": "node", "request": "launch", - "name": "Launch site :4000 sudo", + "name": "Launch site 3000", "program": "${workspaceFolder}/dist/bin/www.js", "cwd": "${workspaceFolder}/dist", "preLaunchTask": "tsbuild", @@ -12,32 +12,26 @@ "console": "integratedTerminal", "env": { "NODE_ENV": "development", - "PORT": "4000", - "DEBUG_GITHUB_PORTAL_SUDO_FORCE": "1", - "DEBUG": "startup,cosmosdb,g:server,context,*simple-oauth2*,appinsights,insights", - "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org" + "DEBUG": "startup,g:server,context,github:tokens", + "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org,health" } }, { "type": "node", "request": "launch", - "name": "Launch site :4000 as-is", - "program": "${workspaceFolder}/dist/bin/www.js", - "cwd": "${workspaceFolder}/dist", + "name": "Jest Tests", + "program": "${workspaceRoot}/node_modules/jest/bin/jest.js", + "args": ["-i"], "preLaunchTask": "tsbuild", "sourceMaps": true, - "console": "integratedTerminal", - "env": { - "NODE_ENV": "development", - "PORT": "4000", - "DEBUG": "startup,g:server,context,*simple-oauth2*,appinsights,insights,appinsights", - "_DEBUG": "cosmosdb,cache" - } + "internalConsoleOptions": "openOnSessionStart", + "console": "externalTerminal", + "outFiles": ["${workspaceRoot}/dist/**/*"] }, { "type": "node", "request": "launch", - "name": "Launch site :4000 sudo OFF", + "name": "Launch site 4000 sudo", "program": "${workspaceFolder}/dist/bin/www.js", "cwd": "${workspaceFolder}/dist", "preLaunchTask": "tsbuild", @@ -46,16 +40,15 @@ "env": { "NODE_ENV": "development", "PORT": "4000", - "DEBUG": "startup,cosmosdb,g:server,context", - "DEBUG_GITHUB_PORTAL_SUDO_OFF": "1", - "DEBUG_GITHUB_ORG_SUDO_OFF": "1", + "DEBUG_GITHUB_PORTAL_SUDO_FORCE": "1", + "DEBUG": "startup,cosmosdb,g:server,context,*simple-oauth2*,appinsights,insights", "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org" } }, { "type": "node", "request": "launch", - "name": "Launch server-rendered legacy site :3000", + "name": "Launch site 4000 sudo OFF", "program": "${workspaceFolder}/dist/bin/www.js", "cwd": "${workspaceFolder}/dist", "preLaunchTask": "tsbuild", @@ -63,15 +56,18 @@ "console": "integratedTerminal", "env": { "NODE_ENV": "development", - "DEBUG": "startup,g:server,context", - "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org,health,github:tokens" + "PORT": "4000", + "DEBUG": "startup,cosmosdb,g:server,context", + "DEBUG_GITHUB_PORTAL_SUDO_OFF": "1", + "DEBUG_GITHUB_ORG_SUDO_OFF": "1", + "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org" } }, { "type": "node", "request": "launch", - "name": "Background Job: Event firehose", - "program": "${workspaceRoot}/dist/jobs/firehose.js", + "name": "Background Job: Firehose", + "program": "${workspaceRoot}/dist/jobs/firehose/index.js", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", @@ -81,18 +77,6 @@ "DEBUG": "startup,querycache" } }, - { - "type": "node", - "request": "launch", - "name": "Jest Tests", - "program": "${workspaceRoot}/node_modules/jest/bin/jest.js", - "args": ["-i"], - "preLaunchTask": "tsbuild", - "sourceMaps": true, - "internalConsoleOptions": "openOnSessionStart", - "console": "externalTerminal", - "outFiles": ["${workspaceRoot}/dist/**/*"] - }, { "type": "node", "request": "launch", @@ -134,7 +118,7 @@ "sourceMaps": true, "env": { "NODE_ENV": "development", - "DEBUG": "appinsights,startup", + "DEBUG": "appinsights,restapi,startup,redis-cross-org,appinsights", "DEBUG_GITHUB_PORTAL_SUDO_OFF": "1", "DEBUG_GITHUB_ORG_SUDO_OFF": "1" } @@ -150,30 +134,42 @@ "console": "integratedTerminal", "env": { "NODE_ENV": "localhost", - "DEBUG": "startup", - "EXIT_IMMEDIATELY": "1" + "DEBUG": "startup" } }, { "type": "node", "request": "launch", - "name": "66: Order 66 Terminations", - "program": "${workspaceRoot}/dist/microsoft/jobs/terminations.js", - "args": ["all"], + "name": "Job: Cleanup invitations", + "program": "${workspaceRoot}/dist/jobs/cleanupInvites/index.js", "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", "env": { "NODE_ENV": "development", - "DEBUG": "startup,appinsights" + "DEBUG": "redis,restapi,startup,appinsights" + } + }, + { + "type": "node", + "request": "launch", + "name": "Job: Cleanup blob cache", + "program": "${workspaceRoot}/dist/jobs/cleanupBlobCache/index.js", + "cwd": "${workspaceRoot}/dist", + "preLaunchTask": "tsbuild", + "sourceMaps": true, + "console": "integratedTerminal", + "env": { + "NODE_ENV": "development", + "DEBUG": "startup" } }, { "type": "node", "request": "launch", "name": "Job: Backfill aliases (3)", - "program": "${workspaceRoot}/dist/jobs/refreshUsernames.js", + "program": "${workspaceRoot}/dist/jobs/refreshUsernames/index.js", "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, @@ -188,21 +184,21 @@ "type": "node", "request": "launch", "name": "Job: User attributes hygiene (4)", - "program": "${workspaceRoot}/dist/jobs/refreshUsernames.js", + "program": "${workspaceRoot}/dist/jobs/refreshUsernames/index.js", "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", "env": { "NODE_ENV": "development", - "DEBUG": "startup,appinsights" + "DEBUG": "redis,restapi,startup,appinsights,cache" } }, { "type": "node", "request": "launch", "name": "Job: Consistency: All (6)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", "args": ["all"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -217,7 +213,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Deleted repos (7)", - "program": "${workspaceRoot}/dist/jobs/deletedRepositoriesCache.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/deletedRepositories.js", "args": [], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -232,7 +228,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Teams (8)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", "args": ["teams"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -247,7 +243,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Org members (9)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", "args": ["organizations"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -262,7 +258,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Repo collaborators (10)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", "args": ["collaborators"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -277,7 +273,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Team permissions (11)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", "args": ["permissions"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -305,8 +301,8 @@ { "type": "node", "request": "launch", - "name": "Job: Migrate links (14)", - "program": "${workspaceRoot}/dist/jobs/migrateLinks.js", + "name": "Job: Migrate links", + "program": "${workspaceRoot}/dist/jobs/migrateLinks/index.js", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", @@ -319,8 +315,8 @@ { "type": "node", "request": "launch", - "name": "Job: System Team Permissions (15)", - "program": "${workspaceRoot}/dist/jobs/permissions.js", + "name": "Job: System Team Permissions", + "program": "${workspaceRoot}/dist/jobs/permissions/index.js", "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, @@ -330,48 +326,6 @@ "DEBUG": "startup,appinsights" } }, - { - "type": "node", - "request": "launch", - "name": "Job: Cleanup invitations (16)", - "program": "${workspaceRoot}/dist/jobs/cleanupInvites.js", - "cwd": "${workspaceRoot}/dist", - "preLaunchTask": "tsbuild", - "sourceMaps": true, - "console": "integratedTerminal", - "env": { - "NODE_ENV": "development", - "DEBUG": "redis,restapi,startup,appinsights" - } - }, - { - "type": "node", - "request": "launch", - "name": "Job: Cleanup blob cache (17)", - "program": "${workspaceRoot}/dist/jobs/cleanupBlobCache.js", - "cwd": "${workspaceRoot}/dist", - "preLaunchTask": "tsbuild", - "sourceMaps": true, - "console": "integratedTerminal", - "env": { - "NODE_ENV": "development", - "DEBUG": "startup" - } - }, - { - "type": "node", - "request": "launch", - "name": "Job: Cleanup team requests (18)", - "program": "${workspaceRoot}/dist/jobs/cleanupTeamRequests.js", - "cwd": "${workspaceRoot}/dist", - "preLaunchTask": "tsbuild", - "sourceMaps": true, - "console": "integratedTerminal", - "env": { - "NODE_ENV": "development", - "DEBUG": "startup" - } - }, { "type": "node", "request": "launch", @@ -391,7 +345,7 @@ "type": "node", "request": "launch", "name": "Script: Import audit CSV", - "program": "${workspaceRoot}/dist/jobs/importAuditLog.js", + "program": "${workspaceRoot}/dist/jobs/importAuditLog/index.js", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", diff --git a/Dockerfile b/Dockerfile index a3f30f081..9daba8526 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,40 @@ -# -# Copyright (c) Microsoft. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -ARG IMAGE_NAME=mcr.microsoft.com/cbl-mariner/base/nodejs:18 +ARG IMAGE_NAME=node:16-alpine FROM $IMAGE_NAME AS build ARG NPM_TOKEN -RUN tdnf -y update --quiet - -# We used to also make Git available for NPM and rsync in build -# tdnf clean all --quiet && \ -# tdnf -y install ca-certificates git --quiet && \ +# Make Git available for NPM and rsync in the build image +RUN apk add --update git && rm -rf /var/cache/apk/* WORKDIR /build +COPY package.json . +COPY package-lock.json . + +# Only if needed, copy .npmrc files into the container +# COPY Dockerfile.npmrc /build/.npmrc + +# If you are doing local development and OK with your private tokens in the contains (CAREFUL): +# DO NOT RECOMMEND: +# COPY .npmrc /build/.npmrc + +# RUN npm install --production --verbose && mv node_modules production_node_modules +RUN npm install --production && mv node_modules production_node_modules COPY . . -# Only if needed, copy file with NPM_TOKEN arg -# COPY .npmrc.arg /build/.npmrc +# Only if needed, copy .npmrc files into the container, again... +# COPY Dockerfile.npmrc /build/.npmrc -RUN npm install --ignore-scripts --production --verbose -RUN npm ci +# Dev dependencies +# RUN npm install --verbose && rm -rf .npmrc +RUN npm install && rm -rf .npmrc + +# TypeScript build RUN npm run-script build -RUN mv node_modules production_node_modules -RUN rm -f .npmrc # The open source project build needs: build the site assets sub-project -RUN cd default-assets-package && npm ci && npm run build +RUN cd default-assets-package && npm install && npm run build FROM $IMAGE_NAME AS run @@ -42,26 +47,24 @@ EXPOSE 3000 WORKDIR /usr/src/repos +RUN addgroup oss && adduser -D -G oss oss && chown -R oss:oss . + # Production Node.js modules -COPY --from=build /build/production_node_modules ./node_modules +COPY --from=build --chown=oss:oss /build/production_node_modules ./node_modules # People not using painless config may need -COPY --from=build /build/data ./data +COPY --from=build --chown=oss:oss /build/data ./data # Copy built assets, app, config map -COPY --from=build /build/dist ./ +COPY --from=build --chown=oss:oss /build/dist ./ # The open source project build needs: default assets should be placed -COPY --from=build /build/default-assets-package ./default-assets-package - -COPY --from=build /build/config ./config -COPY --from=build /build/views ./views -COPY --from=build /build/package.json ./package.json - -# Only if needed, copy our environment -# COPY --from=build /build/.environment ./.environment +COPY --from=build --chown=oss:oss /build/default-assets-package ./default-assets-package -# Only if needed, binary resources -# COPY --from=build /build/microsoft/assets ./microsoft/assets +COPY --from=build --chown=oss:oss /build/config ./config +COPY --from=build --chown=oss:oss /build/views ./views +COPY --from=build --chown=oss:oss /build/package.json ./package.json -ENTRYPOINT ["npm", "run-script", "start-in-container"] +# Host the app +USER oss +ENTRYPOINT ["npm", "run-script", "start-in-container"] \ No newline at end of file diff --git a/api/client/banner.ts b/api/client/banner.ts index a4ccd0f88..732a5cc68 100644 --- a/api/client/banner.ts +++ b/api/client/banner.ts @@ -3,17 +3,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import { ReposAppRequest } from '../../interfaces'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; const router: Router = Router(); // TODO: move to modern w/administration experience, optionally -router.get('/', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.get('/', (req: ReposAppRequest, res, next) => { const { config } = getProviders(req); const text = config?.serviceMessage?.banner || null; const link = config.serviceMessage?.link; @@ -22,7 +22,7 @@ router.get('/', (req: ReposAppRequest, res: Response, next: NextFunction) => { return res.json({ banner }); }); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available within this banner route', 404)); }); diff --git a/api/client/context/administration/app.ts b/api/client/context/administration/app.ts deleted file mode 100644 index 0734a4385..000000000 --- a/api/client/context/administration/app.ts +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { NextFunction, Response, Router } from 'express'; -import asyncHandler from 'express-async-handler'; - -import { ReposAppRequest } from '../../../../interfaces'; -import { CreateError, getProviders } from '../../../../lib/transitional'; - -import routeIndividualApp from './app'; -import GitHubApplication from '../../../../business/application'; -import { OrganizationSetting } from '../../../../business/entities/organizationSettings/organizationSetting'; -import { sortByCaseInsensitive } from '../../../../lib/utils'; -import routeApplicationInstallation from './appInstallation'; -import { ApiRequestWithGitHubApplication, RequestWithInstallation } from './types'; - -const router: Router = Router(); - -router.get( - '/', - asyncHandler(async function (req: ApiRequestWithGitHubApplication, res: Response, next: NextFunction) { - const { gitHubApplication } = req; - const installationIdString = req.query.installation_id; - const setupAction = req.query.setup_action; - // if (installationIdString && setupAction) { - // return res.redirect( - // `./${githubApplication.id}/installations/${installationIdString}?setup_action=${setupAction}` - // ); - // } - // const individualContext = req.individualContext; - const allInstalls = await gitHubApplication.getInstallations({ maxAgeSeconds: 5 }); - const { valid, invalid } = GitHubApplication.filterInstallations(allInstalls); - return res.json({ - state: { - installations: { - valid, - invalid, - }, - app: gitHubApplication.asClientJson(), - }, - }) as unknown as void; - }) -); - -router.use( - '/installations/:installationId', - asyncHandler(async function (req: RequestWithInstallation, res, next) { - // const installationIdString = req.query.installation_id; - // const setupAction = req.query.setup_action; - const { gitHubApplication } = req; - const { installationId: installationIdAsString } = req.params; - const installationId = Number(installationIdAsString); - const installation = await gitHubApplication.getInstallation(installationId); - if (!installation) { - return next( - CreateError.NotFound( - `The GitHub app installation ${installationIdAsString} could not be found for app ${gitHubApplication.id}` - ) - ); - } - req.installation = installation; - return next(); - }) -); - -router.use('/installations/:installationId', routeApplicationInstallation); - -router.use('*', (req, res: Response, next: NextFunction) => { - return next(CreateError.NotFound('no API or function available: context/administration/apps/...')); -}); - -export default router; diff --git a/api/client/context/administration/appInstallation.ts b/api/client/context/administration/appInstallation.ts deleted file mode 100644 index b05c906a1..000000000 --- a/api/client/context/administration/appInstallation.ts +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { NextFunction, Response, Router } from 'express'; -import asyncHandler from 'express-async-handler'; - -import { CreateError, getProviders } from '../../../../lib/transitional'; -import { OrganizationSetting } from '../../../../business/entities/organizationSettings/organizationSetting'; -import { AdministrativeGitHubAppInstallationResponse, RequestWithInstallation } from './types'; - -const router: Router = Router(); - -router.use( - asyncHandler(async function (req: RequestWithInstallation, res: Response, next: NextFunction) { - const { operations, organizationSettingsProvider } = getProviders(req); - - const { installation } = req; - const organizationId = installation.account.id; - const organizationName = installation.account.login; - let settings: OrganizationSetting = null; - try { - settings = await organizationSettingsProvider.getOrganizationSetting(organizationId.toString()); - } catch (notFound) { - /* ignored */ - } - req.organizationDynamicSettings = settings; - - const staticSettings = operations.getOrganizationSettings(organizationName); - req.organizationStaticSettings = staticSettings; - - return next(); - }) -); - -router.get( - '/', - asyncHandler(async (req: RequestWithInstallation, res: Response, next: NextFunction) => { - const { gitHubApplication, installation, organizationDynamicSettings, organizationStaticSettings } = req; - const response: AdministrativeGitHubAppInstallationResponse = { - app: gitHubApplication.asClientJson(), - // installation, - installationId: installation.id, - dynamicSettings: organizationDynamicSettings, - }; - return res.json(response) as unknown as void; - }) -); - -router.use('*', (req, res: Response, next: NextFunction) => { - return next( - CreateError.NotFound( - 'no API or function available: context/administration/apps/:appId/installations/:installationId' - ) - ); -}); - -export default router; diff --git a/api/client/context/administration/apps.ts b/api/client/context/administration/apps.ts deleted file mode 100644 index f9f6e3db0..000000000 --- a/api/client/context/administration/apps.ts +++ /dev/null @@ -1,128 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { NextFunction, Response, Router } from 'express'; -import asyncHandler from 'express-async-handler'; - -import { ReposAppRequest } from '../../../../interfaces'; -import { CreateError, getProviders } from '../../../../lib/transitional'; - -import routeIndividualApp from './app'; -import GitHubApplication from '../../../../business/application'; -import { sortByCaseInsensitive } from '../../../../lib/utils'; -import { - ApiRequestWithGitHubApplication, - ManagedOrganizationAppConfigurationsByOrgView, - ManagedOrganizationStatus, -} from './types'; - -const router: Router = Router(); - -router.get( - '/', - asyncHandler(async (req: ReposAppRequest, res: Response) => { - const { operations, organizationSettingsProvider } = getProviders(req); - const apps = operations.getApplications(); - const byOrg = new Map(); - function getOrg(name: string) { - let o = byOrg.get(name); - if (!o) { - o = { - organizationName: name, - id: undefined, - status: ManagedOrganizationStatus.NotAdopted, - appInstallations: new Map(), - dynamicSettings: null, - configuredInstallations: [], - }; - for (const app of apps) { - o.appInstallations.set(app.id, null); - } - byOrg.set(name, o); - } - return o; - } - for (const app of apps) { - const appInstalls = await app.getInstallations({ maxAgeSeconds: 5 }); - const { valid: validInstallations } = GitHubApplication.filterInstallations(appInstalls); - for (const valid of validInstallations) { - const organizationName = valid.account.login; - const o = getOrg(organizationName.toLowerCase()); - o.appInstallations.set(app.id, { - app, - installationId: valid.id, - }); - o.id = Number(valid.target_id); - if (!o.dynamicSettings && valid.target_type === 'Organization') { - try { - o.dynamicSettings = await organizationSettingsProvider.getOrganizationSetting( - valid.target_id.toString() - ); - } catch (ignore) { - /* ignored */ - } - if (o.dynamicSettings) { - o.configuredInstallations = o.dynamicSettings.installations.map( - (install) => install.installationId - ); - o.status = ManagedOrganizationStatus.Adopted; - } - if (o.dynamicSettings && o.dynamicSettings.active === true) { - o.status = ManagedOrganizationStatus.Active; - } - } - } - } - for (const organization of operations.organizations.values()) { - const anOrg = getOrg(organization.name.toLowerCase()); - anOrg.id = organization.id; - } - const orgNames = Array.from(byOrg.keys()).sort(sortByCaseInsensitive); - return res.json({ - apps: apps.map((app) => app.asClientJson()), - orgNames, - orgs: Array.from(byOrg.values()).map((data) => { - return { - name: data.organizationName, - status: data.status, - id: data.id, - configuredInstallations: data.configuredInstallations, - hasDynamicSettings: !!data.dynamicSettings, - appInstallations: Array.from(data.appInstallations.keys()) - .filter((a) => a) - .map((appIdKey) => { - const install = data.appInstallations.get(appIdKey); - return { - installationId: install?.installationId, - appId: install?.app?.id, - }; - }), - }; - }), - }) as unknown as void; - }) -); - -router.use( - '/:appId', - asyncHandler(async function (req: ApiRequestWithGitHubApplication, res: Response, next: NextFunction) { - const { operations } = getProviders(req); - const appId = Number(req.params.appId); - const app = operations.getApplicationById(appId); - if (app) { - req.gitHubApplication = app; - return next(); - } - return next(CreateError.NotFound('no app available with that ID')); - }) -); - -router.use('/:appId', routeIndividualApp); - -router.use('*', (req, res: Response, next: NextFunction) => { - return next(CreateError.NotFound('no API or function available: context/administration/apps')); -}); - -export default router; diff --git a/api/client/context/administration/index.ts b/api/client/context/administration/index.ts index cb3e3aab5..12889f5aa 100644 --- a/api/client/context/administration/index.ts +++ b/api/client/context/administration/index.ts @@ -3,17 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; - import { Organization } from '../../../../business/organization'; import { ReposAppRequest } from '../../../../interfaces'; import { getIsCorporateAdministrator, jsonError } from '../../../../middleware'; import getCompanySpecificDeployment from '../../../../middleware/companySpecificDeployment'; -import { ErrorHelper, getProviders } from '../../../../lib/transitional'; +import { ErrorHelper, getProviders } from '../../../../transitional'; import routeIndividualOrganization from './organization'; -import routeApps from './apps'; const router: Router = Router(); @@ -22,7 +20,7 @@ interface IRequestWithAdministration extends ReposAppRequest { } router.use( - asyncHandler(async (req: IRequestWithAdministration, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithAdministration, res, next) => { req.isSystemAdministrator = await getIsCorporateAdministrator(req); return next(); }) @@ -30,31 +28,29 @@ router.use( router.get( '/', - asyncHandler(async (req: IRequestWithAdministration, res: Response) => { + asyncHandler(async (req: IRequestWithAdministration, res, next) => { const { operations } = getProviders(req); const isAdministrator = req.isSystemAdministrator; if (!isAdministrator) { return res.json({ isAdministrator, - }) as unknown as void; + }); } const organizations = operations.getOrganizations().map((org) => org.asClientJson()); return res.json({ isAdministrator, organizations, - }) as unknown as void; + }); }) ); -router.use((req: IRequestWithAdministration, res: Response, next: NextFunction) => { +router.use((req: IRequestWithAdministration, res, next) => { return req.isSystemAdministrator ? next() : next(jsonError('Not authorized', 403)); }); -router.use('/apps', routeApps); - router.use( '/organization/:orgName', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { orgName } = req.params; const { operations } = getProviders(req); let organization: Organization = null; @@ -65,8 +61,7 @@ router.use( } catch (noOrgError) { if (ErrorHelper.IsNotFound(noOrgError)) { res.status(404); - res.end(); - return; + return res.end(); } return next(jsonError(noOrgError, 500)); } @@ -79,7 +74,7 @@ const deployment = getCompanySpecificDeployment(); deployment?.routes?.api?.context?.administration?.index && deployment?.routes?.api?.context.administration.index(router); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available: context/administration', 404)); }); diff --git a/api/client/context/administration/organization/index.ts b/api/client/context/administration/organization/index.ts index 5ed533872..45db6953e 100644 --- a/api/client/context/administration/organization/index.ts +++ b/api/client/context/administration/organization/index.ts @@ -3,9 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; - import { ReposAppRequest } from '../../../../../interfaces'; import { jsonError } from '../../../../../middleware'; @@ -17,15 +16,15 @@ router.use('/settings', routeSettings); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; return res.json({ organization: organization.asClientJson(), - }) as unknown as void; + }); }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available in administration - organization', 404)); }); diff --git a/api/client/context/administration/organization/settings.ts b/api/client/context/administration/organization/settings.ts index 4c3201fa1..a1c805df2 100644 --- a/api/client/context/administration/organization/settings.ts +++ b/api/client/context/administration/organization/settings.ts @@ -3,13 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; - -import { OrganizationSetting } from '../../../../../business/entities/organizationSettings/organizationSetting'; +import { OrganizationSetting } from '../../../../../entities/organizationSettings/organizationSetting'; import { ReposAppRequest } from '../../../../../interfaces'; import { jsonError } from '../../../../../middleware'; -import { CreateError, ErrorHelper, getProviders } from '../../../../../lib/transitional'; +import { ErrorHelper, getProviders } from '../../../../../transitional'; const router: Router = Router(); @@ -18,7 +17,7 @@ interface IOrganizationSettings extends ReposAppRequest { } router.use( - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { organization } = req; const { organizationSettingsProvider } = getProviders(req); try { @@ -35,32 +34,11 @@ router.use( router.get( '/', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { dynamicSettings } = req; return res.json({ dynamicSettings, - }) as unknown as void; - }) -); - -router.delete( - '/', - asyncHandler(async function (req: IOrganizationSettings, res: Response) { - const { dynamicSettings } = req; - const { organizationId } = dynamicSettings; - const { organizationSettingsProvider, queryCache } = getProviders(req); - const orgName = req.query.deleteOrganizationConfiguration as string; - if (orgName?.toLowerCase() !== dynamicSettings.organizationName.toLowerCase()) { - throw CreateError.InvalidParameters( - 'The organization name provided does not match the organization name in the configuration.' - ); - } - await organizationSettingsProvider.deleteOrganizationSetting(dynamicSettings); - res.status(204); - if (queryCache) { - queryCache.removeOrganizationById(String(organizationId)); - } - return res.end() as unknown as void; + }); }) ); @@ -68,61 +46,49 @@ router.delete( router.get( '/features', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { dynamicSettings, organization } = req; const { features } = dynamicSettings; return res.json({ features, organizationName: organization.name, - }) as unknown as void; + }); }) ); router.get( '/feature/:flag', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { dynamicSettings, organization } = req; const flag = req.params.flag as string; return res.json({ flag, value: dynamicSettings.features.includes(flag) ? flag : null, organizationName: organization.name, - }) as unknown as void; + }); }) ); router.put( '/feature/:flag', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { dynamicSettings, organization } = req; const { insights, organizationSettingsProvider } = getProviders(req); const { features } = dynamicSettings; const flag = req.params.flag as string; - const restart = req.query.restart === '1'; insights?.trackEvent({ name: 'AddOrganizationFeatureFlag', properties: { flag, - restart, currentFeatureFlags: features.join(', '), }, }); - // special case - if (flag === 'active') { - if (dynamicSettings.active) { - return next(CreateError.InvalidParameters('The organization is already active.')); - } - dynamicSettings.active = true; - } else { - if (features.includes(flag)) { - return next(jsonError(`flag "${flag}" is already set`, 400)); - } - dynamicSettings.features.push(flag); + if (features.includes(flag)) { + return next(jsonError(`flag "${flag}" is already set`, 400)); } + dynamicSettings.features.push(flag); try { - if (restart) { - dynamicSettings.updated = new Date(); - } + dynamicSettings.updated = new Date(); await organizationSettingsProvider.updateOrganizationSetting(dynamicSettings); } catch (error) { return next(jsonError(`error adding flag "${flag}": ${error}`, ErrorHelper.GetStatus(error) || 400)); @@ -130,43 +96,31 @@ router.put( return res.json({ flag, value: dynamicSettings.features.includes(flag) ? flag : null, - restart, organizationName: organization.name, - }) as unknown as void; + }); }) ); router.delete( '/feature/:flag', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { organization, dynamicSettings } = req; const { organizationSettingsProvider, insights } = getProviders(req); const { features } = dynamicSettings; const flag = req.params.flag as string; - const restart = req.query.restart === '1'; insights?.trackEvent({ name: 'RemoveOrganizationFeatureFlag', properties: { flag, - restart, currentFeatureFlags: features.join(', '), }, }); - if (flag === 'active') { - if (!dynamicSettings.active) { - return next(CreateError.InvalidParameters('The organization is already inactive.')); - } - dynamicSettings.active = false; - } else { - if (!features.includes(flag)) { - return next(jsonError(`flag "${flag}" is not set`, 400)); - } - dynamicSettings.features = dynamicSettings.features.filter((flagEntry) => flagEntry !== flag); + if (!features.includes(flag)) { + return next(jsonError(`flag "${flag}" is not set`, 400)); } + dynamicSettings.features = dynamicSettings.features.filter((flagEntry) => flagEntry !== flag); try { - if (restart) { - dynamicSettings.updated = new Date(); - } + dynamicSettings.updated = new Date(); await organizationSettingsProvider.updateOrganizationSetting(dynamicSettings); } catch (error) { return next(jsonError(`error removing flag "${flag}": ${error}`, ErrorHelper.GetStatus(error) || 400)); @@ -174,9 +128,8 @@ router.delete( return res.json({ flag, value: dynamicSettings.features.includes(flag) ? flag : null, - restart, organizationName: organization.name, - }) as unknown as void; + }); }) ); @@ -184,19 +137,19 @@ router.delete( router.get( '/properties', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { dynamicSettings, organization } = req; const { properties } = dynamicSettings; return res.json({ properties, organizationName: organization.name, - }) as unknown as void; + }); }) ); router.get( '/property/:flag', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { dynamicSettings, organization } = req; const propertyName = req.params.propertyName as string; const { properties } = dynamicSettings; @@ -204,18 +157,17 @@ router.get( property: propertyName, value: properties[propertyName] || null, organizationName: organization.name, - }) as unknown as void; + }); }) ); router.put( '/property/:propertyName', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { organization, dynamicSettings } = req; const { insights, organizationSettingsProvider } = getProviders(req); const { properties } = dynamicSettings; const newValue = req.body.value as string; - const restart = req.query.restart === '1'; if (!newValue) { return next(jsonError('body.value required', 400)); } @@ -228,7 +180,6 @@ router.put( name: 'SetOrganizationSettingProperty', properties: { propertyName, - restart, currentProperties: JSON.stringify(properties), currentPropertyValue, }, @@ -236,9 +187,7 @@ router.put( const updateDescription = `Changing property ${propertyName} value from "${currentPropertyValue}" to "${newValue}"`; dynamicSettings.properties[propertyName] = newValue; try { - if (restart) { - dynamicSettings.updated = new Date(); - } + dynamicSettings.updated = new Date(); await organizationSettingsProvider.updateOrganizationSetting(dynamicSettings); } catch (error) { return next( @@ -253,28 +202,25 @@ router.put( value: properties[propertyName] || null, organizationName: organization.name, dynamicSettings, - restart, updateDescription, - }) as unknown as void; + }); }) ); router.delete( '/property/:propertyName', - asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { + asyncHandler(async (req: IOrganizationSettings, res, next) => { const { organization, dynamicSettings } = req; const { organizationSettingsProvider, insights } = getProviders(req); const { properties } = dynamicSettings; const propertyName = req.params.propertyName as string; const currentPropertyValue = properties[propertyName] || null; - const restart = req.query.restart === '1'; insights?.trackEvent({ name: 'RemoveOrganizationSettingProperty', properties: { propertyName, currentProperties: JSON.stringify(properties), currentPropertyValue, - restart, }, }); if (properties[propertyName] === undefined) { @@ -282,9 +228,7 @@ router.delete( } delete dynamicSettings.properties[propertyName]; try { - if (restart) { - dynamicSettings.updated = new Date(); - } + dynamicSettings.updated = new Date(); await organizationSettingsProvider.updateOrganizationSetting(dynamicSettings); } catch (error) { return next( @@ -295,14 +239,13 @@ router.delete( property: propertyName, value: properties[propertyName] || null, organizationName: organization.name, - restart, - }) as unknown as void; + }); }) ); // -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available in administration - organization', 404)); }); diff --git a/api/client/context/administration/types.ts b/api/client/context/administration/types.ts deleted file mode 100644 index 710a2a63b..000000000 --- a/api/client/context/administration/types.ts +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import GitHubApplication, { type GitHubAppDefinition } from '../../../../business/application'; -import { OrganizationSetting } from '../../../../business/entities/organizationSettings/organizationSetting'; -import type { IGitHubAppInstallation, ReposAppRequest } from '../../../../interfaces'; - -export type ApiRequestWithGitHubApplication = ReposAppRequest & { - gitHubApplication: GitHubApplication; -}; - -export enum ManagedOrganizationStatus { - Active = 'Active', - Adopted = 'Adopted', - NotAdopted = 'NotAdopted', -} - -export type ManagedOrganizationAppConfigurationsByOrgView = { - organizationName: string; - status: ManagedOrganizationStatus; - appInstallations: Map; - dynamicSettings: OrganizationSetting; - configuredInstallations: number[]; - id?: number; -}; - -export interface IByOrgViewAppInstallation { - app: GitHubApplication; - installationId?: number; -} - -export type RequestWithInstallation = ApiRequestWithGitHubApplication & { - installation: IGitHubAppInstallation; - organizationDynamicSettings: OrganizationSetting; - organizationStaticSettings: OrganizationSetting; -}; - -export type AdministrativeGitHubAppInstallationResponse = { - app: GitHubAppDefinition; - installationId: number; - dynamicSettings: OrganizationSetting; -}; diff --git a/api/client/context/approvals.ts b/api/client/context/approvals.ts index 4d7a5b817..3e21e398b 100644 --- a/api/client/context/approvals.ts +++ b/api/client/context/approvals.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Team, Organization } from '../../../business'; -import { TeamJoinApprovalEntity } from '../../../business/entities/teamJoinApproval/teamJoinApproval'; +import { TeamJoinApprovalEntity } from '../../../entities/teamJoinApproval/teamJoinApproval'; import { TeamJsonFormat, ReposAppRequest } from '../../../interfaces'; import { jsonError } from '../../../middleware'; import { @@ -16,7 +16,7 @@ import { Approvals_getUserRequests, closeOldRequest, } from '../../../routes/settings/approvals'; -import { getProviders } from '../../../lib/transitional'; +import { getProviders } from '../../../transitional'; import { IndividualContext } from '../../../business/user'; const router: Router = Router(); @@ -30,7 +30,7 @@ const approvalPairToJson = (pair: ApprovalPair) => { router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { approvalProvider, operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { @@ -38,7 +38,7 @@ router.get( teamResponsibilities: [], usersRequests: [], isLinked: false, - }) as unknown as void; + }); } try { // const username = activeContext.getGitHubIdentity().username; @@ -54,7 +54,7 @@ router.get( teamResponsibilities: teamResponsibilities.map(approvalPairToJson), usersRequests: usersRequests.map(approvalPairToJson), }; - return res.json(state) as unknown as void; + return res.json(state); } catch (error) { return next(jsonError(error)); } @@ -65,7 +65,7 @@ router.get( router.get( '/:approvalId', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const approvalId = req.params.approvalId; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { @@ -112,7 +112,7 @@ router.get( }) ); -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use('*', (req: ReposAppRequest, res, next) => { return next(jsonError('Contextual API or route not found within approvals', 404)); }); diff --git a/api/client/context/index.ts b/api/client/context/index.ts index 775716054..efc9530a7 100644 --- a/api/client/context/index.ts +++ b/api/client/context/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Organization } from '../../../business'; @@ -11,7 +11,7 @@ import { IProviders, ReposAppRequest } from '../../../interfaces'; import { jsonError } from '../../../middleware'; import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; -import { ErrorHelper, getProviders } from '../../../lib/transitional'; +import { ErrorHelper, getProviders } from '../../../transitional'; import { IndividualContext } from '../../../business/user'; import routeApprovals from './approvals'; @@ -21,7 +21,6 @@ import routeRepos from './repos'; import routeTeams from './teams'; import routeAdministration from './administration'; import routeSample from './sample'; -import routeSettings from './settings'; const router: Router = Router(); @@ -49,7 +48,7 @@ router.get('/', (req: ReposAppRequest, res) => { router.get( '/specialized/multipleLinkGitHubIdentities', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const links = (activeContext?.link ? [activeContext.link, ...activeContext.additionalLinks] : []).map( @@ -74,13 +73,13 @@ router.get( response.deletedOrChangedUsernames.push(username); } } - return res.json(response) as unknown as void; + return res.json(response); }) ); router.get( '/accountDetails', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; try { @@ -105,11 +104,10 @@ router.get('/orgs', routeOrgs); router.get('/repos', routeRepos); router.get('/teams', routeTeams); router.use('/sample', routeSample); -router.use('/settings', routeSettings); router.use( '/orgs/:orgName', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { orgName } = req.params; const providers = getProviders(req); const { operations } = providers; @@ -125,15 +123,12 @@ router.use( return next(); } catch (noOrgError) { if (ErrorHelper.IsNotFound(noOrgError)) { - // Could be either the org truly does not exist, OR, it's uncontrolled. if (await isUnmanagedOrganization(providers, orgName)) { res.status(204); - res.end(); - return; + return res.end(); } res.status(404); - res.end(); - return; + return res.end(); } return next(jsonError(noOrgError, 500)); } @@ -156,7 +151,7 @@ async function isUnmanagedOrganization(providers: IProviders, orgName: string): router.use('/orgs/:orgName', routeIndividualContextualOrganization); -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use('*', (req: ReposAppRequest, res, next) => { return next(jsonError('Contextual API or route not found', 404)); }); diff --git a/api/client/context/organization/index.ts b/api/client/context/organization/index.ts index 323e6f483..6bb56a540 100644 --- a/api/client/context/organization/index.ts +++ b/api/client/context/organization/index.ts @@ -3,9 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; - import { Organization, Team } from '../../../../business'; import { ReposAppRequest, @@ -17,56 +16,55 @@ import { jsonError } from '../../../../middleware'; import getCompanySpecificDeployment from '../../../../middleware/companySpecificDeployment'; import { IndividualContext } from '../../../../business/user'; -import routeRepos from './repos'; -import routeTeams from './teams'; -import { CreateError } from '../../../../lib/transitional'; +import RouteRepos from './repos'; +import RouteTeams from './teams'; const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return res.json(false) as unknown as void; + return res.json(false); } const membership = await organization.getOperationalMembership( activeContext.getGitHubIdentity().username ); if (!membership) { - return res.json(false) as unknown as void; + return res.json(false); } return res.json({ user: toSanitizedUser(membership.user), organization: toSanitizedOrg(membership.organization), role: membership.role, state: membership.state, - }) as unknown as void; + }); }) ); router.get( '/sudo', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return res.json({ isSudoer: false }) as unknown as void; + return res.json({ isSudoer: false }); } return res.json({ isSudoer: await organization.isSudoer(activeContext.getGitHubIdentity().username, activeContext.link), - }) as unknown as void; + }); }) ); router.get( '/isOwner', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return res.json({ isOrganizationOwner: false }) as unknown as void; + return res.json({ isOrganizationOwner: false }); } try { const username = activeContext.getGitHubIdentity().username; @@ -74,21 +72,21 @@ router.get( const isOrganizationOwner = membership?.role === OrganizationMembershipRole.Admin; return res.json({ isOrganizationOwner, - }) as unknown as void; + }); } catch (error) { - return next(CreateError.InvalidParameters(error)); + return jsonError(error, 400); } }) ); router.delete( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { // "Leave" / remove my context const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return next(CreateError.InvalidParameters('You are not linked')); + return next(jsonError('You are not linked', 400)); } const login = activeContext.getGitHubIdentity().username; const id = activeContext.getGitHubIdentity().id; @@ -96,25 +94,26 @@ router.delete( await organization.removeMember(login, id); return res.json({ message: `Your ${login} account has been removed from ${organization.name}.`, - }) as unknown as void; + }); } catch (error) { console.warn(error); - return next(CreateError.InvalidParameters(error)); + return next(jsonError(error, 400)); } }) ); router.get( '/personalizedTeams', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { try { const organization = req.organization as Organization; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return res.json({ personalizedTeams: [] }) as unknown as void; + return res.json({ personalizedTeams: [] }); } const userAggregateContext = activeContext.aggregations; const maintainedTeams = new Set(); + const broadTeams = new Set(req.organization.broadAccessTeams); const userTeams = userAggregateContext.reduceOrganizationTeams( organization, await userAggregateContext.teams() @@ -132,21 +131,21 @@ router.get( }); return res.json({ personalizedTeams, - }) as unknown as void; + }); } catch (error) { - return next(CreateError.InvalidParameters(error)); + return next(jsonError(error, 400)); } }) ); -router.use('/repos', routeRepos); -router.use('/teams', routeTeams); +router.use('/repos', RouteRepos); +router.use('/teams', RouteTeams); const deployment = getCompanySpecificDeployment(); deployment?.routes?.api?.context?.organization?.index && deployment?.routes?.api?.context?.organization?.index(router); -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available: client>organization', 404)); }); @@ -160,7 +159,6 @@ const toSanitizedUser = (user) => { avatar_url: user.avatar_url, }; }; - const toSanitizedOrg = (org) => { if (!org || !org.login) { return undefined; diff --git a/api/client/context/organization/repo.ts b/api/client/context/organization/repo.ts index 14c337022..e995886f8 100644 --- a/api/client/context/organization/repo.ts +++ b/api/client/context/organization/repo.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { @@ -21,9 +21,9 @@ const router: Router = Router(); router.get( '/permissions', AddRepositoryPermissionsToRequest, - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const permissions = getContextualRepositoryPermissions(req); - return res.json(permissions) as unknown as void; + return res.json(permissions); }) ); @@ -33,7 +33,7 @@ const deployment = getCompanySpecificDeployment(); deployment?.routes?.api?.context?.organization?.repo && deployment?.routes?.api?.context?.organization?.repo(router); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError(`no API or ${req.method} function available for repo`, 404)); }); diff --git a/api/client/context/organization/repoForkUnlock.ts b/api/client/context/organization/repoForkUnlock.ts index 1b7aadd81..55fa0935e 100644 --- a/api/client/context/organization/repoForkUnlock.ts +++ b/api/client/context/organization/repoForkUnlock.ts @@ -3,21 +3,24 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../../middleware'; import { getRepositoryMetadataProvider, ReposAppRequest } from '../../../../interfaces'; import { Organization } from '../../../../business'; -import { getContextualRepository } from '../../../../middleware/github/repoPermissions'; +import { + getContextualRepository, + getContextualRepositoryPermissions, +} from '../../../../middleware/github/repoPermissions'; import { IndividualContext } from '../../../../business/user'; -import { ErrorHelper, getProviders } from '../../../../lib/transitional'; -import NewRepositoryLockdownSystem from '../../../../business/features/newRepositories/newRepositoryLockdown'; +import { ErrorHelper, getProviders } from '../../../../transitional'; +import NewRepositoryLockdownSystem from '../../../../features/newRepositories/newRepositoryLockdown'; const router: Router = Router(); router.use( - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const organization = req.organization as Organization; if (!organization.isNewRepositoryLockdownSystemEnabled()) { return next(jsonError('This endpoint is not available as configured for the organization', 400)); @@ -39,13 +42,12 @@ router.use( router.post( '/approve', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { - const { insights, operations } = getProviders(req); + asyncHandler(async (req: ReposAppRequest, res, next) => { + const { operations } = getProviders(req); const repository = getContextualRepository(req); const repositoryMetadataProvider = getRepositoryMetadataProvider(operations); const organization = repository.organization; const lockdownSystem = new NewRepositoryLockdownSystem({ - insights, operations, organization, repository, @@ -56,7 +58,7 @@ router.post( return res.json({ message: `Unlocked the ${repository.name} repo in the ${organization.name} org`, unlocked: true, - }) as unknown as void; + }); } catch (error) { return next( jsonError( @@ -68,7 +70,7 @@ router.post( }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError(`no API or ${req.method} function available for repo fork unlock`, 404)); }); diff --git a/api/client/context/organization/repos.ts b/api/client/context/organization/repos.ts index c124647a3..851aa48c2 100644 --- a/api/client/context/organization/repos.ts +++ b/api/client/context/organization/repos.ts @@ -3,22 +3,21 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; - import { Repository } from '../../../../business'; import { jsonError } from '../../../../middleware'; import { setContextualRepository } from '../../../../middleware/github/repoPermissions'; -import { OrganizationMembershipState, ReposAppRequest, VoidedExpressRoute } from '../../../../interfaces'; +import { OrganizationMembershipState, ReposAppRequest } from '../../../../interfaces'; import { IndividualContext } from '../../../../business/user'; import { createRepositoryFromClient } from '../../newOrgRepo'; -import routeContextualRepo from './repo'; +import RouteContextualRepo from './repo'; const router: Router = Router(); -async function validateActiveMembership(req: ReposAppRequest, res: Response, next: NextFunction) { +async function validateActiveMembership(req: ReposAppRequest, res, next) { const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { @@ -34,15 +33,11 @@ async function validateActiveMembership(req: ReposAppRequest, res: Response, nex return next(); } -router.post( - '/', - asyncHandler(validateActiveMembership), - asyncHandler(createRepositoryFromClient as VoidedExpressRoute) -); +router.post('/', asyncHandler(validateActiveMembership), asyncHandler(createRepositoryFromClient)); router.use( '/:repoName', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const { repoName } = req.params; let repository: Repository = null; @@ -52,9 +47,9 @@ router.use( }) ); -router.use('/:repoName', routeContextualRepo); +router.use('/:repoName', RouteContextualRepo); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available for repos', 404)); }); diff --git a/api/client/context/organization/team.ts b/api/client/context/organization/team.ts index 649de7635..8574d37fb 100644 --- a/api/client/context/organization/team.ts +++ b/api/client/context/organization/team.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; -import { TeamJoinApprovalEntity } from '../../../../business/entities/teamJoinApproval/teamJoinApproval'; +import { TeamJoinApprovalEntity } from '../../../../entities/teamJoinApproval/teamJoinApproval'; import { ReposAppRequest, OrganizationMembershipState, @@ -24,9 +24,8 @@ import { import { submitTeamJoinRequest } from '../../../../routes/org/team'; import { postActionDecision, TeamApprovalDecision } from '../../../../routes/org/team/approval'; import { PermissionWorkflowEngine } from '../../../../routes/org/team/approvals'; -import { CreateError, getProviders } from '../../../../lib/transitional'; +import { getProviders } from '../../../../transitional'; import { IndividualContext } from '../../../../business/user'; -import getCompanySpecificDeployment from '../../../../middleware/companySpecificDeployment'; const router: Router = Router(); @@ -43,16 +42,16 @@ router.get( '/permissions', asyncHandler(AddTeamPermissionsToRequest), asyncHandler(AddTeamMembershipToRequest), - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const membership = getTeamMembershipFromRequest(req); const permissions = getTeamPermissionsFromRequest(req); - return res.json({ permissions, membership }) as unknown as void; + return res.json({ permissions, membership }); }) ); router.get( '/join/request', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { approvalProvider } = getProviders(req); const team = getContextualTeam(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; @@ -64,49 +63,32 @@ router.get( request = approvals.length > 0 ? approvals[0] : null; } const response: ITeamRequestJsonResponse = { request }; - return res.json(response) as unknown as void; + return res.json(response); }) ); router.post( '/join', asyncHandler(AddTeamMembershipToRequest), - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { try { const providers = getProviders(req); const { approvalProvider } = providers; const membership = getTeamMembershipFromRequest(req); if (!membership.isLinked) { - return res.json({ - error: 'You have not linked your GitHub account to your corporate identity yet', - }) as unknown as void; + return res.json({ error: 'You have not linked your GitHub account to your corporate identity yet' }); } if (membership.membershipState === OrganizationMembershipState.Active) { - return res.json({ error: 'You already have an active team membership' }) as unknown as void; + return res.json({ error: 'You already have an active team membership' }); } const team = getContextualTeam(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; - const companySpecific = getCompanySpecificDeployment(); - if (companySpecific?.middleware?.teamPermissions.beforeJoinRequest) { - try { - const optionalOutcome = await companySpecific.middleware.teamPermissions.beforeJoinRequest( - providers, - activeContext, - team - ); - if (optionalOutcome) { - return res.json(optionalOutcome) as unknown as void; - } - } catch (error) { - return next(error); - } - } // no point query currently implemented let approvals = await approvalProvider.queryPendingApprovalsForTeam(String(team.id)); approvals = approvals.filter((approval) => approval.corporateId === activeContext.corporateIdentity.id); const request = approvals.length > 0 ? approvals[0] : null; if (request) { - return res.json({ error: 'You already have a pending team join request' }) as unknown as void; + return res.json({ error: 'You already have a pending team join request' }); } // const justification = (req.body.justification || '') as string; @@ -120,7 +102,7 @@ router.post( correlationId, hostname ); - return res.json(outcome) as unknown as void; + return res.json(outcome); } catch (error) { return next(jsonError(error)); } @@ -130,21 +112,21 @@ router.post( router.post( '/join/approvals/:approvalId', asyncHandler(AddTeamPermissionsToRequest), - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { approvalId: id } = req.params; if (!id) { - return next(CreateError.InvalidParameters('invalid approval')); + return next(jsonError('invalid approval', 400)); } const permissions = getTeamPermissionsFromRequest(req); if (!permissions.allowAdministration) { - return next(CreateError.NotAuthorized('you do not have permission to administer this team')); + return next(jsonError('you do not have permission to administer this team', 401)); } const providers = getProviders(req); const { approvalProvider, operations } = providers; const team = getContextualTeam(req); const request = await approvalProvider.getApprovalEntity(id); if (String(request.teamId) !== String(team.id)) { - return next(CreateError.InvalidParameters('mismatch on team')); + return next(jsonError('mismatch on team', 400)); } const requestingUser = await operations.getAccountWithDetailsAndLink(request.thirdPartyId); const approvalPackage = { request, requestingUser, id }; @@ -164,7 +146,7 @@ router.post( decision = TeamApprovalDecision.Reopen; break; default: - return next(CreateError.InvalidParameters('invalid or no decision type')); + return next(jsonError('invalid or no decision type', 400)); } const teamBaseUrl = `/orgs/${team.organization.name}/teams/${team.slug}/`; // trailing? try { @@ -172,9 +154,9 @@ router.post( if (outcome.error) { throw outcome.error; } - return res.json(outcome) as unknown as void; + return res.json(outcome); } catch (outcomeError) { - return next(CreateError.ServerError(outcomeError)); + return next(jsonError(outcomeError, 500)); } }) ); @@ -182,21 +164,21 @@ router.post( router.get( '/join/approvals/:approvalId', asyncHandler(AddTeamPermissionsToRequest), - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { approvalId: id } = req.params; if (!id) { - return next(CreateError.InvalidParameters('invalid approval')); + return next(jsonError('invalid approval', 400)); } const permissions = getTeamPermissionsFromRequest(req); if (!permissions.allowAdministration) { - return next(CreateError.NotAuthorized('you do not have permission to administer this team')); + return next(jsonError('you do not have permission to administer this team', 401)); } const providers = getProviders(req); const { approvalProvider, graphProvider } = providers; const team = getContextualTeam(req); const request = await approvalProvider.getApprovalEntity(id); if (String(request.teamId) !== String(team.id)) { - return next(CreateError.InvalidParameters('mismatch on team')); + return next(jsonError('mismatch on team', 400)); } let management: IGraphEntry[] = null; if (request?.corporateId) { @@ -206,14 +188,14 @@ router.get( // we ignore any failure here, this is an optional value-add for now } } - return res.json({ approval: request, management }) as unknown as void; + return res.json({ approval: request, management }); }) ); router.get( '/join/approvals', asyncHandler(AddTeamPermissionsToRequest), - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { approvalProvider } = getProviders(req); const team = getContextualTeam(req); const permissions = getTeamPermissionsFromRequest(req); @@ -224,22 +206,22 @@ router.get( response.allowAdministration = permissions.allowAdministration; response.approvals = await approvalProvider.queryPendingApprovalsForTeam(String(team.id)); } - return res.json(response) as unknown as void; + return res.json(response); }) ); router.post( '/role/:login', asyncHandler(AddTeamPermissionsToRequest), - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { role } = req.body; const { login } = req.params; if (!login) { - return next(CreateError.InvalidParameters('invalid login')); + return next(jsonError('invalid login', 400)); } const permissions = getTeamPermissionsFromRequest(req); if (!permissions.allowAdministration) { - return next(CreateError.NotAuthorized('you do not have permission to administer this team')); + return next(jsonError('you do not have permission to administer this team', 401)); } const team = getContextualTeam(req); try { @@ -248,21 +230,17 @@ router.post( !currentRole || (currentRole as ITeamMembershipRoleState).state !== OrganizationMembershipState.Active ) { - return next(CreateError.InvalidParameters(`${login} is not currently a member of the team`)); + return next(jsonError(`${login} is not currently a member of the team`, 400)); } const response = await team.addMembership(login, { role }); - return res.json(response) as unknown as void; + return res.json(response); } catch (outcomeError) { - return next(CreateError.ServerError(outcomeError)); + return next(jsonError(outcomeError, 500)); } }) ); -const deployment = getCompanySpecificDeployment(); -deployment?.routes?.api?.context?.organization?.team && - deployment?.routes?.api?.context?.organization?.team(router); - -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available for contextual team', 404)); }); diff --git a/api/client/context/organization/teams.ts b/api/client/context/organization/teams.ts index 3cb9ffeea..99781f31b 100644 --- a/api/client/context/organization/teams.ts +++ b/api/client/context/organization/teams.ts @@ -3,9 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; - import { Team } from '../../../../business'; import { jsonError } from '../../../../middleware'; import { setContextualTeam } from '../../../../middleware/github/teamPermissions'; @@ -19,7 +18,7 @@ const router: Router = Router(); router.use( '/:teamSlug', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const { teamSlug } = req.params; let team: Team = null; @@ -36,7 +35,7 @@ router.use( router.use('/:teamSlug', RouteTeam); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available for repos', 404)); }); diff --git a/api/client/context/orgs.ts b/api/client/context/orgs.ts index 962e43f44..fd242331f 100644 --- a/api/client/context/orgs.ts +++ b/api/client/context/orgs.ts @@ -15,7 +15,7 @@ export default asyncHandler(async (req: ReposAppRequest, res) => { member: [], admin: [], isLinked: false, - }) as unknown as void; + }); } const orgs = await activeContext.aggregations.getQueryCacheOrganizations(); const data = { @@ -33,5 +33,5 @@ export default asyncHandler(async (req: ReposAppRequest, res) => { }; }), }; - return res.json(data) as unknown as void; + return res.json(data); }); diff --git a/api/client/context/repos.ts b/api/client/context/repos.ts index 2af5ab598..e446dbda3 100644 --- a/api/client/context/repos.ts +++ b/api/client/context/repos.ts @@ -3,20 +3,19 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; import asyncHandler from 'express-async-handler'; import { GitHubRepositoryPermission, ReposAppRequest } from '../../../interfaces'; import { IndividualContext } from '../../../business/user'; -export default asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { +export default asyncHandler(async (req: ReposAppRequest, res, next) => { try { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { return res.json({ isLinked: false, repositories: [], - }) as unknown as void; + }); } let permissions = await activeContext.aggregations.getQueryCacheRepositoryPermissions(); permissions = permissions.filter((perm) => { @@ -48,7 +47,7 @@ export default asyncHandler(async (req: ReposAppRequest, res: Response, next: Ne // TODO: would be nice for team permission for repos to also store the team slug in the query cache! }; }), - }) as unknown as void; + }); } catch (error) { return next(error); } diff --git a/api/client/context/sample.ts b/api/client/context/sample.ts index 687377ea7..e957ab121 100644 --- a/api/client/context/sample.ts +++ b/api/client/context/sample.ts @@ -3,20 +3,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { sendLinkedAccountMail } from '../../../business/operations/link'; import { ReposAppRequest } from '../../../interfaces'; import { jsonError } from '../../../middleware'; -import { CreateError, getProviders } from '../../../lib/transitional'; +import { CreateError, getProviders } from '../../../transitional'; import { IndividualContext } from '../../../business/user'; const router: Router = Router(); router.get( '/:templateName', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const templateName = req.params.templateName as string; @@ -39,11 +39,11 @@ router.get( } catch (error) { return next(error); } - return res.json({ templateName }) as unknown as void; + return res.json({ templateName }); }) ); -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use('*', (req: ReposAppRequest, res, next) => { return next(jsonError('Contextual API or route not found within samples', 404)); }); diff --git a/api/client/context/settings.ts b/api/client/context/settings.ts deleted file mode 100644 index 86a72a256..000000000 --- a/api/client/context/settings.ts +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { NextFunction, Response, Router } from 'express'; -import asyncHandler from 'express-async-handler'; - -import { ReposAppRequest } from '../../../interfaces'; -import { CreateError, getProviders } from '../../../lib/transitional'; -import { getUserSettings } from '../../../middleware/business/userSettings'; - -import type { ReposAppRequestWithUserSettings } from '../../../interfaces/middleware'; - -const router: Router = Router(); - -router.use(asyncHandler(getUserSettings)); - -router.get( - '/', - asyncHandler(async (req: ReposAppRequestWithUserSettings, res: Response, next: NextFunction) => { - const { userSettings } = req; - return res.json(userSettings || {}) as unknown as any; - }) -); - -async function setPublicDataSharingValue( - sharingOptOn: boolean, - req: ReposAppRequestWithUserSettings, - res: Response, - next: NextFunction -) { - const { userSettings } = req; - const { userSettingsProvider } = getProviders(req); - userSettings.contributionShareOptIn = sharingOptOn; - await userSettingsProvider.updateUserSettings(userSettings); - return res.status(201).json(userSettings || {}) as unknown as any; -} - -// Actions as separate posts to keep the API simple -router.post('/publicDataSharing/optIn', asyncHandler(setPublicDataSharingValue.bind(null, true))); -router.post('/publicDataSharing/optOut', asyncHandler(setPublicDataSharingValue.bind(null, false))); - -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { - return next(CreateError.NotFound('Contextual API route not found: /settings')); -}); - -export default router; diff --git a/api/client/context/teams.ts b/api/client/context/teams.ts index ad45b7a43..4ffc3405e 100644 --- a/api/client/context/teams.ts +++ b/api/client/context/teams.ts @@ -4,24 +4,23 @@ // import asyncHandler from 'express-async-handler'; -import { NextFunction, Response } from 'express'; import { ReposAppRequest, TeamJsonFormat } from '../../../interfaces'; import { IndividualContext } from '../../../business/user'; -export default asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { +export default asyncHandler(async (req: ReposAppRequest, res, next) => { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { return res.json({ isLinked: false, member: [], maintainer: [], - }) as unknown as void; + }); } const permissions = await activeContext.aggregations.getQueryCacheTeams(); return res.json({ isLinked: true, member: permissions.member.map((t) => t.asJson(TeamJsonFormat.Augmented)), maintainer: permissions.maintainer.map((t) => t.asJson(TeamJsonFormat.Augmented)), - }) as unknown as void; + }); }); diff --git a/api/client/index.ts b/api/client/index.ts index db0e86073..e1b4538b3 100644 --- a/api/client/index.ts +++ b/api/client/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { @@ -12,9 +12,8 @@ import { requireAccessTokenClient, setIdentity, jsonError, - requireAuthenticatedUserOrSignIn, } from '../../middleware'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; @@ -31,19 +30,13 @@ import routeNews from './news'; import routeCrossOrganizationPeople from './people'; import routeCrossOrganizationRepos from './repos'; import routeCrossOrganizationTeams from './teams'; -import routeUsers from './users'; const router: Router = Router(); -router.use((req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use((req: ReposAppRequest, res, next) => { const { config } = getProviders(req); if (config?.features?.allowApiClient) { - if (req.isAuthenticated()) { - return next(); - } else if (req.query.authenticate === 'session') { - return requireAuthenticatedUserOrSignIn(req, res, next); - } - return next(jsonError('Session is not authenticated', 401)); + return req.isAuthenticated() ? next() : next(jsonError('Session is not authenticated', 401)); } return next(jsonError('Client API features unavailable', 403)); }); @@ -64,7 +57,6 @@ router.use('/signout', routeSession); router.use('/people', routeCrossOrganizationPeople); router.use('/repos', routeCrossOrganizationRepos); router.use('/teams', routeCrossOrganizationTeams); -router.use('/users', routeUsers); router.use('/news', routeNews); const dynamicStartupInstance = getCompanySpecificDeployment(); @@ -89,7 +81,7 @@ router.get('/', (req: ReposAppRequest, res) => { appService: config?.webServer?.appService?.name ? { name: config?.webServer?.appService?.name, - slot: config?.webServer?.appService?.advanced?.slotType || config?.webServer?.appService?.slot, + slot: config?.webServer?.appService?.slot, region: config?.webServer?.appService?.region, } : undefined, @@ -128,7 +120,7 @@ router.get('/', (req: ReposAppRequest, res) => { return res.send(JSON.stringify(data, null, 2)); }); -router.use((req, res: Response, next: NextFunction) => { +router.use((req, res, next) => { return next(jsonError('The resource or endpoint you are looking for is not there', 404)); }); diff --git a/api/client/linking.ts b/api/client/linking.ts index c3188b951..918af1e7d 100644 --- a/api/client/linking.ts +++ b/api/client/linking.ts @@ -3,19 +3,19 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { IndividualContext } from '../../business/user'; import { jsonError } from '../../middleware'; -import { ErrorHelper, getProviders } from '../../lib/transitional'; +import { ErrorHelper, getProviders } from '../../transitional'; import { unlinkInteractive } from '../../routes/unlink'; import { interactiveLinkUser } from '../../routes/link'; import { ReposAppRequest } from '../../interfaces'; const router: Router = Router(); -async function validateLinkOk(req: ReposAppRequest, res: Response, next: NextFunction) { +async function validateLinkOk(req: ReposAppRequest, res, next) { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const providers = getProviders(req); const insights = providers.insights; @@ -91,7 +91,7 @@ async function validateLinkOk(req: ReposAppRequest, res: Response, next: NextFun } } -router.get('/banner', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.get('/banner', (req: ReposAppRequest, res, next) => { const { config } = getProviders(req); const offline = config?.github?.links?.provider?.linkingOfflineMessage; return res.json({ offline }); @@ -99,7 +99,7 @@ router.get('/banner', (req: ReposAppRequest, res: Response, next: NextFunction) router.delete( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; return unlinkInteractive(true, activeContext, req, res, next); }) @@ -108,13 +108,13 @@ router.delete( router.post( '/', validateLinkOk, - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; return interactiveLinkUser(true, activeContext, req, res, next); }) ); -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use('*', (req: ReposAppRequest, res, next) => { return next(jsonError('API or route not found', 404)); }); diff --git a/api/client/newOrgRepo.ts b/api/client/newOrgRepo.ts index 0984312b3..280dd8879 100644 --- a/api/client/newOrgRepo.ts +++ b/api/client/newOrgRepo.ts @@ -3,24 +3,19 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import _ from 'lodash'; - -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; +import _ from 'lodash'; + +import { getProviders } from '../../transitional'; import { jsonError } from '../../middleware/jsonError'; import { IndividualContext } from '../../business/user'; import { Organization } from '../../business/organization'; import { CreateRepository, ICreateRepositoryApiResult, CreateRepositoryEntrypoint } from '../createRepo'; import { Team } from '../../business/team'; -import { - GitHubRepositoryVisibility, - GitHubTeamRole, - ReposAppRequest, - VoidedExpressRoute, -} from '../../interfaces'; +import { GitHubRepositoryVisibility, GitHubTeamRole, ReposAppRequest } from '../../interfaces'; // This file supports the client apps for creating repos. @@ -30,7 +25,7 @@ interface ILocalApiRequest extends ReposAppRequest { knownRequesterMailAddress?: string; } -router.get('/metadata', (req: ILocalApiRequest, res: Response, next: NextFunction) => { +router.get('/metadata', (req: ILocalApiRequest, res, next) => { try { const options = { projectType: req.query.projectType, @@ -45,13 +40,12 @@ router.get('/metadata', (req: ILocalApiRequest, res: Response, next: NextFunctio router.get( '/personalizedTeams', - asyncHandler(async (req: ILocalApiRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalApiRequest, res, next) => { try { const organization = req.organization as Organization; const userAggregateContext = req.apiContext.aggregations; const maintainedTeams = new Set(); const broadTeams = new Set(req.organization.broadAccessTeams); - const openAccessTeams = new Set(req.organization.openAccessTeams); const userTeams = userAggregateContext.reduceOrganizationTeams( organization, await userAggregateContext.teams() @@ -63,7 +57,6 @@ router.get( const personalizedTeams = Array.from(combinedTeams.values()).map((combinedTeam) => { return { broad: broadTeams.has(Number(combinedTeam.id)), - isOpenAccessTeam: openAccessTeams.has(Number(combinedTeam.id)), description: combinedTeam.description, id: Number(combinedTeam.id), name: combinedTeam.name, @@ -74,7 +67,7 @@ router.get( }); return res.json({ personalizedTeams, - }) as unknown as void; + }); } catch (error) { return next(jsonError(error, 400)); } @@ -83,12 +76,11 @@ router.get( router.get( '/teams', - asyncHandler(async (req: ILocalApiRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalApiRequest, res, next) => { const providers = getProviders(req); const queryCache = providers.queryCache; const organization = req.organization as Organization; const broadTeams = new Set(organization.broadAccessTeams); - const openAccessTeams = new Set(req.organization.openAccessTeams); if (req.query.refresh === undefined && queryCache && queryCache.supportsTeams) { // Use the newer method in this case... const organizationTeams = await queryCache.organizationTeams(organization.id.toString()); @@ -99,12 +91,9 @@ router.get( if (broadTeams.has(Number(t.id))) { t['broad'] = true; } - if (openAccessTeams.has(Number(t.id))) { - t['openAccess'] = true; - } return t; }), - }) as unknown as void; + }); } // By default, allow a 30-second old list of teams. If the cached @@ -165,7 +154,7 @@ router.get( }) ); -export async function discoverUserIdentities(req: ReposAppRequest, res: Response, next: NextFunction) { +export async function discoverUserIdentities(req: ReposAppRequest, res, next) { const apiContext = req.apiContext as IndividualContext; const providers = getProviders(req); const mailAddressProvider = providers.mailAddressProvider; @@ -186,16 +175,12 @@ export async function discoverUserIdentities(req: ReposAppRequest, res: Response return next(); } -router.post( - '/repo/:repo', - asyncHandler(discoverUserIdentities), - asyncHandler(createRepositoryFromClient as VoidedExpressRoute) -); +router.post('/repo/:repo', asyncHandler(discoverUserIdentities), asyncHandler(createRepositoryFromClient)); -export async function createRepositoryFromClient(req: ILocalApiRequest, res: Response, next: NextFunction) { +export async function createRepositoryFromClient(req: ILocalApiRequest, res, next) { const providers = getProviders(req); const { insights, diagnosticsDrop, customizedNewRepositoryLogic, graphProvider } = providers; - const individualContext = req.watchdogContextOverride || req.individualContext || req.apiContext; + const individualContext = req.individualContext || req.apiContext; const config = getProviders(req).config; const organization = (req.organization || (req as any).aeOrganization) as Organization; const existingRepoId = req.body.existingrepoid; diff --git a/api/client/newRepo.ts b/api/client/newRepo.ts index 8d28cae1c..26aca31e6 100644 --- a/api/client/newRepo.ts +++ b/api/client/newRepo.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { jsonError } from '../../middleware/jsonError'; import newOrgRepo from './newOrgRepo'; import { ReposAppRequest } from '../../interfaces'; -router.use('/org/:org', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use('/org/:org', (req: ReposAppRequest, res, next) => { const orgName = req.params.org; const { operations } = getProviders(req); try { diff --git a/api/client/news.ts b/api/client/news.ts index 24cb920a0..b33739fa7 100644 --- a/api/client/news.ts +++ b/api/client/news.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { ReposAppRequest } from '../../interfaces'; const router: Router = Router(); @@ -16,11 +16,11 @@ router.get( '/', asyncHandler(async (req: ReposAppRequest, res) => { const { config } = getProviders(req); - return res.json({ articles: config?.news?.all || [] }) as unknown as void; + return res.json({ articles: config?.news?.all || [] }); }) ); -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use('*', (req: ReposAppRequest, res, next) => { return next(jsonError('API or route not found within news', 404)); }); diff --git a/api/client/organization/annotations.ts b/api/client/organization/annotations.ts index 764ac8b63..834e2c130 100644 --- a/api/client/organization/annotations.ts +++ b/api/client/organization/annotations.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware/jsonError'; @@ -19,12 +19,10 @@ import { import { IOrganizationAnnotationChange, OrganizationAnnotation, - getOrganizationAnnotationRestrictedPropertyNames, -} from '../../../business/entities/organizationAnnotation'; -import { CreateError, ErrorHelper, getProviders } from '../../../lib/transitional'; +} from '../../../entities/organizationAnnotation'; +import { ErrorHelper, getProviders } from '../../../transitional'; import { IndividualContext } from '../../../business/user'; import { IProviders } from '../../../interfaces'; -import { ensureOrganizationProfileMiddleware } from '../../../middleware/github/ensureOrganizationProfile'; const router: Router = Router(); @@ -35,7 +33,7 @@ type IRequestWithOrganizationAnnotations = IReposAppRequestWithOrganizationManag router.use( '/', checkIsCorporateAdministrator, - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { const { organizationAnnotationsProvider } = getProviders(req); const { organization, organizationManagementType, organizationProfile } = req; const organizationId = @@ -55,28 +53,24 @@ router.use( router.get( '/', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { const { annotations } = req; // Limited redaction - const annotation = { ...annotations }; const isSystemAdministrator = await getIsCorporateAdministrator(req); - for (const propertyToRedact of getOrganizationAnnotationRestrictedPropertyNames(isSystemAdministrator)) { - delete annotation[propertyToRedact]; + if (!isSystemAdministrator && annotations.administratorNotes) { + annotations.administratorNotes = '*****'; + } + if (!isSystemAdministrator && annotations?.history?.length > 0) { + delete annotations.history; } return res.json({ isSystemAdministrator, - annotations: annotation, - }) as unknown as void; + annotations, + }); }) ); -router.use(ensureOrganizationProfileMiddleware); - -async function ensureAnnotations( - req: IRequestWithOrganizationAnnotations, - res: Response, - next: NextFunction -) { +async function ensureAnnotations(req: IRequestWithOrganizationAnnotations, res, next) { if (!req.annotations) { const { organizationAnnotationsProvider } = getProviders(req); try { @@ -86,7 +80,7 @@ async function ensureAnnotations( await organizationAnnotationsProvider.insertAnnotations(annotations); req.annotations = annotations; } catch (error) { - return next(jsonError(error)); + return next(error); } } return next(); @@ -97,11 +91,11 @@ router.put('*', AuthorizeOnlyCorporateAdministrators, ensureAnnotations); router.put( '/', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { // No-op mostly, since ensureAnnotations precedes return res.json({ annotations: req.annotations, - }) as unknown as void; + }); }) ); @@ -133,17 +127,17 @@ function addChangeNote( router.put( '/property/:propertyName', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const changes: IOrganizationAnnotationChange[] = []; const newValue = req.body.value as string; if (!newValue) { - return next(CreateError.InvalidParameters('body.value required')); + return next(jsonError('body.value required', 400)); } if (typeof newValue !== 'string') { - return next(CreateError.InvalidParameters('body.value must be a string value')); + return next(jsonError('body.value must be a string value', 400)); } const propertyName = req.params.propertyName as string; const currentPropertyValue = annotations.properties[propertyName] || null; @@ -154,13 +148,13 @@ router.put( return res.json({ annotations, updated, - }) as unknown as void; + }); }) ); router.delete( '/property/:propertyName', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; @@ -168,7 +162,7 @@ router.delete( const propertyName = req.params.propertyName as string; const currentPropertyValue = annotations.properties[propertyName] || null; if (annotations.properties[propertyName] === undefined) { - return next(CreateError.InvalidParameters(`property ${propertyName} is not set`)); + return next(jsonError(`property ${propertyName} is not set`, 400)); } delete annotations.properties[propertyName]; addChangeNote( @@ -183,7 +177,7 @@ router.delete( return res.json({ annotations, updated, - }) as unknown as void; + }); }) ); @@ -191,14 +185,14 @@ router.delete( router.put( '/feature/:flag', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const changes: IOrganizationAnnotationChange[] = []; const flag = req.params.flag as string; if (annotations.features.includes(flag)) { - return next(CreateError.InvalidParameters(`The feature flag ${flag} is already present`)); + return next(jsonError(`The feature flag ${flag} is already present`, 400)); } annotations.features.push(flag); addChangeNote( @@ -213,20 +207,20 @@ router.put( return res.json({ annotations, updated, - }) as unknown as void; + }); }) ); router.delete( '/feature/:flag', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const changes: IOrganizationAnnotationChange[] = []; const flag = req.params.flag as string; if (!annotations.features.includes(flag)) { - return next(CreateError.InvalidParameters(`The feature flag ${flag} is not set`)); + return next(jsonError(`The feature flag ${flag} is not set`, 400)); } annotations.features = annotations.features.filter((f) => f !== flag); addChangeNote( @@ -241,7 +235,7 @@ router.delete( return res.json({ annotations, updated, - }) as unknown as void; + }); }) ); @@ -249,7 +243,7 @@ router.delete( router.patch( '/', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; @@ -273,7 +267,7 @@ router.patch( return res.json({ annotations, updated, - }) as unknown as void; + }); }) ); @@ -296,7 +290,7 @@ async function applyPatch( // features, properties // flag -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available within the organization annotations route', 404)); }); diff --git a/api/client/organization/index.ts b/api/client/organization/index.ts index 6cc49a116..3acf46701 100644 --- a/api/client/organization/index.ts +++ b/api/client/organization/index.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { ReposAppRequest } from '../../../interfaces'; import { jsonError } from '../../../middleware'; import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; -import { getProviders } from '../../../lib/transitional'; +import { getProviders } from '../../../transitional'; import { blockIfUnmanagedOrganization, IReposAppRequestWithOrganizationManagementType, @@ -32,14 +32,14 @@ router.get( asyncHandler(async (req: IReposAppRequestWithOrganizationManagementType, res) => { const { organization, organizationProfile, organizationManagementType } = req; if (organizationManagementType === OrganizationManagementType.Unmanaged) { - return res.json(organizationProfile) as unknown as void; + return res.json(organizationProfile); } const entity = organization.getEntity(); if (entity) { - return res.json(entity) as unknown as void; + return res.json(entity); } const details = await organization.getDetails(); - return res.json(details) as unknown as void; + return res.json(details); }) ); @@ -63,21 +63,19 @@ asClientJson() { */ router.get( '/', - asyncHandler( - async (req: IReposAppRequestWithOrganizationManagementType, res: Response, next: NextFunction) => { - const { organization, organizationProfile, organizationManagementType } = req; - if (organizationManagementType === OrganizationManagementType.Unmanaged) { - return res.json({ - managementType: req.organizationManagementType, - id: organizationProfile.id, - }) as unknown as void; - } + asyncHandler(async (req: IReposAppRequestWithOrganizationManagementType, res, next) => { + const { organization, organizationProfile, organizationManagementType } = req; + if (organizationManagementType === OrganizationManagementType.Unmanaged) { return res.json({ managementType: req.organizationManagementType, - ...organization.asClientJson(), - }) as unknown as void; + id: organizationProfile.id, + }); } - ) + return res.json({ + managementType: req.organizationManagementType, + ...organization.asClientJson(), + }); + }) ); router.use('/annotations', routeAnnotations); @@ -95,7 +93,7 @@ router.get('/newRepoBanner', (req: ReposAppRequest, res) => { return res.json({ newRepositoriesOffline }); }); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available', 404)); }); diff --git a/api/client/organization/newRepoMetadata.ts b/api/client/organization/newRepoMetadata.ts index 4133cb2b5..4761fbb8e 100644 --- a/api/client/organization/newRepoMetadata.ts +++ b/api/client/organization/newRepoMetadata.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware/jsonError'; @@ -13,7 +13,7 @@ const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const metadata = organization.getRepositoryCreateMetadata(); res.json(metadata); @@ -22,7 +22,7 @@ router.get( router.get( '/byProjectReleaseType', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const options = { projectType: req.query.projectType, @@ -32,7 +32,7 @@ router.get( }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available within this path', 404)); }); diff --git a/api/client/organization/people.ts b/api/client/organization/people.ts index 5d75ab5c4..f8f39743a 100644 --- a/api/client/organization/people.ts +++ b/api/client/organization/people.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware'; -import { getProviders } from '../../../lib/transitional'; +import { getProviders } from '../../../transitional'; import LeakyLocalCache, { getLinksLightCache } from '../leakyLocalCache'; import JsonPager from '../jsonPager'; import { @@ -118,7 +118,7 @@ export async function equivalentLegacyPeopleSearch(req: ReposAppRequest, options router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const pager = new JsonPager(req, res); try { const searcher = await equivalentLegacyPeopleSearch(req); @@ -142,7 +142,7 @@ router.get( }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available within this people list', 404)); }); diff --git a/api/client/organization/repo.ts b/api/client/organization/repo.ts index 635105e2d..4ad38e634 100644 --- a/api/client/organization/repo.ts +++ b/api/client/organization/repo.ts @@ -3,32 +3,36 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware'; -import { CreateError, ErrorHelper, getProviders } from '../../../lib/transitional'; +import { ErrorHelper, getProviders } from '../../../transitional'; +import { Repository } from '../../../business'; import { IndividualContext } from '../../../business/user'; -import NewRepositoryLockdownSystem from '../../../business/features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../../../features/newRepositories/newRepositoryLockdown'; import { AddRepositoryPermissionsToRequest, getContextualRepositoryPermissions, } from '../../../middleware/github/repoPermissions'; +import { renameRepositoryDefaultBranchEndToEnd } from '../../../routes/org/repos'; import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; import RouteRepoPermissions from './repoPermissions'; import { + ReposAppRequest, LocalApiRepoAction, getRepositoryMetadataProvider, NoCacheNoBackground, - GitHubRepositoryVisibility, } from '../../../interfaces'; -import { RequestWithRepo } from '../../../middleware/business/repository'; -enum RepositoryChangeAction { +type RequestWithRepo = ReposAppRequest & { + repository: Repository; +}; + +enum ArchivalAction { Archive, UnArchive, - Privatize, } const router: Router = Router(); @@ -40,15 +44,15 @@ router.use('/permissions', RouteRepoPermissions); router.get( '/', - asyncHandler(async (req: RequestWithRepo, res: Response, next: NextFunction) => { + asyncHandler(async (req: RequestWithRepo, res, next) => { const { repository } = req; try { await repository.getDetails({ backgroundRefresh: false }); const clone = Object.assign({}, repository.getEntity()); - delete (clone as any).temp_clone_token; // never share this back - delete (clone as any).cost; + delete clone.temp_clone_token; // never share this back + delete clone.cost; - return res.json(repository.getEntity()) as unknown as void; + return res.json(repository.getEntity()); } catch (repoError) { if (ErrorHelper.IsNotFound(repoError)) { // // Attempt fallback by ID (?) @@ -60,7 +64,7 @@ router.get( router.get( '/exists', - asyncHandler(async (req: RequestWithRepo, res: Response, next: NextFunction) => { + asyncHandler(async (req: RequestWithRepo, res, next) => { let exists = false; let name: string = undefined; const { repository } = req; @@ -77,85 +81,58 @@ router.get( } } } catch (repoError) {} - return res.json({ exists, name }) as unknown as void; + return res.json({ exists, name }); }) ); -router.get( - '/archived', - asyncHandler(async (req: RequestWithRepo, res: Response, next: NextFunction) => { +router.patch( + '/renameDefaultBranch', + asyncHandler(AddRepositoryPermissionsToRequest), + asyncHandler(async function (req: RequestWithRepo, res, next) { + const providers = getProviders(req); + const activeContext = (req.individualContext || req.apiContext) as IndividualContext; + const repoPermissions = getContextualRepositoryPermissions(req); + const targetBranchName = req.body.default_branch; const { repository } = req; try { - await repository.getDetails(); - const data = { - archivedAt: null, - }; - if (repository?.archived) { - const archivedAt = await repository.getArchivedAt(); - if (archivedAt) { - data.archivedAt = archivedAt.toISOString(); - } - } - return res.json(data) as unknown as void; + const result = await renameRepositoryDefaultBranchEndToEnd( + providers, + activeContext, + repoPermissions, + repository, + targetBranchName, + true /* wait for refresh before sending response */ + ); + return res.json(result); } catch (error) { - return next(error); + return next(jsonError(error)); } }) ); -router.post( - '/privatize', - asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(RepositoryStateChangeHandler.bind(null, RepositoryChangeAction.Privatize)) -); router.post( '/archive', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(RepositoryStateChangeHandler.bind(null, RepositoryChangeAction.Archive)) + asyncHandler(archiveUnArchiveRepositoryHandler.bind(null, ArchivalAction.Archive)) ); router.post( '/unarchive', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(RepositoryStateChangeHandler.bind(null, RepositoryChangeAction.UnArchive)) + asyncHandler(archiveUnArchiveRepositoryHandler.bind(null, ArchivalAction.UnArchive)) ); -async function RepositoryStateChangeHandler( - action: RepositoryChangeAction, - req: RequestWithRepo, - res: Response, - next: NextFunction -) { +async function archiveUnArchiveRepositoryHandler(action: ArchivalAction, req: RequestWithRepo, res, next) { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const providers = getProviders(req); const { insights } = providers; const repoPermissions = getContextualRepositoryPermissions(req); - let phrase: string = null; - let insightsPrefix: string = null; - let localAction: LocalApiRepoAction = null; - switch (action) { - case RepositoryChangeAction.Archive: - phrase = 'archive'; - insightsPrefix = 'ArchiveRepo'; - localAction = LocalApiRepoAction.Archive; - break; - case RepositoryChangeAction.UnArchive: - phrase = 'unarchive'; - insightsPrefix = 'UnArchiveRepo'; - localAction = LocalApiRepoAction.UnArchive; - break; - case RepositoryChangeAction.Privatize: - phrase = 'privatize'; - insightsPrefix = 'PrivatizeRepo'; - localAction = LocalApiRepoAction.Privatize; - break; - default: - return next(jsonError('Invalid action', 400)); - } + const phrase = action === ArchivalAction.Archive ? 'archive' : 'unarchive'; const completedPhrase = `${phrase}d`; if (!repoPermissions.allowAdministration) { return next(jsonError(`You do not have permission to ${phrase} this repo`, 403)); } + const insightsPrefix = `${action === ArchivalAction.UnArchive ? 'Un' : ''}ArchiveRepo`; const { repository } = req; try { insights?.trackEvent({ @@ -170,28 +147,16 @@ async function RepositoryStateChangeHandler( const currentRepositoryState = deployment?.features?.repositoryActions?.getCurrentRepositoryState ? await deployment.features.repositoryActions.getCurrentRepositoryState(providers, repository) : null; - switch (action) { - case RepositoryChangeAction.Archive: { - await repository.archive(); - break; - } - case RepositoryChangeAction.UnArchive: { - await repository.unarchive(); - break; - } - case RepositoryChangeAction.Privatize: { - await repository.update({ - visibility: GitHubRepositoryVisibility.Private, - }); - break; - } - default: { - return next(CreateError.InvalidParameters('Invalid action')); - } - } + await (action === ArchivalAction.Archive ? repository.archive() : repository.unarchive()); if (deployment?.features?.repositoryActions?.sendActionReceipt) { deployment.features.repositoryActions - .sendActionReceipt(providers, activeContext, repository, localAction, currentRepositoryState) + .sendActionReceipt( + providers, + activeContext, + repository, + action === ArchivalAction.Archive ? LocalApiRepoAction.Archive : LocalApiRepoAction.UnArchive, + currentRepositoryState + ) .then((ok) => {}) .catch(() => {}); } @@ -235,7 +200,7 @@ async function RepositoryStateChangeHandler( router.delete( '/', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: RequestWithRepo, res: Response, next: NextFunction) { + asyncHandler(async function (req: RequestWithRepo, res, next) { // NOTE: duplicated code from /routes/org/repos.ts const providers = getProviders(req); const { insights } = providers; @@ -285,7 +250,7 @@ router.delete( }); return res.json({ message: `You deleted: ${repository.full_name}`, - }) as unknown as void; + }); } catch (error) { insights?.trackException({ exception: error }); insights?.trackEvent({ @@ -330,7 +295,6 @@ router.delete( const { operations } = getProviders(req); const repositoryMetadataProvider = getRepositoryMetadataProvider(operations); const lockdownSystem = new NewRepositoryLockdownSystem({ - insights, operations, organization, repository, @@ -342,11 +306,11 @@ router.delete( ); return res.json({ message: `You deleted your repo, ${repository.full_name}.`, - }) as unknown as void; + }); }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { console.warn(req.baseUrl); return next(jsonError('no API or function available within this specific repo', 404)); }); diff --git a/api/client/organization/repoPermissions.ts b/api/client/organization/repoPermissions.ts index f5eefaba7..b479e8ab8 100644 --- a/api/client/organization/repoPermissions.ts +++ b/api/client/organization/repoPermissions.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware/jsonError'; @@ -19,7 +19,7 @@ const router: Router = Router(); router.get( '/', - asyncHandler(async (req: RequestWithRepo, res: Response, next: NextFunction) => { + asyncHandler(async (req: RequestWithRepo, res, next) => { const { repository, organization } = req; try { const teamPermissions = await repository.getTeamPermissions(); @@ -38,7 +38,7 @@ router.get( collaborators: collaborators.map((c) => c.asJson()), outsideCollaborators: outsideCollaborators.map((oc) => oc.asJson()), memberCollaborators: memberCollaborators.map((oc) => oc.asJson()), - }) as unknown as void; + }); } catch (error) { return next(jsonError(error)); } diff --git a/api/client/organization/repos.ts b/api/client/organization/repos.ts index 2a32f163b..499ec7ac5 100644 --- a/api/client/organization/repos.ts +++ b/api/client/organization/repos.ts @@ -3,25 +3,23 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware'; -import { CreateError, getProviders } from '../../../lib/transitional'; +import { getProviders } from '../../../transitional'; import { Repository } from '../../../business'; +import RouteRepo from './repo'; import JsonPager from '../jsonPager'; import { ReposAppRequest, IProviders } from '../../../interfaces'; -import { sortRepositoriesByNameCaseInsensitive } from '../../../lib/utils'; -import { apiMiddlewareRepositoriesToRepository } from '../../../middleware/business/repository'; - -import routeRepo from './repo'; +import { sortRepositoriesByNameCaseInsensitive } from '../../../utils'; const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const providers = getProviders(req); const pager = new JsonPager(req, res); @@ -238,10 +236,21 @@ export async function searchRepos( // --- End of search reimplementation --- -router.use('/:repoName', asyncHandler(apiMiddlewareRepositoriesToRepository), routeRepo); +router.use( + '/:repoName', + asyncHandler(async (req: ReposAppRequest, res, next) => { + const { organization } = req; + const { repoName } = req.params; + // does not confirm the name + (req as any).repository = organization.repository(repoName); + return next(); + }) +); + +router.use('/:repoName', RouteRepo); -router.use('*', (req, res: Response, next: NextFunction) => { - return next(CreateError.NotFound('no API or function available within org/repos endpoint')); +router.use('*', (req, res, next) => { + return next(jsonError('no API or function available within this repos endpoint', 404)); }); export default router; diff --git a/api/client/organization/team.ts b/api/client/organization/team.ts index 73e44e323..20d5925a3 100644 --- a/api/client/organization/team.ts +++ b/api/client/organization/team.ts @@ -3,46 +3,33 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { getContextualTeam } from '../../../middleware/github/teamPermissions'; import { jsonError } from '../../../middleware'; -import { getProviders } from '../../../lib/transitional'; +import { getProviders } from '../../../transitional'; import JsonPager from '../jsonPager'; import { getLinksLightCache } from '../leakyLocalCache'; import { equivalentLegacyPeopleSearch } from './people'; import { TeamRepositoryPermission, OrganizationMember, corporateLinkToJson } from '../../../business'; import { ReposAppRequest, TeamJsonFormat, NoCacheNoBackground, ICorporateLink } from '../../../interfaces'; -import { sortRepositoriesByNameCaseInsensitive } from '../../../lib/utils'; -import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; +import { sortRepositoriesByNameCaseInsensitive } from '../../../utils'; const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { - const providers = getProviders(req); + asyncHandler(async (req: ReposAppRequest, res, next) => { const team = getContextualTeam(req); - const format = TeamJsonFormat.Augmented; // includes corporateMetadata - let json = team.asJson(format); - const companySpecific = getCompanySpecificDeployment(); - if (companySpecific?.features?.augmentApiMetadata?.augmentTeamClientJson) { - json = await companySpecific.features.augmentApiMetadata.augmentTeamClientJson( - providers, - team, - json, - format - ); - } - return res.json(json) as unknown as void; + return res.json(team.asJson(TeamJsonFormat.Augmented /* includes corporateMetadata */)); }) ); router.get( '/repos', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { try { const forceRefresh = !!req.query.refresh; const pager = new JsonPager(req, res); @@ -69,7 +56,7 @@ router.get( router.get( '/members', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { try { const forceRefresh = !!req.query.refresh; const team = getContextualTeam(req); @@ -97,7 +84,7 @@ router.get( router.get( '/maintainers', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { operations } = getProviders(req); try { const forceRefresh = !!req.query.refresh; @@ -121,14 +108,14 @@ router.get( link: corporateLinkToJson(ls.get(Number(maintainer.id))), }; }) - ) as unknown as void; + ); } catch (error) { return next(error); } }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available for this specific team', 404)); }); diff --git a/api/client/organization/teams.ts b/api/client/organization/teams.ts index b69b82c84..eebde0d51 100644 --- a/api/client/organization/teams.ts +++ b/api/client/organization/teams.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Organization } from '../../../business/organization'; @@ -24,7 +24,7 @@ const leakyLocalCache = new LeakyLocalCache(); router.use( '/:teamSlug', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { organization } = req; const { teamSlug } = req.params; let team: Team = null; @@ -61,19 +61,15 @@ async function getTeamsForOrganization( router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { return await getClientApiOrganizationTeamsResponse(req, res, next); }) ); -export async function getClientApiOrganizationTeamsResponse( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export async function getClientApiOrganizationTeamsResponse(req: ReposAppRequest, res, next) { const organization = (req.organization || (req as any).aeOrganization) as Organization; if (!organization) { - return next(jsonError('No available organization', 400)); + return next(jsonError('No available organization'), 400); } const pager = new JsonPager(req, res); const q: string = (req.query.q ? (req.query.q as string) : null) || ''; @@ -105,7 +101,7 @@ export async function getClientApiOrganizationTeamsResponse( } } -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available within this team', 404)); }); diff --git a/api/client/organizations.ts b/api/client/organizations.ts index 2c26e165c..fac7fcafc 100644 --- a/api/client/organizations.ts +++ b/api/client/organizations.ts @@ -3,41 +3,41 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; -import throat from 'throat'; -import { getIsCorporateAdministrator, jsonError } from '../../middleware'; -import { CreateError, getProviders } from '../../lib/transitional'; +import memoryCache from 'memory-cache'; + +import { jsonError } from '../../middleware'; +import { CreateError, ErrorHelper, getProviders } from '../../transitional'; import { ReposAppRequest } from '../../interfaces'; import RouteOrganization from './organization'; -import { apiMiddlewareOrganizationsToOrganization } from '../../middleware/business/organization'; -import type { GitHubOrganizationResponseSanitized } from '../../business'; import { - OrganizationAnnotation, - OrganizationAnnotationProperty, - getOrganizationAnnotationRestrictedPropertyNames, -} from '../../business/entities/organizationAnnotation'; -import { getOrganizationProfileViaMemoryCache } from '../../middleware/github/ensureOrganizationProfile'; + IReposAppRequestWithOrganizationManagementType, + OrganizationManagementType, +} from '../../middleware/business/organization'; + +import { IGitHubOrganizationResponse } from '../../business'; +import { OrganizationAnnotation } from '../../entities/organizationAnnotation'; const router: Router = Router(); -export type OrganizationAnnotationPair = { - profile: GitHubOrganizationResponseSanitized; +type HighlightedOrganization = { + profile: IGitHubOrganizationResponse; annotations: OrganizationAnnotation; }; router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { operations } = getProviders(req); try { const orgs = operations.getOrganizations(); const dd = orgs.map((org) => { return org.asClientJson(); }); - return res.json(dd) as unknown as void; + return res.json(dd); } catch (error) { throw jsonError(error, 400); } @@ -46,86 +46,39 @@ router.get( router.get( '/annotations', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { - const providers = getProviders(req); - const { organizationAnnotationsProvider } = providers; - const projectionQuery = typeof req.query.projection === 'string' ? req.query.projection : undefined; - const isSystemAdministrator = await getIsCorporateAdministrator(req); - // governance filter: a specific value or unset cohort - const governance = - typeof req.query.governance === 'string' ? req.query.governance?.toLowerCase() : undefined; - const filterByGovernance = governance !== undefined; + asyncHandler(async (req: ReposAppRequest, res, next) => { + const { operations, organizationAnnotationsProvider } = getProviders(req); + const cacheTimeMs = 1000 * 60 * 60 * 24; try { - const highlights: OrganizationAnnotationPair[] = []; - let annotations = await organizationAnnotationsProvider.getAllAnnotations(); - if (filterByGovernance) { - annotations = annotations.filter((annotation) => { - const value = annotation?.getProperty(OrganizationAnnotationProperty.Governance); - return governance ? value === governance : !value; - }); - } - const getAnnotationProfile = async (annotation: OrganizationAnnotation) => { + const highlights: HighlightedOrganization[] = []; + const annotations = await organizationAnnotationsProvider.getAllAnnotations(); + for (const annotation of annotations) { try { - const profile = await getOrganizationProfileViaMemoryCache(providers, annotation.organizationId); + const key = `org:profile:${annotation.organizationId}`; + let profile = memoryCache.get(key) as IGitHubOrganizationResponse; + if (!profile) { + const details = await operations.getOrganizationProfileById(Number(annotation.organizationId)); + details.cost && delete details.cost; + details.headers && delete details.headers; + profile = details; + memoryCache.put(key, details, cacheTimeMs); + } + const scrubbedAnnotations = { ...annotation }; + delete scrubbedAnnotations.administratorNotes; + delete scrubbedAnnotations.history; highlights.push({ profile, - annotations: annotation, + annotations: scrubbedAnnotations as OrganizationAnnotation, }); } catch (error) { // we ignore any individual resolution error } - }; - const projections = projectionQuery?.split(','); - if (projections?.length > 0) { - const propertiesToRedact = getOrganizationAnnotationRestrictedPropertyNames(isSystemAdministrator); - if (projections.some((p) => propertiesToRedact.includes(p))) { - throw CreateError.InvalidParameters( - `One or more of the requested projections are not authorized for the current user` - ); - } - } - const parallelRequests = 6; - const throttle = throat(parallelRequests); - await Promise.all(annotations.map((annotation) => throttle(() => getAnnotationProfile(annotation)))); - if (projectionQuery) { - if (projections.length > 1 && !projections.includes('login')) { - throw CreateError.InvalidParameters('When using multiple projections, login must be included'); - } - let projected = highlights.map((highlight) => { - const profile = highlight.profile; - const annotations = highlight.annotations; - const result = {}; - for (const p of projections) { - let value = null; - if (profile[p]) { - value = result[p] = profile[p]; - } else if (annotations?.getProperty(p)) { - value = result[p] = annotations.getProperty(p); - } else if (annotations?.hasFeature(p)) { - value = result[p] = true; - } - if (projections.length === 1) { - return value; - } - } - return result; - }); - if (projections.length === 1 && projected.length >= 1 && typeof projected[0] === 'string') { - projected = projected.sort((a, b) => { - return a.localeCompare(b); - }); - } else if (projections.length > 1) { - projected = projected.sort((a, b) => { - return a['login'].localeCompare(b['login']); - }); - } - return res.json(projected) as unknown as void; } return res.json({ highlights: highlights.sort((a, b) => { return a.profile.login.localeCompare(b.profile.login); }), - }) as unknown as void; + }); } catch (error) { throw jsonError(error, 400); } @@ -134,7 +87,7 @@ router.get( router.get( '/list.txt', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { operations } = getProviders(req); try { const orgs = operations.getOrganizations(); @@ -149,10 +102,46 @@ router.get( }) ); -router.use('/:orgName', asyncHandler(apiMiddlewareOrganizationsToOrganization), RouteOrganization); +router.use( + '/:orgName', + asyncHandler(async (req: IReposAppRequestWithOrganizationManagementType, res, next) => { + const { operations } = getProviders(req); + const { orgName } = req.params; + req.organizationName = orgName; + try { + const org = operations.getOrganization(orgName); + if (org) { + req.organizationManagementType = OrganizationManagementType.Managed; + req.organization = org; + return next(); + } + } catch (orgNotFoundError) { + if (!ErrorHelper.IsNotFound(orgNotFoundError)) { + return next(orgNotFoundError); + } + } + try { + const org = operations.getUncontrolledOrganization(orgName); + const details = await org.getDetails(); + details.cost && delete details.cost; + details.headers && delete details.headers; + req.organizationProfile = details; + } catch (orgProfileError) { + if (ErrorHelper.IsNotFound(orgProfileError)) { + return next(CreateError.NotFound(`The organization ${orgName} does not exist`)); + } else { + return next(orgProfileError); + } + } + req.organizationManagementType = OrganizationManagementType.Unmanaged; + return next(); + }) +); + +router.use('/:orgName', RouteOrganization); -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { - return next(CreateError.NotFound('orgs API not found')); +router.use('*', (req: ReposAppRequest, res, next) => { + return next(jsonError('orgs API not found', 404)); }); export default router; diff --git a/api/client/people.ts b/api/client/people.ts index 41b30e959..c0a2fc12c 100644 --- a/api/client/people.ts +++ b/api/client/people.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { corporateLinkToJson } from '../../business'; import { jsonError } from '../../middleware'; -import { type GitHubSimpleAccount, type ICorporateLink, ReposAppRequest } from '../../interfaces'; +import { ICorporateLink, ReposAppRequest } from '../../interfaces'; import JsonPager from './jsonPager'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import { getPerson as routeGetPerson } from './person'; +import RouteGetPerson from './person'; import { equivalentLegacyPeopleSearch } from './peopleSearch'; const router: Router = Router(); @@ -20,28 +20,34 @@ const router: Router = Router(); const deployment = getCompanySpecificDeployment(); deployment?.routes?.api?.people && deployment.routes.api.people(router); +interface ISimpleAccount { + login: string; + avatar_url: string; + id: number; +} + export interface ICrossOrganizationMemberResponse { - account: GitHubSimpleAccount; + account: ISimpleAccount; link?: ICorporateLink; organizations: string[]; } export interface ICrossOrganizationSearchedMember { id: number; - account: GitHubSimpleAccount; + account: ISimpleAccount; link?: ICorporateLink; orgs: IOrganizationMembershipAccount; } interface IOrganizationMembershipAccount { - [id: string]: GitHubSimpleAccount; + [id: string]: ISimpleAccount; } -router.get('/:login', routeGetPerson); +router.get('/:login', RouteGetPerson); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const pager = new JsonPager(req, res); try { const searcher = await equivalentLegacyPeopleSearch(req); @@ -67,7 +73,7 @@ router.get( }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available within this cross-organization people list', 404)); }); diff --git a/api/client/peopleSearch.ts b/api/client/peopleSearch.ts index 82ae5c27f..1c55e6d16 100644 --- a/api/client/peopleSearch.ts +++ b/api/client/peopleSearch.ts @@ -5,7 +5,7 @@ import { Organization, MemberSearch, ICrossOrganizationMembersResult, Operations } from '../../business'; import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import LeakyLocalCache, { getLinksLightCache } from './leakyLocalCache'; // BAD PRACTICE: leaky local cache diff --git a/api/client/person.ts b/api/client/person.ts index 61369456a..913658945 100644 --- a/api/client/person.ts +++ b/api/client/person.ts @@ -4,15 +4,13 @@ // import asyncHandler from 'express-async-handler'; -import { NextFunction, Response } from 'express'; - import { ReposAppRequest, AccountJsonFormat } from '../../interfaces'; import { IGraphEntry } from '../../lib/graphProvider'; import { jsonError } from '../../middleware'; -import { CreateError, ErrorHelper, getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; -const getPerson = asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { +export default asyncHandler(async (req: ReposAppRequest, res, next) => { const providers = getProviders(req); const { operations, queryCache, graphProvider } = providers; const login = req.params.login as string; @@ -72,14 +70,8 @@ const getPerson = asyncHandler(async (req: ReposAppRequest, res: Response, next: json, { corporateEntry } ); - return res.json(combined) as unknown as void; + return res.json(combined); } catch (error) { - return next( - ErrorHelper.IsNotFound(error) - ? error - : CreateError.InvalidParameters(`Invalid issue retrieving user ${login}: ${error.message}`) - ); + return next(jsonError(`login ${login} error: ${error}`, 500)); } }); - -export { getPerson }; diff --git a/api/client/repos.ts b/api/client/repos.ts index ca1675f2a..ae426e7df 100644 --- a/api/client/repos.ts +++ b/api/client/repos.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Repository } from '../../business'; import { ReposAppRequest } from '../../interfaces'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import JsonPager from './jsonPager'; import { RepositorySearchSortOrder, searchRepos } from './organization/repos'; @@ -17,7 +17,7 @@ const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const providers = getProviders(req); const pager = new JsonPager(req, res); const searchOptions = { @@ -39,7 +39,7 @@ router.get( }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available within this cross-organization repps list', 404)); }); diff --git a/api/client/session.ts b/api/client/session.ts index 35f98dd2a..e0b128e99 100644 --- a/api/client/session.ts +++ b/api/client/session.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import { jsonError } from '../../middleware/jsonError'; import { IAppSession, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; const router: Router = Router(); @@ -42,7 +42,7 @@ router.post('/github', (req: ReposAppRequest, res) => { res.end(); }); -router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use('*', (req: ReposAppRequest, res, next) => { return next(jsonError('API or route not found', 404)); }); diff --git a/api/client/teams.ts b/api/client/teams.ts index 089fa240b..b2c863291 100644 --- a/api/client/teams.ts +++ b/api/client/teams.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Operations, Team } from '../../business'; @@ -13,7 +13,7 @@ import { TeamJsonFormat, } from '../../interfaces'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import JsonPager from './jsonPager'; const router: Router = Router(); @@ -40,7 +40,7 @@ async function getCrossOrganizationTeams(operations: Operations): Promise { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { operations } = getProviders(req); const pager = new JsonPager(req, res); const q: string = (req.query.q ? (req.query.q as string) : null) || ''; @@ -71,7 +71,7 @@ router.get( }) ); -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('no API or function available within this cross-organization teams list', 404)); }); diff --git a/api/client/users.ts b/api/client/users.ts deleted file mode 100644 index 940789452..000000000 --- a/api/client/users.ts +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { NextFunction, Response, Router } from 'express'; -import asyncHandler from 'express-async-handler'; - -import { ReposAppRequest, AccountJsonFormat } from '../../interfaces'; -import { CreateError, getProviders } from '../../lib/transitional'; - -const router: Router = Router(); - -router.get( - '/:login', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { - const { operations } = getProviders(req); - const login = req.params.login as string; - try { - if (!login) { - throw CreateError.ParameterRequired('login'); - } - const accountInfo = await operations.getAccountByUsername(login); - return res.json(accountInfo.asJson(AccountJsonFormat.GitHubExtended)) as any as void; - } catch (error) { - return next(error); - } - }) -); - -router.use('*', (req, res: Response, next: NextFunction) => { - return next(CreateError.NotFound('/users: no API found')); -}); - -export default router; diff --git a/api/createRepo.ts b/api/createRepo.ts index 585949c25..c986bc293 100644 --- a/api/createRepo.ts +++ b/api/createRepo.ts @@ -17,9 +17,9 @@ import { ICustomizedNewRepositoryLogic, INewRepositoryContext, splitSemiColonCommas, -} from '../lib/transitional'; +} from '../transitional'; import { Organization, Repository } from '../business'; -import { RepositoryMetadataEntity } from '../business/entities/repositoryMetadata/repositoryMetadata'; +import { RepositoryMetadataEntity } from '../entities/repositoryMetadata/repositoryMetadata'; import RenderHtmlMail from '../lib/emailRender'; import { @@ -29,7 +29,7 @@ import { } from '../routes/org/repoWorkflowEngine'; import { IMailProvider } from '../lib/mailProvider'; import { IndividualContext } from '../business/user'; -import NewRepositoryLockdownSystem from '../business/features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../features/newRepositories/newRepositoryLockdown'; import { ICreateRepositoryResult, ICorporateLink, @@ -176,7 +176,7 @@ export async function CreateRepository( try { createResult = await organization.createRepository(parameters.name, parameters); if (createResult && createResult.repository) { - repository = organization.repositoryFromEntity(createResult.repository.getEntity()); + repository = organization.repositoryFromEntity(createResult.repository); } } catch (error) { providers.insights?.trackEvent({ @@ -624,22 +624,14 @@ async function sendEmail( req.insights.trackException({ exception: renderError, properties: { - correlationId, - existingRepoId, - orgName: repository.organization.name, - repoName: repository.name, - results: repoCreateResults, + content: contentOptions, eventName: 'ApiRepoCreateMailRenderFailure', }, }); throw renderError; } const customData = { - correlationId, - existingRepoId, - orgName: repository.organization.name, - repoName: repository.name, - results: repoCreateResults, + content: contentOptions, receipt: null, eventName: undefined, }; diff --git a/api/extension.ts b/api/extension.ts index 4e9e2f1b0..c339ab89a 100644 --- a/api/extension.ts +++ b/api/extension.ts @@ -3,25 +3,25 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; import { setIdentity } from '../middleware/business/authentication'; -import { AddLinkToRequest } from '../middleware/business/links'; +import { AddLinkToRequest } from '../middleware/links'; import { jsonError } from '../middleware'; import { apiContextMiddleware } from '../middleware/business/setContext'; -import { ILocalExtensionKeyProvider } from '../business/entities/localExtensionKey'; -import { LocalExtensionKey } from '../business/entities/localExtensionKey/localExtensionKey'; +import { ILocalExtensionKeyProvider } from '../entities/localExtensionKey'; +import { LocalExtensionKey } from '../entities/localExtensionKey/localExtensionKey'; import { IApiRequest } from '../middleware/apiReposAuth'; -import { PersonalAccessToken } from '../business/entities/token/token'; +import { PersonalAccessToken } from '../entities/token/token'; const thisApiScopeName = 'extension'; -type ExtensionResponse = Response & { +interface IExtensionResponse extends Response { localKey?: any; -}; +} interface IConnectionInformation { link?: any; @@ -29,7 +29,7 @@ interface IConnectionInformation { auth?: any; } -router.use(function (req: IApiRequest, res: Response, next: NextFunction) { +router.use(function (req: IApiRequest, res, next) { const token = req.apiKeyToken; if (!token.scopes) { return next(jsonError('The key is not authorized for specific APIs', 403)); @@ -40,7 +40,7 @@ router.use(function (req: IApiRequest, res: Response, next: NextFunction) { return next(); }); -function overwriteUserContext(req: IApiRequest, res: Response, next: NextFunction) { +function overwriteUserContext(req: IApiRequest, res, next) { const token = req.apiKeyToken; const corporateId = token.corporateId; if (!corporateId) { @@ -121,7 +121,7 @@ router.get('/', (req: IApiRequest, res) => { router.get( '/metadata', asyncHandler(getLocalEncryptionKeyMiddleware), - (req: IApiRequest, res: ExtensionResponse) => { + (req: IApiRequest, res: IExtensionResponse) => { const apiContext = req.apiContext; const localKey = res.localKey; @@ -186,11 +186,7 @@ function getSanitizedOrganizations(operations) { return value; } -async function getLocalEncryptionKeyMiddleware( - req: IApiRequest, - res: ExtensionResponse, - next: NextFunction -): Promise { +async function getLocalEncryptionKeyMiddleware(req: IApiRequest, res, next): Promise { const providers = getProviders(req); const localExtensionKeyProvider = providers.localExtensionKeyProvider; const apiKeyToken = req.apiKeyToken; @@ -254,7 +250,7 @@ async function getOrCreateLocalEncryptionKey( return await createLocalEncryptionKey(insights, localExtensionKeyProvider, corporateId); } -router.use('*', (req, res: Response, next: NextFunction) => { +router.use('*', (req, res, next) => { return next(jsonError('API not found', 404)); }); diff --git a/api/index.ts b/api/index.ts index a4f5c58ba..a26d7f502 100644 --- a/api/index.ts +++ b/api/index.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import cors from 'cors'; -import { CreateError, getProviders } from '../lib/transitional'; +import { CreateError, getProviders } from '../transitional'; import { jsonError } from '../middleware'; import { IApiRequest } from '../middleware/apiReposAuth'; @@ -17,9 +17,8 @@ import { IApiRequest } from '../middleware/apiReposAuth'; import apiExtension from './extension'; import apiWebhook from './webhook'; import apiPeople from './people'; -import apiNews from './client/news'; -import aadApiAuthentication, { requireAadApiAuthorizedScope } from '../middleware/apiAad'; +import AadApiAuthentication, { requireAadApiAuthorizedScope } from '../middleware/apiAad'; import AzureDevOpsAuthenticationMiddleware from '../middleware/apiVstsAuth'; import ReposApiAuthentication from '../middleware/apiReposAuth'; import { CreateRepository, CreateRepositoryEntrypoint } from './createRepo'; @@ -37,7 +36,7 @@ function isClientRoute(req: ReposAppRequest) { router.use('/webhook', apiWebhook); -router.use((req: IApiRequest, res: Response, next: NextFunction) => { +router.use((req: IApiRequest, res, next) => { if (isClientRoute(req)) { // The frontend client routes are hooked into Express after // the session middleware. The client route does not require @@ -68,16 +67,15 @@ router.use((req: IApiRequest, res: Response, next: NextFunction) => { // AUTHENTICATION: VSTS or repos //----------------------------------------------------------------------------- const multipleProviders = supportMultipleAuthProviders([ - aadApiAuthentication, + AadApiAuthentication, ReposApiAuthentication, AzureDevOpsAuthenticationMiddleware, ]); -const aadAndCustomProviders = supportMultipleAuthProviders([aadApiAuthentication, ReposApiAuthentication]); +const aadAndCustomProviders = supportMultipleAuthProviders([AadApiAuthentication, ReposApiAuthentication]); router.use('/people', cors(), multipleProviders, apiPeople); router.use('/extension', cors(), multipleProviders, apiExtension); -router.use('/news', cors(), aadApiAuthentication, requireAadApiAuthorizedScope('news'), apiNews); //----------------------------------------------------------------------------- // AUTHENTICATION: AAD or repos (specific to this app) @@ -92,8 +90,8 @@ router.post('/:org/repos', aadAndCustomProviders); router.post( '/:org/repos', - requireAadApiAuthorizedScope(['repo/create', 'createRepo']), - function (req: IApiRequest, res: Response, next: NextFunction) { + requireAadApiAuthorizedScope('createRepo'), + function (req: IApiRequest, res, next) { const orgName = req.params.org; if (!req.apiKeyToken.organizationScopes) { return next(jsonError('There is a problem with the key configuration (no organization scopes)', 412)); @@ -118,7 +116,7 @@ router.post( router.post( '/:org/repos', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const providers = getProviders(req); const organization = req.organization; const convergedObject = Object.assign({}, req.headers); @@ -176,7 +174,7 @@ router.post( response: JSON.stringify(repoCreateResponse), }, }); - return res.json(repoCreateResponse) as unknown as void; + return res.json(repoCreateResponse); } catch (error) { const data = { ...convergedObject }; data.error = error.message; @@ -187,7 +185,7 @@ router.post( }) ); -router.use((req: IApiRequest, res: Response, next: NextFunction) => { +router.use((req: IApiRequest, res, next) => { if (isClientRoute(req)) { // The frontend client routes are hooked into Express after // the session middleware. The client route does not require diff --git a/api/jsonErrorHandler.ts b/api/jsonErrorHandler.ts index 9fa874805..50915b863 100644 --- a/api/jsonErrorHandler.ts +++ b/api/jsonErrorHandler.ts @@ -3,10 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; -export default function JsonErrorHandler(err, req, res: Response, next: NextFunction) { +export default function JsonErrorHandler(err, req, res, next) { if (err && err['json']) { // jsonError objects should bubble up like before return next(err); diff --git a/api/people/index.ts b/api/people/index.ts index 2a02f017e..a724df813 100644 --- a/api/people/index.ts +++ b/api/people/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import { json404 } from '../../middleware/jsonError'; diff --git a/api/people/link.ts b/api/people/link.ts index 3202e00f3..d92825a8a 100644 --- a/api/people/link.ts +++ b/api/people/link.ts @@ -3,9 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { jsonError } from '../../middleware'; import { IApiRequest } from '../../middleware/apiReposAuth'; import { ICorporateLink, LinkOperationSource } from '../../interfaces'; @@ -17,7 +15,7 @@ const supportedApiVersions = new Set([ '2019-10-01', ]); -export default async function postLinkApi(req: IApiRequest, res: Response, next: NextFunction) { +export default async function postLinkApi(req: IApiRequest, res, next) { const providers = getProviders(req); const { operations } = providers; const token = req.apiKeyToken; diff --git a/api/people/links.ts b/api/people/links.ts index 3ea4caa59..5332bab1a 100644 --- a/api/people/links.ts +++ b/api/people/links.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../middleware'; import { ICrossOrganizationMembersResult, MemberSearch, Operations } from '../../business'; -import { ICorporateLink, VoidedExpressRoute } from '../../interfaces'; +import { ICorporateLink } from '../../interfaces'; import { IApiRequest } from '../../middleware/apiReposAuth'; import postLinkApi from './link'; -import { CreateError, ErrorHelper, getProviders } from '../../lib/transitional'; -import { wrapError } from '../../lib/utils'; +import { ErrorHelper, getProviders } from '../../transitional'; +import { wrapError } from '../../utils'; const router: Router = Router(); @@ -26,7 +26,7 @@ const extendedLinkApiVersions = [ '2019-02-01', ]; -router.use(function (req: IApiRequest, res: Response, next: NextFunction) { +router.use(function (req: IApiRequest, res, next) { const token = req.apiKeyToken; if (!token.scopes) { return next(jsonError('The key is not authorized for specific APIs', 401)); @@ -37,11 +37,11 @@ router.use(function (req: IApiRequest, res: Response, next: NextFunction) { return next(); }); -router.post('/', asyncHandler(postLinkApi as VoidedExpressRoute)); +router.post('/', asyncHandler(postLinkApi)); router.get( '/', - asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: IApiRequest, res, next) => { const { operations } = getProviders(req); const skipOrganizations = req.query.showOrganizations !== undefined && !!req.query.showOrganizations; const showTimestamps = req.query.showTimestamps !== undefined && req.query.showTimestamps === 'true'; @@ -54,11 +54,9 @@ router.get( router.get( '/:linkid', - asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: IApiRequest, res, next) => { if (unsupportedApiVersions.includes(req.apiVersion)) { - return next( - CreateError.InvalidParameters('This API is not supported by the API version you are using.') - ); + return next(jsonError('This API is not supported by the API version you are using.', 400)); } const linkid = req.params.linkid.toLowerCase(); const { operations } = getProviders(req); @@ -83,33 +81,31 @@ router.get( ); } catch (error) { if (ErrorHelper.IsNotFound(error)) { - return next(CreateError.NotFound('Could not find the link')); + return next(jsonError('Could not find the link', 404)); } else { - return next(CreateError.ServerError(error)); + return next(jsonError(error, 500)); } } req.insights.trackMetric({ name: 'ApiRequestLinkByLinkId', value: 1 }); - return res.json(entry) as unknown as void; + return res.json(entry); } const results = await getAllUsers(req.apiVersion, operations, skipOrganizations, showTimestamps, true); for (let i = 0; i < results.length; i++) { const entry = results[i]; if (entry && entry.id === linkid) { req.insights.trackMetric({ name: 'ApiRequestLinkByLinkId', value: 1 }); - return res.json(entry) as unknown as void; + return res.json(entry); } } - return next(CreateError.NotFound('Could not find the link')); + return next(jsonError('Could not find the link', 404)); }) ); router.get( '/github/:username', - asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: IApiRequest, res, next) => { if (unsupportedApiVersions.includes(req.apiVersion)) { - return next( - CreateError.InvalidParameters('This API is not supported by the API version you are using.') - ); + return next(jsonError('This API is not supported by the API version you are using.', 400)); } const username = req.params.username.toLowerCase(); const { operations } = getProviders(req); @@ -122,9 +118,9 @@ router.get( account = await operations.getAccountByUsername(username); } catch (getAccountError) { if (ErrorHelper.IsNotFound(account)) { - return next(CreateError.NotFound('Could not find a link for the user')); + return next(jsonError('Could not find a link for the user', 404)); } - return next(CreateError.ServerError(getAccountError)); + return next(jsonError(getAccountError, 500)); } try { const entry = await getByThirdPartyId( @@ -135,7 +131,7 @@ router.get( showTimestamps ); req.insights.trackMetric({ name: 'ApiRequestLinkByGitHubUsername', value: 1 }); - return res.json(entry) as unknown as void; + return res.json(entry); } catch (entryError) { return next(jsonError(entryError, ErrorHelper.GetStatus(entryError) || 500)); } @@ -145,16 +141,16 @@ router.get( const entry = results[i]; if (entry && entry.github && entry.github.login.toLowerCase() === username) { req.insights.trackMetric({ name: 'ApiRequestLinkByGitHubUsername', value: 1 }); - return res.json(entry) as unknown as void; + return res.json(entry); } } - return next(CreateError.NotFound('Could not find a link for the user')); + return next(jsonError('Could not find a link for the user', 404)); }) ); router.get( '/aad/userPrincipalName/:upn', - asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: IApiRequest, res, next) => { const upn = req.params.upn; const { operations } = getProviders(req); const skipOrganizations = req.query.showOrganizations !== undefined && !!req.query.showOrganizations; @@ -189,7 +185,7 @@ router.get( userPrincipalName: upn, }, }); - return res.json(r) as unknown as void; + return res.json(r); } const results = await getAllUsers(req.apiVersion, operations, skipOrganizations, showTimestamps); const r = []; @@ -207,20 +203,18 @@ router.get( }, }); if (r.length === 0) { - return next(CreateError.NotFound('Could not find a link for the user')); + return next(jsonError('Could not find a link for the user', 404)); } req.insights.trackMetric({ name: 'ApiRequestLinkByAadUpn', value: 1 }); - return res.json(r) as unknown as void; + return res.json(r); }) ); router.get( '/aad/:id', - asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: IApiRequest, res, next) => { if (req.apiVersion == '2016-12-01') { - return next( - CreateError.InvalidParameters('This API is not supported by the API version you are using.') - ); + return next(jsonError('This API is not supported by the API version you are using.', 400)); } const id = req.params.id; const skipOrganizations = req.query.showOrganizations !== undefined && !!req.query.showOrganizations; @@ -250,7 +244,7 @@ router.get( } } req.insights.trackMetric({ name: 'ApiRequestLinkByAadId', value: 1 }); - return res.json(r) as unknown as void; + return res.json(r); } const results = await getAllUsers(req.apiVersion, operations, skipOrganizations, showTimestamps); const r = []; @@ -264,7 +258,7 @@ router.get( return next(jsonError('Could not find a link for the user', 404)); } req.insights.trackMetric({ name: 'ApiRequestLinkByAadId', value: 1 }); - return res.json(r) as unknown as void; + return res.json(r); }) ); @@ -277,6 +271,7 @@ async function getByThirdPartyId( showLinkIds?: boolean ): Promise { const providers = operations.providers; + const { graphProvider } = providers; let link: ICorporateLink = null; try { link = await providers.linkProvider.getByThirdPartyId(thirdPartyId); @@ -351,7 +346,7 @@ async function getByThirdPartyId( } async function getAllUsers( - apiVersion: string, + apiVersion, operations: Operations, skipOrganizations: boolean, showTimestamps: boolean, diff --git a/api/people/unlink.ts b/api/people/unlink.ts index dbaa25e72..3a7aea7d5 100644 --- a/api/people/unlink.ts +++ b/api/people/unlink.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { ICorporateLink, UnlinkPurpose } from '../../interfaces'; import { jsonError } from '../../middleware'; import { IApiRequest } from '../../middleware/apiReposAuth'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; const router: Router = Router(); @@ -17,7 +17,7 @@ interface ILinksApiRequestWithUnlink extends IApiRequest { unlink?: ICorporateLink; } -router.use(function (req: ILinksApiRequestWithUnlink, res: Response, next: NextFunction) { +router.use(function (req: ILinksApiRequestWithUnlink, res, next) { const token = req.apiKeyToken; if (!token.scopes) { return next(jsonError('The key is not authorized for specific APIs', 401)); @@ -30,7 +30,7 @@ router.use(function (req: ILinksApiRequestWithUnlink, res: Response, next: NextF router.use( '/github/id/:id', - asyncHandler(async (req: ILinksApiRequestWithUnlink, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILinksApiRequestWithUnlink, res, next) => { const { linkProvider } = getProviders(req); const id = req.params.id; try { @@ -46,11 +46,11 @@ router.use( }) ); -router.use('*', (req: ILinksApiRequestWithUnlink, res: Response, next: NextFunction) => { +router.use('*', (req: ILinksApiRequestWithUnlink, res, next) => { return next(req.unlink ? undefined : jsonError('No link available for operation', 404)); }); -router.delete('*', (req: ILinksApiRequestWithUnlink, res: Response, next: NextFunction) => { +router.delete('*', (req: ILinksApiRequestWithUnlink, res, next) => { const { config, operations } = getProviders(req); const link = req.unlink; let purpose: UnlinkPurpose = null; diff --git a/api/webhook.ts b/api/webhook.ts index c7531a8ce..a41104162 100644 --- a/api/webhook.ts +++ b/api/webhook.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import moment from 'moment'; import { ReposAppRequest } from '../interfaces'; import { jsonError } from '../middleware'; -import { getProviders, isWebhookIngestionEndpointEnabled } from '../lib/transitional'; +import { getProviders, isWebhookIngestionEndpointEnabled } from '../transitional'; -import OrganizationWebhookProcessor from '../business/webhooks/organizationProcessor'; +import OrganizationWebhookProcessor from '../webhooks/organizationProcessor'; const router: Router = Router(); @@ -21,7 +21,7 @@ interface IRequestWithRaw extends ReposAppRequest { } router.use( - asyncHandler(async (req: IRequestWithRaw, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithRaw, res, next) => { if (!isWebhookIngestionEndpointEnabled(req)) { return next( jsonError( diff --git a/app.ts b/app.ts new file mode 100644 index 000000000..6bcc8ce8c --- /dev/null +++ b/app.ts @@ -0,0 +1,156 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import express from 'express'; +import { hostname } from 'os'; + +import { IReposApplication, IReposJob, IReposJobOptions, IReposJobResult } from './interfaces'; + +import configResolver from './lib/config'; +import initialize from './middleware/initialize'; +import { quitInTenSeconds } from './utils'; + +const app = express() as any as IReposApplication; + +import Debug from 'debug'; +Debug.debug('startup')('starting...'); + +app.initializeApplication = initialize.bind(undefined, app, express, __dirname); + +app.initializeJob = function initializeJob(config, configurationError) { + if (config) { + config.isJobInternal = true; + config.skipModules = new Set(['web']); + } else { + console.warn(`Configuration did not resolve successfully`, configurationError); + } + return initialize(app, express, __dirname, config, configurationError); +}; + +async function startup(startupApplication: boolean) { + let painlessConfigResolver = null; + try { + painlessConfigResolver = configResolver(); + } catch (error) { + console.warn('Painless config resolver initialization error:'); + console.error(error); + throw error; + } + let config: any = null; + let configurationError: Error = null; + try { + config = await painlessConfigResolver.resolve(); + } catch (error) { + configurationError = error; + } + + try { + if (startupApplication) { + await app.initializeApplication(config, configurationError); + } else { + await app.initializeJob(config, configurationError); + } + } catch (startupError) { + console.error(`Startup error: ${startupError}`); + process.exit(1); // throw startupError; + } + + return app; +} + +app.startupApplication = startup.bind(null, true); +app.startupJob = startup.bind(null, false); +app.runJob = async function ( + job: (job: IReposJob) => Promise, + options?: IReposJobOptions +): Promise { + options = options || {}; + // TODO: automatically track elapsed job time + const started = new Date(); + if (options.timeoutMinutes) { + setTimeout(() => { + // TODO: insights metric and event, if a prefix exists + console.log(`Kill bit at ${options.timeoutMinutes}m`); + process.exit(1); + }, 1000 * 60 * options.timeoutMinutes); + } + if (options.defaultDebugOutput && !process.env.DEBUG) { + process.env.DEBUG = options.defaultDebugOutput; + } + app.isBackgroundJob = true; + if (options.enableAllGitHubApps) { + app.enableAllGitHubApps = true; + } + try { + await app.startupJob(); + } catch (startupError) { + console.error(`Job startup error before runJob: ${startupError}`); + quitInTenSeconds(false); + return app; + } + if (options.insightsPrefix && app.providers.insights) { + try { + app.providers.insights.trackEvent({ + name: `${options.insightsPrefix}Started`, + properties: { + hostname: hostname(), + }, + }); + } catch (ignoreInsightsError) { + console.error(`insights error: ${ignoreInsightsError}`); + } + } + const jobObject = { + app, + providers: app.providers, + started, + parameters: options && options.parameters ? options.parameters : {}, + args: process.argv.length > 2 ? process.argv.slice(2) : [], + }; + try { + const result = await job.call(null, jobObject); + if (result && result.successProperties && app.providers.insights && options.insightsPrefix) { + try { + app.providers.insights.trackEvent({ + name: `${options.insightsPrefix}Success`, + properties: Object.assign( + { + hostname: hostname(), + }, + result.successProperties + ), + }); + } catch (ignoreInsightsError) { + console.error(`insights error: ${ignoreInsightsError}`); + } + } + } catch (jobError) { + console.error(`The job failed: ${jobError}`); + // by default, let's not show the whole inner error + const simpleError = { ...jobError }; + simpleError?.cause && delete simpleError.cause; + console.dir(simpleError); + quitInTenSeconds(false); + if (options.insightsPrefix && app.providers.insights) { + try { + app.providers.insights.trackException({ + exception: jobError, + properties: { + name: `${options.insightsPrefix}Failure`, + }, + }); + } catch (ignoreInsightsError) { + console.error(`insights error: ${ignoreInsightsError}`); + } + } + return app; + } + // CONSIDER: insights metric for job time + console.log('The job was successful.'); + quitInTenSeconds(true); + return app; +}; + +export default app; diff --git a/bin/www.ts b/bin/www.ts index af8fe7d7b..8fbd05f5c 100644 --- a/bin/www.ts +++ b/bin/www.ts @@ -9,15 +9,13 @@ import Debug from 'debug'; const debug = Debug.debug('g:server'); const debugInitialization = Debug.debug('startup'); +import app from '../app'; + import http from 'http'; import https from 'https'; import fs from 'fs'; import path from 'path'; -import { createExpressApplication } from '..'; - -const app = createExpressApplication(); - function normalizePort(val) { const port = parseInt(val, 10); diff --git a/business/account.ts b/business/account.ts index 990c52a49..473eb8997 100644 --- a/business/account.ts +++ b/business/account.ts @@ -7,18 +7,18 @@ import _ from 'lodash'; import * as common from './common'; -import { wrapError } from '../lib/utils'; +import { wrapError } from '../utils'; import { corporateLinkToJson } from './corporateLink'; import { Organization } from './organization'; -import { AppPurpose } from '../lib/github/appPurposes'; +import { AppPurpose } from './githubApps'; import { ILinkProvider } from '../lib/linkProviders'; -import { CacheDefault, Operations, getMaxAgeSeconds } from '.'; +import { CacheDefault, getMaxAgeSeconds } from '.'; import { AccountJsonFormat, CoreCapability, ICacheOptions, ICorporateLink, - GetAuthorizationHeader, + IGetAuthorizationHeader, IGitHubAccountDetails, IOperationsInstance, IOperationsLinks, @@ -29,7 +29,7 @@ import { throwIfNotCapable, throwIfNotGitHubCapable, } from '../interfaces'; -import { ErrorHelper } from '../lib/transitional'; +import { ErrorHelper } from '../transitional'; interface IRemoveOrganizationMembershipsResult { error?: IReposError; @@ -46,7 +46,7 @@ const secondaryAccountProperties = []; export class Account { private _operations: IOperationsInstance; - private _getAuthorizationHeader: GetAuthorizationHeader; + private _getAuthorizationHeader: IGetAuthorizationHeader; private _link: ICorporateLink; private _id: number; @@ -70,12 +70,6 @@ export class Account { case AccountJsonFormat.GitHub: { return basic; } - case AccountJsonFormat.GitHubExtended: { - const cloneEntity = Object.assign({}, this._originalEntity || {}); - delete (cloneEntity as any).cost; - delete (cloneEntity as any).headers; - return cloneEntity; - } case AccountJsonFormat.GitHubDetailedWithLink: { const cloneEntity = Object.assign({}, this._originalEntity || {}); delete (cloneEntity as any).cost; @@ -137,7 +131,7 @@ export class Account { return this._originalEntity ? this._originalEntity.name : undefined; } - constructor(entity, operations: IOperationsInstance, getAuthorizationHeader: GetAuthorizationHeader) { + constructor(entity, operations: IOperationsInstance, getAuthorizationHeader: IGetAuthorizationHeader) { common.assignKnownFieldsPrefixed( this, entity, @@ -150,7 +144,7 @@ export class Account { this._getAuthorizationHeader = getAuthorizationHeader; } - overrideAuthorization(getAuthorizationHeader: GetAuthorizationHeader) { + overrideAuthorization(getAuthorizationHeader: IGetAuthorizationHeader) { this._getAuthorizationHeader = getAuthorizationHeader; } @@ -358,10 +352,8 @@ export class Account { cacheOptions.backgroundRefresh = options.backgroundRefresh; } try { - const ops = operations as Operations; const entity = (await operations.github.request( - ops.getPublicAuthorizationToken(), - // this.authorize(AppPurpose.Data), + this.authorize(AppPurpose.Data), 'GET /user/:id', parameters, cacheOptions @@ -420,7 +412,7 @@ export class Account { }; const eventData = { github: { - id, + id: id, login: this._login, }, aad: aadIdentity, @@ -486,11 +478,7 @@ export class Account { return currentOrganizationMemberships; } - async removeCollaboratorPermissions( - onlyOneHundred?: boolean - ): Promise { - // NOTE: this at least temporarily adds the ability to punt 100 - // but not all grants; probably should use options eventually vs bool param. + async removeCollaboratorPermissions(): Promise { const history = []; const error: IReposError = null; const operations = throwIfNotGitHubCapable(this._operations); @@ -504,18 +492,13 @@ export class Account { await this.getDetails(); } const collaborativeRepos = await queryCache.userCollaboratorRepositories(this.id.toString()); - let i = 0; for (const entry of collaborativeRepos) { - if (onlyOneHundred && i >= 100) { - break; - } const { repository } = entry; try { await repository.getDetails(); if (repository.archived) { - history.push(`FYI: cannot alter prior grant to archived repository ${repository.full_name}`); + history.push(`FYI: previous access to an archived repository ${repository.full_name}`); } else { - ++i; await repository.removeCollaborator(this.login); history.push(`Removed ${this.login} as a Collaborator from the repository ${repository.full_name}`); } @@ -573,8 +556,11 @@ export class Account { return { history, error }; } - private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/application.ts b/business/application.ts index de134a1dc..40e0b602a 100644 --- a/business/application.ts +++ b/business/application.ts @@ -3,15 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { OrganizationSetting } from './entities/organizationSettings/organizationSetting'; import { IOperationsGitHubRestLibrary, IOperationsDefaultCacheTimes, - GetAuthorizationHeader, + IGetAuthorizationHeader, IGitHubAppInstallation, ICacheOptions, } from '../interfaces'; -import { wrapError } from '../lib/utils'; +import { wrapError } from '../utils'; const primaryInstallationProperties = [ 'id', @@ -23,34 +22,13 @@ const primaryInstallationProperties = [ 'events', ]; -export type GitHubAppDefinition = { - id: number; - slug: string; - friendlyName: string; -}; - -export function isInstallationConfigured( - settings: OrganizationSetting, - installation: IGitHubAppInstallation -): boolean { - if (!settings || !settings.installations) { - return false; - } - for (const install of settings.installations) { - if (install.installationId === installation.id) { - return true; - } - } - return false; -} - export default class GitHubApplication { constructor( private operations: IOperationsGitHubRestLibrary & IOperationsDefaultCacheTimes, public id: number, public slug: string, public friendlyName: string, - private getAuthorizationHeader: GetAuthorizationHeader + private getAuthorizationHeader: IGetAuthorizationHeader ) {} static PrimaryInstallationProperties = primaryInstallationProperties; @@ -74,14 +52,6 @@ export default class GitHubApplication { return invalid; } - asClientJson(): GitHubAppDefinition { - return { - id: this.id, - slug: this.slug, - friendlyName: this.friendlyName, - }; - } - async getInstallation(installationId: number, options?: ICacheOptions): Promise { const operations = this.operations; const parameters = { @@ -115,7 +85,7 @@ export default class GitHubApplication { async getInstallations(options?: ICacheOptions): Promise { options = options || {}; const operations = this.operations; - const getAuthorizationHeader = this.getAuthorizationHeader.bind(this) as GetAuthorizationHeader; + const getAuthorizationHeader = this.getAuthorizationHeader.bind(this) as IGetAuthorizationHeader; const github = operations.github; const caching = { maxAgeSeconds: options.maxAgeSeconds || operations.defaults.orgRepoDetailsStaleSeconds, // borrowing from another value @@ -132,8 +102,8 @@ export default class GitHubApplication { return installations; } - private authorize(): GetAuthorizationHeader | string { - const getAuthorizationHeader = this.getAuthorizationHeader.bind(this) as GetAuthorizationHeader; + private authorize(): IGetAuthorizationHeader | string { + const getAuthorizationHeader = this.getAuthorizationHeader.bind(this) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/collaborator.ts b/business/collaborator.ts index ed745527d..c40bc6f67 100644 --- a/business/collaborator.ts +++ b/business/collaborator.ts @@ -4,7 +4,6 @@ // import { GitHubRepositoryPermission, IGitHubCollaboratorPermissions } from '../interfaces'; -import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../lib/transitional'; import * as common from './common'; // prettier-ignore @@ -15,19 +14,6 @@ const memberPrimaryProperties = [ 'avatar_url', ]; -export type CollaboratorJson = { - avatar_url: string; - id: number; - login: string; - permissions: IGitHubCollaboratorPermissions; -}; - -export type CollaboratorAccount = Collaborator | { id: number; login: string }; - -export function compareCollaborators(a: Collaborator, b: Collaborator) { - return a?.login.localeCompare(b?.login, 'en', { sensitivity: 'base' }); -} - export class Collaborator { public static PrimaryProperties = memberPrimaryProperties; @@ -42,7 +28,7 @@ export class Collaborator { } } - asJson(): CollaboratorJson { + asJson() { return { avatar_url: this.avatar_url, id: this._id, @@ -59,7 +45,15 @@ export class Collaborator { if (!this._permissions) { return GitHubRepositoryPermission.None; } - return projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(this._permissions); + const permissions = this._permissions; + if (permissions.admin) { + return GitHubRepositoryPermission.Admin; + } else if (permissions.push) { + return GitHubRepositoryPermission.Push; + } else if (permissions.pull) { + return GitHubRepositoryPermission.Pull; + } + throw new Error(`Unsupported permission type by getHighestPermission`); } get id(): number { diff --git a/business/domains.ts b/business/domains.ts index 73d211f3a..d283dac00 100644 --- a/business/domains.ts +++ b/business/domains.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { AppPurpose, AppPurposeTypes } from './githubApps'; import { Organization } from '.'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, throwIfNotGitHubCapable, - GetAuthorizationHeader, + IGetAuthorizationHeader, } from '../interfaces'; import { decorateIterable, @@ -17,7 +17,7 @@ import { IteratorResponse, PaginationPageSizeOptions, } from './iterable'; -import { DefaultGraphqlPageSize } from '../lib/transitional'; +import { DefaultGraphqlPageSize } from '../transitional'; type DomainResponse = { id: string; @@ -44,15 +44,15 @@ export class OrganizationDomains { private _organization: Organization; private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _purpose: AppPurpose; constructor( organization: Organization, operations: IOperationsInstance, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader ) { this._getAuthorizationHeader = getAuthorizationHeader; this._getSpecificAuthorizationHeader = getSpecificAuthorizationHeader; @@ -110,16 +110,19 @@ export class OrganizationDomains { } } - private authorize(purpose: AppPurpose = this._purpose): GetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose = this._purpose): IGetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/enterprise.ts b/business/enterprise.ts deleted file mode 100644 index 8c60aa5ae..000000000 --- a/business/enterprise.ts +++ /dev/null @@ -1,194 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { IProviders } from '../interfaces'; - -// TODO: paginate across enterprise fix + support iterators - -export type EnterpriseSamlExternalIdentityBasics = { - id: string; - user: { - login: string; - }; - samlIdentity: { - nameId: string; - }; -}; - -export type EnterpriseSamlExternalIdentityNode = { - node: EnterpriseSamlExternalIdentityBasics; -}; - -export default class GitHubEnterprise { - constructor( - private providers: IProviders, - public slug: string, - private administrativeToken: string - ) {} - - async getGitHubLoginForUserPrincipalName(userPrincipalName: string): Promise { - const node = await this.getSamlNodeFromUserPrincipalName(userPrincipalName); - return node?.user?.login; - } - - async getSamlNodeFromUserPrincipalName( - userPrincipalName: string - ): Promise { - const github = this.providers.github; - try { - const response = await github.graphql( - this.administrativeToken, - queries.getIdentityFromExternal, - { - enterpriseName: this.slug, - userPrincipalName, - }, - { - paginate: false, - } - ); - const nodes = response?.enterprise?.ownerInfo?.samlIdentityProvider?.externalIdentities - ?.edges as EnterpriseSamlExternalIdentityNode[]; - if (nodes.length > 0) { - return nodes[0].node; - } - } catch (error) { - throw error; - } - } - - async getSamlUserPrincipalNameForGitHubLogin(login: string): Promise { - const node = await this.getSamlNodeForGitHubLogin(login); - return node?.samlIdentity?.nameId; - } - - async getSamlNodeForGitHubLogin(login: string): Promise { - const github = this.providers.github; - try { - const response = await github.graphql( - this.administrativeToken, - queries.getIdentityFromGitHubLogin, - { - enterpriseName: this.slug, - login, - }, - { - paginate: false, - } - ); - const nodes = response?.enterprise?.ownerInfo?.samlIdentityProvider?.externalIdentities - ?.edges as EnterpriseSamlExternalIdentityNode[]; - if (nodes.length > 0) { - return nodes[0].node; - } - } catch (error) { - throw error; - } - } - - async getSamlMemberExternalIdentities(): Promise { - const fixedFirstFieldsCount = 8; - const github = this.providers.github; - try { - const response = await github.graphql( - this.administrativeToken, - queries.paginate, - { - enterpriseName: this.slug, - // id: this._id, - }, - { - paginate: false, // true, - } - ); - const nodes = response?.enterprise?.ownerInfo?.samlIdentityProvider?.externalIdentities - ?.edges as EnterpriseSamlExternalIdentityNode[]; - return nodes.map((node) => node.node); - } catch (error) { - throw error; - } - } -} - -const queries = { - getIdentityFromGitHubLogin: ` - query getIdentity($enterpriseName: String!, $login: String!) { - enterprise(slug: $enterpriseName) { - ownerInfo { - samlIdentityProvider { - externalIdentities(first: 5, login: $login) { - pageInfo { - hasNextPage - endCursor - } - edges { - node { - user { - login - } - samlIdentity { - nameId - } - } - } - } - } - } - } - } - `, - getIdentityFromExternal: ` - query getIdentity($enterpriseName: String!, $userPrincipalName: String!) { - enterprise(slug: $enterpriseName) { - ownerInfo { - samlIdentityProvider { - externalIdentities(first: 5, userName: $userPrincipalName) { - pageInfo { - hasNextPage - endCursor - } - edges { - node { - user { - login - } - samlIdentity { - nameId - } - } - } - } - } - } - } - } - `, - paginate: ` - query paginate($cursor: String, $enterpriseName: String!) { - enterprise(slug: $enterpriseName) { - ownerInfo { - samlIdentityProvider { - externalIdentities(after: $cursor, first: 100) { - pageInfo { - hasNextPage - endCursor - } - edges { - node { - user { - login - } - samlIdentity { - nameId - } - } - } - } - } - } - } - } - `, -}; diff --git a/lib/github/appTokens.ts b/business/githubApps/appTokens.ts similarity index 76% rename from lib/github/appTokens.ts rename to business/githubApps/appTokens.ts index 6e75bf780..7811be3c4 100644 --- a/lib/github/appTokens.ts +++ b/business/githubApps/appTokens.ts @@ -7,11 +7,10 @@ import { request } from '@octokit/request'; import { createAppAuth, InstallationAccessTokenAuthentication } from '@octokit/auth-app'; import { AppAuthentication, AuthInterface } from '@octokit/auth-app/dist-types/types'; -import { AppPurposeTypes, ICustomAppPurpose } from './appPurposes'; -import { AuthorizationHeaderValue } from '../../interfaces'; +import { AppPurposeTypes, ICustomAppPurpose } from '.'; +import { IAuthorizationHeaderValue } from '../../interfaces'; import Debug from 'debug'; -import { CreateError } from '../transitional'; const debug = Debug('github:tokens'); interface IInstallationToken { @@ -28,45 +27,6 @@ interface IInstallationToken { const InstallationTokenLifetimeMilliseconds = 1000 * 60 * 60; const ValidityOffsetAfterNowMilliseconds = 1000 * 120; // how long to require validity in the future -export enum GitHubTokenType { - PersonalAccessToken = 'ghp', - OAuthAccessToken = 'gho', - UserToServerToken = 'ghu', - ServerToServerToken = 'ghs', - RefreshToken = 'ghr', - FineGrainedPersonalAccessToken = 'github_pat', -} - -export const GitHubTokenTypes = [ - GitHubTokenType.PersonalAccessToken, - GitHubTokenType.OAuthAccessToken, - GitHubTokenType.UserToServerToken, - GitHubTokenType.ServerToServerToken, - GitHubTokenType.RefreshToken, - GitHubTokenType.FineGrainedPersonalAccessToken, -]; - -export function getGitHubTokenTypeFromValue(value: string | AuthorizationHeaderValue): GitHubTokenType { - if (!value) { - throw CreateError.ParameterRequired('value'); - } - if (typeof value === 'object') { - value = value.value; - } else if (typeof value !== 'string') { - throw CreateError.InvalidParameters('value must be a string or AuthorizationHeaderValue'); - } - if (!value.startsWith('token ')) { - throw CreateError.InvalidParameters('value must start with "token "'); - } - const tokenValue = value.substr(6); - for (const tokenType of GitHubTokenTypes) { - if (tokenValue.startsWith(tokenType)) { - return tokenType; - } - } - throw CreateError.InvalidParameters('value does not appear to be a GitHub token'); -} - export class GitHubAppTokens { #privateKey: string; private _appId: number; @@ -79,25 +39,23 @@ export class GitHubAppTokens { static CreateFromBase64EncodedFileString( purpose: AppPurposeTypes, - slug: string, friendlyName: string, applicationId: number, fileContents: string, baseUrl?: string ): GitHubAppTokens { const keyContents = Buffer.from(fileContents, 'base64').toString('utf8').replace(/\r\n/g, '\n'); - return new GitHubAppTokens(purpose, slug, friendlyName, applicationId, keyContents, baseUrl); + return new GitHubAppTokens(purpose, friendlyName, applicationId, keyContents, baseUrl); } static CreateFromString( purpose: AppPurposeTypes, - slug: string, friendlyName: string, applicationId: number, value: string, baseUrl?: string ): GitHubAppTokens { - return new GitHubAppTokens(purpose, slug, friendlyName, applicationId, value, baseUrl); + return new GitHubAppTokens(purpose, friendlyName, applicationId, value, baseUrl); } get appId() { @@ -110,7 +68,6 @@ export class GitHubAppTokens { constructor( purpose: AppPurposeTypes, - public slug: string, public friendlyName: string, appId: number, privateKey: string, @@ -157,7 +114,7 @@ export class GitHubAppTokens { async getInstallationToken( installationId: number, organizationName: string - ): Promise { + ): Promise { const now = new Date(); const requiredValidityPeriod = new Date(now.getTime() + ValidityOffsetAfterNowMilliseconds); const latestToken = this.getLatestValidToken(installationId, requiredValidityPeriod); @@ -256,12 +213,8 @@ function sortByLatestToken(a: IInstallationToken, b: IInstallationToken) { function tokenValidFilter(timeTokenMustBeValid: Date, token: IInstallationToken) { const isValid = token.expires > timeTokenMustBeValid; if (!isValid) { - const header = token.headerValue.substr(6); - const subset = (header.length > 12 ? header.substr(0, 8) : '') + '*'.repeat(4); console.log( - `token expired: redacted=${subset}, expires=${token.expires.toISOString()}, install_id=${ - token.installationId - }, org=${token.organizationName}` + `invalid or expired token being removed: expires=${token.expires} install_id=${token.installationId} org=${token.organizationName}` ); return false; } diff --git a/business/githubApps/index.ts b/business/githubApps/index.ts new file mode 100644 index 000000000..7f1ddfdec --- /dev/null +++ b/business/githubApps/index.ts @@ -0,0 +1,151 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { IReposApplication } from '../../interfaces'; +import { CreateError } from '../../transitional'; + +import Debug from 'debug'; +const debug = Debug('github:tokens'); + +export enum AppPurpose { + Data = 'Data', + CustomerFacing = 'CustomerFacing', + Operations = 'Operations', + BackgroundJobs = 'BackgroundJobs', // "secondary" / "default" fallback + Updates = 'Updates', + Security = 'Security', + ActionsData = 'ActionsData', +} + +export interface ICustomAppPurpose { + isCustomAppPurpose: boolean; // basic type check + id: string; + name: string; + getForOrganizationName?(organizationName: string): IGitHubAppConfiguration; + getApplicationConfigurationForInitialization?(): IGitHubAppConfiguration; +} + +export type AppPurposeTypes = AppPurpose | ICustomAppPurpose; + +export abstract class CustomAppPurpose implements ICustomAppPurpose { + get isCustomAppPurpose() { + return true; + } + constructor(public id: string, public name: string) {} +} + +export class CustomAppPurposeOrganizationVariance extends CustomAppPurpose { + fallbackIfNotConfiguredOrganizationName = false; + constructor(public id: string, public name: string, private configurations: IGitHubAppConfiguration[]) { + super(id, name); + } + getForOrganizationName(organizationName: string) { + const configuration = this.configurations.find( + (c) => c.specificOrganizationName.toLowerCase() === organizationName.toLowerCase() + ); + if (!configuration && this.fallbackIfNotConfiguredOrganizationName === false) { + throw CreateError.NotFound(`No configuration found for organization ${organizationName}`); + } + return configuration || this.configurations[0]; + } +} + +export class CustomAppPurposeSingleConfiguration extends CustomAppPurpose { + constructor(public id: string, public name: string, private configuration: IGitHubAppConfiguration) { + super(id, name); + } + + getApplicationConfigurationForInitialization() { + return this.configuration; + } +} + +export const DefinedAppPurposes = [ + AppPurpose.Data, + AppPurpose.CustomerFacing, + AppPurpose.Operations, + AppPurpose.BackgroundJobs, + AppPurpose.Updates, + AppPurpose.Security, + AppPurpose.ActionsData, +]; + +// export const GitHubAppPurposesExemptFromAllRepositoriesSelection = [AppPurpose.Onboarding]; + +const appPurposeToConfigurationName = { + [AppPurpose.Data]: 'data', + [AppPurpose.CustomerFacing]: 'ui', + [AppPurpose.Operations]: 'operations', + [AppPurpose.BackgroundJobs]: 'jobs', + [AppPurpose.Updates]: 'updates', + [AppPurpose.Security]: 'security', + [AppPurpose.ActionsData]: 'actions', +}; + +export function getAppPurposeId(purpose: AppPurposeTypes) { + if ((purpose as ICustomAppPurpose).isCustomAppPurpose === true) { + return (purpose as ICustomAppPurpose).id; + } + const asPurpose = purpose as AppPurpose; + const id = appPurposeToConfigurationName[asPurpose]; + if (!id) { + throw new Error(`No configuration name for purpose ${asPurpose}`); + } + return id; +} + +export class GitHubAppPurposes { + private static _instance: GitHubAppPurposes = new GitHubAppPurposes(); + + static get AllAvailableAppPurposes() { + debug(`Retrieving all available purposes (${this._instance._purposes.length})`); + return this._instance._purposes; + } + + static RegisterCustomPurpose(purpose: ICustomAppPurpose) { + debug(`Registering custom purpose ${purpose.id} (${purpose.name})`); + if (purpose.isCustomAppPurpose !== true) { + throw new Error('Purpose must have `isCustomAppPurpose` set to true'); + } + if ( + (this._instance._purposes as ICustomAppPurpose[]) + .filter((p) => (p as ICustomAppPurpose)?.isCustomAppPurpose === true) + .find((p) => p.id === purpose.id) + ) { + throw new Error(`Purpose with ID ${purpose.id} already registered`); + } + this._instance._purposes.push(purpose); + } + + private _purposes: AppPurposeTypes[]; + + constructor() { + this._purposes = [...DefinedAppPurposes]; + } +} + +export enum GitHubAppAuthenticationType { + ForceSpecificInstallation = 'force', + BestAvailable = 'best', +} + +export interface IGitHubAppConfiguration { + clientId?: string; + clientSecret?: string; + appId?: number; + appKey?: string; + appKeyFile?: string; + webhookSecret?: string; + slug?: string; + description?: string; + baseUrl?: string; + + specificOrganizationName?: string; +} + +export interface IGitHubAppsOptions { + app: IReposApplication; + configurations: Map; +} diff --git a/lib/github/tokenManager.ts b/business/githubApps/tokenManager.ts similarity index 65% rename from lib/github/tokenManager.ts rename to business/githubApps/tokenManager.ts index 413b4940e..560ba6e7f 100644 --- a/lib/github/tokenManager.ts +++ b/business/githubApps/tokenManager.ts @@ -15,21 +15,20 @@ import { GitHubAppPurposes, AppPurposeTypes, getAppPurposeId, -} from './appPurposes'; +} from '.'; import { GitHubAppTokens } from './appTokens'; -import { AuthorizationHeaderValue, GetAuthorizationHeader, NoCacheNoBackground } from '../../interfaces'; -import { OrganizationSetting } from '../../business/entities/organizationSettings/organizationSetting'; -import { readFileToText } from '../utils'; -import { Operations, OperationsCore, Organization } from '../../business'; -import { CreateError } from '../transitional'; -import { shuffle } from 'lodash'; +import { IAuthorizationHeaderValue, NoCacheNoBackground } from '../../interfaces'; +import { OrganizationSetting } from '../../entities/organizationSettings/organizationSetting'; +import { readFileToText } from '../../utils'; +import { Operations, OperationsCore, Organization } from '..'; +import { CreateError } from '../../transitional'; -export type GitHubRateLimit = { +export interface IGitHubRateLimit { limit: number; remaining: number; reset: number; used: number; -}; +} // Installation redirect format: // /setup/app/APP_ID?installation_id=INSTALLATION_ID&setup_action=install @@ -54,7 +53,7 @@ export class GitHubTokenManager { private _forceInstanceTokensToPurpose: AppPurposeTypes; private _allowReadOnlyFallbackToOtherInstallations: boolean; - private static RegisterManagerForOperations(operations: OperationsCore, manager: GitHubTokenManager) { + static RegisterManagerForOperations(operations: OperationsCore, manager: GitHubTokenManager) { GitHubTokenManager._managersForOperations.set(operations, manager); } @@ -66,15 +65,9 @@ export class GitHubTokenManager { if (!options) { throw new Error('options required'); } - const executionEnvironment = options.executionEnvironment; this.#options = options; GitHubTokenManager._forceBackgroundTokens = - executionEnvironment.isJob && !executionEnvironment.enableAllGitHubApps; - GitHubTokenManager.RegisterManagerForOperations(options.operations, this); - } - - private operations() { - return this.#options.operations as Operations; + options.app.isBackgroundJob && !options.app.enableAllGitHubApps; } private getFallbackList(input: AppPurposeTypes[]) { @@ -153,8 +146,6 @@ export class GitHubTokenManager { } private getPurposeDisplayId(purpose: AppPurposeTypes) { - // is this identical to the method getAppPurposeId? - const asCustom = purpose as ICustomAppPurpose; if (asCustom?.isCustomAppPurpose === true) { return asCustom.id; @@ -170,38 +161,14 @@ export class GitHubTokenManager { return null; } - async ensureConfigurationAppInitialized( - customPurpose: AppPurposeTypes, - customPurposeConfiguration: IGitHubAppConfiguration - ): Promise { - const appId = customPurposeConfiguration.appId; - const asCustomPurpose = this.getCustomPurpose(customPurpose); - if (!asCustomPurpose?.isCustomAppPurpose) { - throw CreateError.InvalidParameters(`The purpose ${customPurpose} is not a custom app purpose`); - } - let app = this._appsById.get(appId); - if (!app) { - debug(`initializing app for custom purpose ${asCustomPurpose.id} with custom configuration`); - app = await this.initializeApp(asCustomPurpose, customPurposeConfiguration); - } - if (!app) { - throw CreateError.InvalidParameters( - `Error initializing purpose ${this.getPurposeDisplayId(customPurpose)}` - ); - } - return app; - } - async getOrganizationAuthorizationHeader( organizationName: string, preferredPurpose: AppPurposeTypes, organizationSettings: OrganizationSetting, appAuthenticationType: GitHubAppAuthenticationType - ): Promise { + ): Promise { debug( - `getOrganizationAuthorizationHeader(${organizationName}, ${this.getPurposeDisplayId( - preferredPurpose - )}, ${appAuthenticationType})` + `getOrganizationAuthorizationHeader(${organizationName}, ${preferredPurpose}, ${appAuthenticationType})` ); const installationIdPair = this.getPrioritizedOrganizationInstallationId( preferredPurpose, @@ -210,10 +177,8 @@ export class GitHubTokenManager { appAuthenticationType ); if (!installationIdPair) { - throw CreateError.InvalidParameters( - `GitHubTokenManager: organization ${organizationName} does not have a configured GitHub App installation, or, the installation information is not in this environment. The API preferred purpose was ${getAppPurposeId( - preferredPurpose - )} with the selection type ${appAuthenticationType}.` + throw new Error( + `GitHubTokenManager: organization ${organizationName} does not have a configured GitHub App installation, or, the installation information is not in this environment. The API preferred purpose was ${preferredPurpose} with the selection type ${appAuthenticationType}.` ); } if ( @@ -267,18 +232,16 @@ export class GitHubTokenManager { ); const value = await app.getInstallationToken(installationIdPair.installationId, organizationName); debug( - `returned installation ID pair: installationId=${value?.installationId}, source=${value?.source}, purpose=${this.getPurposeDisplayId( - value?.purpose - )}` + `returned installation ID pair: installationId=${value?.installationId}, source=${value?.source}, purpose=${value?.purpose}` ); return value; } - getInstallationAuthorizationHeader( + async getInstallationAuthorizationHeader( appId: number, installationId: number, organizationName: string - ): Promise { + ): Promise { const app = this._appsById.get(appId); if (!app) { throw new Error(`App ID=${appId} is not configured in this application instance`); @@ -286,52 +249,10 @@ export class GitHubTokenManager { return app.getInstallationToken(installationId, organizationName); } - getAppForPurpose(purpose: AppPurposeTypes, organizationName?: string) { - const asCustomPurpose = this.getCustomPurpose(purpose); - if (asCustomPurpose?.getForOrganizationName) { - const configForOrganization = asCustomPurpose.getForOrganizationName(organizationName); - const appId = configForOrganization.appId; - if (appId) { - return this._appsById.get(appId); - } - } else if (asCustomPurpose?.getApplicationConfigurationForInitialization) { - const config = asCustomPurpose.getApplicationConfigurationForInitialization(); - const appId = config.appId; - if (appId) { - return this._appsById.get(appId); - } - } + getAppForPurpose(purpose: AppPurposeTypes) { return this._apps.get(purpose); } - getAnyConfiguredInstallationIdForAppId(operations: Operations, appId: number) { - const orgs = operations.getOrganizations(); - for (const org of orgs) { - const settings = org.getDynamicSettings(); - if (settings?.installations) { - for (const { appId: appConfiguredId, installationId } of settings.installations) { - if (appConfiguredId === appId) { - return { installationId, organizationName: org.name }; - } - } - } - } - } - - getAnyConfiguredInstallationIdForAnyApp(operations: Operations) { - const orgs = shuffle(operations.getOrganizations()); - for (const org of orgs) { - const settings = org.getDynamicSettings(); - if (settings?.installations) { - const installs = shuffle(settings.installations); - const configuredInstalls = installs.filter((i) => this._appsById.has(i.appId)); - for (const { installationId, appId } of configuredInstalls) { - return { installationId, organizationName: org.name, appId }; - } - } - } - } - getInstallationIdForOrganization(purpose: AppPurposeTypes, organization: Organization) { const settings = organization.getDynamicSettings(); if (settings?.installations) { @@ -342,18 +263,7 @@ export class GitHubTokenManager { } } } - const asCustomPurpose = this.getCustomPurpose(purpose); - if (asCustomPurpose?.getForOrganizationName) { - const configForOrganization = asCustomPurpose.getForOrganizationName(organization.name); - if (configForOrganization.slug) { - throw CreateError.NotImplemented( - `While a custom purpose is configured for the "${organization.name}" with the app ${configForOrganization.slug}, the installation ID is not yet available with this call. This is a known limitation.` - ); - } - throw CreateError.NotImplemented( - `This custom purpose is not configured for the "${organization.name}" org with the app ${configForOrganization.slug}, the installation ID is not yet available with this call. This is a known limitation.` - ); - } + // CONSIDER: custom purposes could expose the installation ID here if (!organization.hasDynamicSettings) { throw CreateError.InvalidParameters( `Organization ${organization.name} does not have dynamic settings or purpose-directed configuration` @@ -361,73 +271,6 @@ export class GitHubTokenManager { } } - getAuthorizationHeaderForAnyApp(): Promise { - const anyConfigured = this.getAnyConfiguredInstallationIdForAnyApp(this.operations()); - if (anyConfigured) { - return this.getInstallationAuthorizationHeader( - anyConfigured.appId, - anyConfigured.installationId, - anyConfigured.organizationName - ); - } - throw CreateError.InvalidParameters('No configured applications available.'); - } - - async getAppInformation(purpose: AppPurposeTypes, organizationName?: string) { - const appTokens = this.getAppForPurpose(purpose, organizationName); - if (!appTokens) { - throw CreateError.InvalidParameters(`No app configured yet for purpose ${purpose}`); - } - const slug = appTokens.slug; - if (!slug) { - throw CreateError.InvalidParameters(`No slug configured for purpose ${purpose}`); - } - return this.getAppInformationBySlug(this.operations(), slug); - } - - async getAppInformationBySlug(operations: Operations, slug: string) { - let appId: number = null; - for (const entry of this._appSlugs.entries()) { - if (entry[1] === slug) { - appId = entry[0]; - break; - } - } - let authorizationHeader: GetAuthorizationHeader = null; - // Have the app call itself via the slug-based API (works if it's a private single-org app) - if (appId) { - const anyConfiguredForApp = this.getAnyConfiguredInstallationIdForAppId(operations, appId); - if (anyConfiguredForApp) { - authorizationHeader = this.getInstallationAuthorizationHeader.bind( - this, - appId, - anyConfiguredForApp.installationId, - anyConfiguredForApp.organizationName - ); - } - } - // Call using any configured app - if (!authorizationHeader) { - const anyConfigured = this.getAnyConfiguredInstallationIdForAnyApp(operations); - if (anyConfigured) { - authorizationHeader = this.getInstallationAuthorizationHeader.bind( - this, - anyConfigured.appId, - anyConfigured.installationId, - anyConfigured.organizationName - ); - } - } - // Fallback to a static token - if (!authorizationHeader) { - authorizationHeader = operations.getPublicReadOnlyStaticToken.bind(operations); - } - const value = await operations.github.post(authorizationHeader, 'apps.getBySlug', { - app_slug: slug, - }); - return value; - } - async getRateLimitInformation(purpose: AppPurposeTypes, organization: Organization) { const settings = organization.getDynamicSettings(); if (settings?.installations) { @@ -446,7 +289,7 @@ export class GitHubTokenManager { NoCacheNoBackground ); if (value?.rate) { - return value.rate as GitHubRateLimit; + return value.rate as IGitHubRateLimit; } console.warn(value); throw CreateError.InvalidParameters('No rate limit information returned'); @@ -482,18 +325,12 @@ export class GitHubTokenManager { const allPurposes = GitHubAppPurposes.AllAvailableAppPurposes; const fallbackPurposePriorities = this.getFallbackList(allPurposes); const customPurposes = allPurposes.filter((p) => (p as ICustomAppPurpose).isCustomAppPurpose === true); - const matchingCustomPurposes = - (preferredPurpose as ICustomAppPurpose)?.isCustomAppPurpose === true - ? customPurposes.filter( - (cp) => (cp as ICustomAppPurpose).id === (preferredPurpose as ICustomAppPurpose).id - ) - : customPurposes; let order = this.isForcingBackgroundJobType() === true ? fallbackPurposePriorities : [preferredPurpose, ...fallbackPurposePriorities]; if (appAuthenticationType === GitHubAppAuthenticationType.ForceSpecificInstallation) { - order = [preferredPurpose, ...matchingCustomPurposes]; + order = [preferredPurpose, ...customPurposes]; } for (const purpose of order) { let customAppPurpose = purpose as ICustomAppPurpose; @@ -546,12 +383,11 @@ export class GitHubTokenManager { // Not base64-encoded, use the CreateFromString method. skipDecodingBase64 = true; } - const slug = appConfig.slug; const friendlyName = customPurpose?.name || appConfig.description || 'Unknown'; const baseUrl = appConfig.baseUrl; const app = skipDecodingBase64 - ? GitHubAppTokens.CreateFromString(purpose, slug, friendlyName, appId, key, baseUrl) - : GitHubAppTokens.CreateFromBase64EncodedFileString(purpose, slug, friendlyName, appId, key, baseUrl); + ? GitHubAppTokens.CreateFromString(purpose, friendlyName, appId, key, baseUrl) + : GitHubAppTokens.CreateFromBase64EncodedFileString(purpose, friendlyName, appId, key, baseUrl); const hasCustomConfigurationByOrganization = customPurpose?.getForOrganizationName; const standardPurpose = purpose as AppPurpose; if (!hasCustomConfigurationByOrganization) { diff --git a/business/graphManager.ts b/business/graphManager.ts index a0e0cdc2c..eb3624736 100644 --- a/business/graphManager.ts +++ b/business/graphManager.ts @@ -18,7 +18,7 @@ import { IPagedCrossOrganizationCacheOptions, GitHubRepositoryPermission, } from '../interfaces'; -import { isPermissionBetterThan } from '../lib/transitional'; +import { isPermissionBetterThan } from '../transitional'; interface ILocalLinksCache { updated: moment.Moment; diff --git a/business/operations/administration.ts b/business/operations/administration.ts index 139f7e830..6cc984d31 100644 --- a/business/operations/administration.ts +++ b/business/operations/administration.ts @@ -4,7 +4,7 @@ // import { IProviders } from '../../interfaces'; -import { ErrorHelper } from '../../lib/transitional'; +import { ErrorHelper } from '../../transitional'; export async function isAuthorizedSystemAdministrator( providers: IProviders, diff --git a/business/operations/core.ts b/business/operations/core.ts index 161e2164e..6b4e0fdd4 100644 --- a/business/operations/core.ts +++ b/business/operations/core.ts @@ -3,14 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { OrganizationSetting } from '../entities/organizationSettings/organizationSetting'; -import { - GitHubAppAuthenticationType, - AppPurpose, - ICustomAppPurpose, - AppPurposeTypes, -} from '../../lib/github/appPurposes'; -import { GitHubTokenManager } from '../../lib/github/tokenManager'; +import { OrganizationSetting } from '../../entities/organizationSettings/organizationSetting'; +import { GitHubAppAuthenticationType, AppPurpose, ICustomAppPurpose, AppPurposeTypes } from '../githubApps'; +import { GitHubTokenManager } from '../githubApps/tokenManager'; import { IProviders, ICacheDefaultTimes, @@ -24,48 +19,22 @@ import { throwIfNotGitHubCapable, throwIfNotCapable, IOperationsCentralOperationsToken, - AuthorizationHeaderValue, + IAuthorizationHeaderValue, SiteConfiguration, - ExecutionEnvironment, - IPagedCacheOptions, - ICacheOptionsWithPurpose, } from '../../interfaces'; import { RestLibrary } from '../../lib/github'; -import { CreateError } from '../../lib/transitional'; -import { wrapError } from '../../lib/utils'; +import { CreateError } from '../../transitional'; +import { wrapError } from '../../utils'; import { Account } from '../account'; import GitHubApplication from '../application'; import Debug from 'debug'; const debugGitHubTokens = Debug('github:tokens'); -const symbolCost = Symbol('cost'); -const symbolHeaders = Symbol('headers'); - -export function symbolizeApiResponse(response: any): T { - if (response && response.headers) { - response[symbolHeaders] = response.headers; - delete response.headers; - } - if (response && response.cost) { - response[symbolCost] = response.cost; - delete response.cost; - } - return response; -} - -export function getApiSymbolMetadata(response: any) { - if (response) { - return { headers: response[symbolHeaders], cost: response[symbolCost] }; - } - throw CreateError.ParameterRequired('response'); -} - export interface IOperationsCoreOptions { github: RestLibrary; providers: IProviders; baseUrl?: string; - executionEnvironment: ExecutionEnvironment; } export enum CacheDefault { @@ -92,7 +61,6 @@ export enum CacheDefault { teamDetailStaleSeconds = 'teamDetailStaleSeconds', orgRepoWebhooksStaleSeconds = 'orgRepoWebhooksStaleSeconds', teamRepositoryPermissionStaleSeconds = 'teamRepositoryPermissionStaleSeconds', - defaultStaleSeconds = 'defaultStaleSeconds', } // defaults could move to configuration alternatively @@ -120,7 +88,6 @@ const defaults: ICacheDefaultTimes = { [CacheDefault.teamDetailStaleSeconds]: 60 * 60 * 2 /* 2h */, [CacheDefault.orgRepoWebhooksStaleSeconds]: 60 * 60 * 8 /* 8h */, [CacheDefault.teamRepositoryPermissionStaleSeconds]: 0 /* 0m */, - [CacheDefault.defaultStaleSeconds]: 60 /* 1m */, }; export const DefaultPageSize = 100; @@ -139,46 +106,6 @@ export function getPageSize(operations: IOperationsInstance, options?: IOptionWi return DefaultPageSize; } -export function createCacheOptions( - operations: IOperationsInstance, - options?: ICacheOptions, - cacheDefault: CacheDefault = CacheDefault.defaultStaleSeconds -) { - const cacheOptions: ICacheOptions = { - maxAgeSeconds: getMaxAgeSeconds(operations, cacheDefault, options, 60), - }; - if (options.backgroundRefresh !== undefined) { - cacheOptions.backgroundRefresh = options.backgroundRefresh; - } - return cacheOptions; -} - -export function createPagedCacheOptions( - operations: IOperationsInstance, - options?: IPagedCacheOptions, - cacheDefault: CacheDefault = CacheDefault.defaultStaleSeconds -) { - const cacheOptions: IPagedCacheOptions = { - maxAgeSeconds: getMaxAgeSeconds(operations, cacheDefault, options, 60), - }; - if (options.pageRequestDelay !== undefined) { - cacheOptions.pageRequestDelay = options.pageRequestDelay; - } - if (options.backgroundRefresh !== undefined) { - cacheOptions.backgroundRefresh = options.backgroundRefresh; - } - return cacheOptions; -} - -export function popPurpose(options: ICacheOptionsWithPurpose, defaultPurpose: AppPurposeTypes) { - if (options.purpose) { - const purpose = options.purpose; - delete options.purpose; - return purpose; - } - return defaultPurpose; -} - export function getMaxAgeSeconds( operations: IOperationsInstance, cacheDefault: CacheDefault, @@ -268,7 +195,7 @@ export abstract class OperationsCore async getAccountByUsername(username: string, options?: ICacheOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this); - const ops = throwIfNotCapable( + const centralOperations = throwIfNotCapable( this, CoreCapability.GitHubCentralOperations ); @@ -285,9 +212,10 @@ export abstract class OperationsCore cacheOptions.backgroundRefresh = options.backgroundRefresh; } try { - const getHeaderFunction = ops.getPublicAuthorizationToken(); + const getHeaderFunction = centralOperations.getCentralOperationsToken(); + const authorizationHeader = await getHeaderFunction(AppPurpose.Data); const entity = await operations.github.call( - getHeaderFunction, + authorizationHeader, 'users.getByUsername', parameters, cacheOptions @@ -407,16 +335,17 @@ export abstract class OperationsCore organizationName: string, organizationSettings: OrganizationSetting, legacyOwnerToken: string, + centralOperationsFallbackToken: string, appAuthenticationType: GitHubAppAuthenticationType, purpose: AppPurposeTypes - ): Promise { + ): Promise { const customPurpose = purpose as ICustomAppPurpose; const isCustomPurpose = customPurpose?.isCustomAppPurpose === true; if ( !isCustomPurpose && !this.tokenManager.organizationSupportsAnyPurpose(organizationName, organizationSettings) ) { - const legacyTokenValue = legacyOwnerToken; + const legacyTokenValue = legacyOwnerToken || centralOperationsFallbackToken; if (!legacyTokenValue) { throw new Error( `Organization ${organizationName} is not configured with a GitHub app, Personal Access Token ownerToken configuration value, or a fallback central operations token for the ${ @@ -427,7 +356,7 @@ export abstract class OperationsCore return { value: `token ${legacyTokenValue}`, purpose: null, - source: 'legacyOwnerToken', + source: legacyOwnerToken ? 'legacyOwnerToken' : 'centralOperationsFallbackToken', }; } if (!purpose) { diff --git a/business/operations/index.ts b/business/operations/index.ts index 7040e423c..c2124a153 100644 --- a/business/operations/index.ts +++ b/business/operations/index.ts @@ -5,33 +5,31 @@ import axios from 'axios'; import throat from 'throat'; -import { shuffle } from 'lodash'; import { Account } from '../account'; import { GraphManager } from '../graphManager'; -import { GitHubOrganizationResponse, Organization } from '../organization'; -import { GitHubTokenManager } from '../../lib/github/tokenManager'; +import { IGitHubOrganizationResponse, Organization } from '../organization'; +import { GitHubTokenManager } from '../githubApps/tokenManager'; import RenderHtmlMail from '../../lib/emailRender'; -import { wrapError, sortByCaseInsensitive } from '../../lib/utils'; +import { wrapError, sortByCaseInsensitive } from '../../utils'; import { Repository } from '../repository'; import { RestLibrary } from '../../lib/github'; import { - AppPurpose, AppPurposeTypes, getAppPurposeId, GitHubAppAuthenticationType, GitHubAppPurposes, IGitHubAppConfiguration, -} from '../../lib/github/appPurposes'; +} from '../githubApps'; import { OrganizationFeature, OrganizationSetting, -} from '../entities/organizationSettings/organizationSetting'; -import { OrganizationSettingProvider } from '../entities/organizationSettings/organizationSettingProvider'; +} from '../../entities/organizationSettings/organizationSetting'; +import { OrganizationSettingProvider } from '../../entities/organizationSettings/organizationSettingProvider'; import { IMail } from '../../lib/mailProvider'; import { ILinkProvider } from '../../lib/linkProviders'; import { ICacheHelper } from '../../lib/caching'; -import { createPortalSudoInstance, IPortalSudo } from '../features'; +import { createPortalSudoInstance, IPortalSudo } from '../../features'; import { CacheDefault, getMaxAgeSeconds, IOperationsCoreOptions, OperationsCore } from './core'; import { linkAccounts as linkAccountsMethod } from './link'; import { sendTerminatedAccountMail as sendTerminatedAccountMailMethod } from './unlinkMail'; @@ -44,7 +42,7 @@ import { ICreateLinkOptions, ICrossOrganizationMembershipByOrganization, ICrossOrganizationTeamMembership, - GetAuthorizationHeader, + IGetAuthorizationHeader, IGitHubAppInstallation, IMapPlusMetaCost, IOperationsCentralOperationsToken, @@ -58,22 +56,18 @@ import { IOperationsTemplates, IPagedCrossOrganizationCacheOptions, IPromisedLinks, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, ISupportedLinkTypeOutcome, IUnlinkMailStatus, NoCacheNoBackground, SupportedLinkType, UnlinkPurpose, - type LinkEvent, - type UnlinkEvent, } from '../../interfaces'; -import { CreateError, ErrorHelper } from '../../lib/transitional'; +import { CreateError, ErrorHelper } from '../../transitional'; import { Team } from '../team'; -import { IRepositoryMetadataProvider } from '../entities/repositoryMetadata/repositoryMetadataProvider'; +import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; import { isAuthorizedSystemAdministrator } from './administration'; import type { ConfigGitHubOrganizationsSpecializedList } from '../../config/github.organizations.types'; -import { type GitHubTokenType, getGitHubTokenTypeFromValue } from '../../lib/github/appTokens'; -import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; export * from './core'; @@ -92,7 +86,13 @@ export interface ICrossOrganizationMembersResult extends Map {} export interface IOperationsOptions extends IOperationsCoreOptions { + // cacheProvider: ICacheHelper; + // config: any; github: RestLibrary; + // insights: TelemetryClient; + // linkProvider: ILinkProvider; + // mailAddressProvider: IMailAddressProvider; + // mailProvider: IMailProvider; repositoryMetadataProvider: IRepositoryMetadataProvider; } @@ -102,12 +102,6 @@ export type GetInvisibleOrganizationOptions = { storeInstanceByName?: boolean; }; -type CreateOrganizationOptions = { - settings: OrganizationSetting; - appAuthenticationType: GitHubAppAuthenticationType; - asUncontrolledPublicOnly?: boolean; -}; - export class Operations extends OperationsCore implements @@ -128,7 +122,7 @@ export class Operations private _invisibleOrganizations: Map; private _uncontrolledOrganizations: Map; private _organizationOriginalNames: any; - private _organizationNamesWithAuthorizationHeaders: Map; + private _organizationNamesWithAuthorizationHeaders: Map; private _defaultPageSize: number; private _organizationIds: Map; private _organizationSettings: OrganizationSetting[]; @@ -184,10 +178,10 @@ export class Operations } } this._tokenManager = new GitHubTokenManager({ - operations: this, configurations: purposesToConfigurations, - executionEnvironment: options.executionEnvironment, + app: this.providers.app, }); + GitHubTokenManager.RegisterManagerForOperations(this, this._tokenManager); this._dynamicOrganizationIds = new Set(); this._organizationSettings = []; } @@ -348,46 +342,41 @@ export class Operations return Array.from(this._organizationIds.keys()); } - private createOrganization(name: string, options: CreateOrganizationOptions): Organization { + private createOrganization( + name: string, + settings: OrganizationSetting, + centralOperationsFallbackToken: string, + appAuthenticationType: GitHubAppAuthenticationType + ): Organization { name = name.toLowerCase(); - if (!options) { - throw CreateError.ParameterRequired('options'); - } - const { settings, appAuthenticationType, asUncontrolledPublicOnly } = options; if (!settings) { - throw CreateError.InvalidParameters( - `This application does not have configuration information for the ${name} organization` - ); + throw new Error(`This application is not configured for the ${name} organization`); } const ownerToken = settings.getOwnerToken(); const hasDynamicSettings = this._dynamicOrganizationIds && settings.organizationId && this._dynamicOrganizationIds.has(Number(settings.organizationId)); - let configuredGetAuthorizationHeader: GetAuthorizationHeader = this.getAuthorizationHeader.bind( - this, - name, - settings, - ownerToken, - appAuthenticationType - ); - let forcedGetAuthorizationHeader: GetAuthorizationHeader = this.getAuthorizationHeader.bind( - this, - name, - settings, - ownerToken, - GitHubAppAuthenticationType.ForceSpecificInstallation - ); - if (!ownerToken && asUncontrolledPublicOnly) { - configuredGetAuthorizationHeader = this.getPublicAuthorizationToken(); - forcedGetAuthorizationHeader = configuredGetAuthorizationHeader; - } return new Organization( this, name, settings, - configuredGetAuthorizationHeader, - forcedGetAuthorizationHeader, + this.getAuthorizationHeader.bind( + this, + name, + settings, + ownerToken, + centralOperationsFallbackToken, + appAuthenticationType + ), + this.getAuthorizationHeader.bind( + this, + name, + settings, + ownerToken, + centralOperationsFallbackToken, + GitHubAppAuthenticationType.ForceSpecificInstallation + ), hasDynamicSettings ); } @@ -396,6 +385,7 @@ export class Operations if (!this._organizations) { const organizations = new Map(); const names = this.organizationNames; + const centralOperationsToken = this.config.github.operations.centralOperationsToken; for (let i = 0; i < names.length; i++) { const name = names[i]; let settings: OrganizationSetting = null; @@ -408,10 +398,12 @@ export class Operations settings = dos; } } - const organization = this.createOrganization(name, { + const organization = this.createOrganization( + name, settings, - appAuthenticationType: GitHubAppAuthenticationType.BestAvailable, - }); + centralOperationsToken, + GitHubAppAuthenticationType.BestAvailable + ); organizations.set(name, organization); } this._organizations = organizations; @@ -430,10 +422,13 @@ export class Operations for (let i = 0; i < list.length; i++) { const settings = list[i]; if (settings && settings.name && settings.name.toLowerCase() === lowercase) { - return this.createOrganization(lowercase, { - settings: OrganizationSetting.CreateFromStaticSettings(settings), - appAuthenticationType: GitHubAppAuthenticationType.BestAvailable, - }); + const centralOperationsToken = this.config.github.operations.centralOperationsToken; + return this.createOrganization( + lowercase, + OrganizationSetting.CreateFromStaticSettings(settings), + centralOperationsToken, + GitHubAppAuthenticationType.BestAvailable + ); } } } @@ -449,10 +444,12 @@ export class Operations } getUnconfiguredOrganization(settings: OrganizationSetting): Organization { - return this.createOrganization(settings.organizationName.toLowerCase(), { + return this.createOrganization( + settings.organizationName.toLowerCase(), settings, - appAuthenticationType: GitHubAppAuthenticationType.BestAvailable, - }); + null, + GitHubAppAuthenticationType.BestAvailable + ); } // An invisible organization does not appear in the cross-organization @@ -483,10 +480,7 @@ export class Operations dynamicSettings = options.settings; } const authenticationType = options?.authenticationType || GitHubAppAuthenticationType.BestAvailable; - const organization = this.createOrganization(name, { - settings: dynamicSettings, - appAuthenticationType: authenticationType, - }); + const organization = this.createOrganization(name, dynamicSettings, null, authenticationType); if (!options || options?.storeInstanceByName) { this._invisibleOrganizations.set(name, organization); } @@ -504,12 +498,13 @@ export class Operations } const emptySettings = new OrganizationSetting(); emptySettings.operationsNotes = `Uncontrolled Organization - ${organizationName}`; - const asUncontrolledPublicOnly = true; - const org = this.createOrganization(organizationName, { - settings: emptySettings, - appAuthenticationType: GitHubAppAuthenticationType.ForceSpecificInstallation, - asUncontrolledPublicOnly, - }); + const centralOperationsToken = this.config.github.operations.centralOperationsToken; + const org = this.createOrganization( + organizationName, + emptySettings, + centralOperationsToken, + GitHubAppAuthenticationType.ForceSpecificInstallation + ); this._uncontrolledOrganizations.set(organizationName, org); org.uncontrolled = true; return org; @@ -517,19 +512,18 @@ export class Operations getPublicOnlyAccessOrganization(organizationName: string, organizationId?: number): Organization { organizationName = organizationName.toLowerCase(); + const emptySettings = new OrganizationSetting(); + emptySettings.operationsNotes = `Uncontrolled public organization - ${organizationName}`; const publicAccessToken = this.config.github.operations.publicAccessToken; if (!publicAccessToken) { - throw CreateError.InvalidParameters('not configured for public read-only tokens'); + throw new Error('not configured for public read-only tokens'); } - const emptySettings = OrganizationSetting.CreateEmptyWithOldToken( + const org = this.createOrganization( + organizationName, + emptySettings, publicAccessToken, - `Uncontrolled public organization - ${organizationName}`, - organizationId + GitHubAppAuthenticationType.ForceSpecificInstallation ); - const org = this.createOrganization(organizationName, { - settings: emptySettings, - appAuthenticationType: GitHubAppAuthenticationType.ForceSpecificInstallation, - }); this._uncontrolledOrganizations.set(organizationName, org); org.uncontrolled = true; return org; @@ -605,14 +599,14 @@ export class Operations get organizationNamesWithAuthorizationHeaders() { if (!this._organizationNamesWithAuthorizationHeaders) { - const tokens = new Map(); + const tokens = new Map(); const visited = new Set(); for (const entry of this._organizationSettings) { const lowercase = entry.organizationName.toLowerCase(); if (entry.active && !visited.has(lowercase) && !entry.hasFeature(OrganizationFeature.Invisible)) { visited.add(lowercase); const orgInstance = this.getOrganization(lowercase); - const token = orgInstance.getAuthorizationHeader(AppPurpose.Data); + const token = orgInstance.getAuthorizationHeader(); tokens.set(lowercase, token); } } @@ -790,6 +784,10 @@ export class Operations return this.config.brand.operationsMail; } + getInfrastructureNotificationsMail(): string { + return this.config.brand.infrastructureNotificationsMail || this.getOperationsMailAddress(); + } + getLinksNotificationMailAddress(): string { return this.config.notifications.linksMailAddress || this.getOperationsMailAddress(); } @@ -887,22 +885,6 @@ export class Operations } async getRepoById(repoId: number, options?: ICacheOptions): Promise { - const { repositoryCacheProvider } = this.providers; - if (repositoryCacheProvider) { - try { - const cachedRepository = await repositoryCacheProvider.getRepository(String(repoId)); - if (cachedRepository?.organizationId) { - const organization = this.getOrganizationById(Number(cachedRepository.organizationId)); - return organization.repository(cachedRepository.repositoryName); - } - } catch (error) { - if (ErrorHelper.IsNotFound(error)) { - console.log(`Repository ${repoId} not found in the cache: ${error}`); - } else { - console.log(`Repository ${repoId} error retrieving from cache: ${error}`); - } - } - } const cacheOptions = options || { maxAgeSeconds: this.defaults.crossOrgsReposStaleSecondsPerOrg, }; @@ -924,46 +906,10 @@ export class Operations } } - async getOrganizationProfileById(id: number, options?: ICacheOptions): Promise { - options = options || {}; - if (!id) { - throw new Error('Must provide a repository ID to retrieve the repository.'); - } - const organization = this._organizationIds.get(id); - return this._getOrganizationProfileById(id, organization ? id : null, options); - } - - async getOrganizationPublicProfileById( + async getOrganizationProfileById( id: number, options?: ICacheOptions - ): Promise { - options = options || {}; - if (!id) { - throw new Error('Must provide a repository ID to retrieve the repository.'); - } - let lookupId: number | null = this._organizationIds.get(id) ? id : null; - if (lookupId) { - const allIdsExcludingOrg = this.getOrganizationIds().filter((orgId) => orgId !== id); - const shuffledIds = shuffle(allIdsExcludingOrg); - if (shuffledIds.length > 0) { - lookupId = shuffledIds[0]; - } - } - if (lookupId === null) { - throw CreateError.InvalidParameters( - 'This approach requires configuring at least two organizations (getOrganizationPublicProfileById).' - ); - } - return this._getOrganizationProfileById(id, lookupId, options); - } - - private async _getOrganizationProfileById( - id: number, - lookupUsingIdOrCentralToken: number | null, - options?: ICacheOptions - ): Promise { - // EMU note: you need to use an EMU-installed app vs public... - // Cache note: this will be a cache miss if you switch between public/non-public entrypoints + ): Promise { options = options || {}; if (!id) { throw new Error('Must provide a repository ID to retrieve the repository.'); @@ -977,15 +923,13 @@ export class Operations if (options.backgroundRefresh !== undefined) { cacheOptions.backgroundRefresh = options.backgroundRefresh; } - const organization = this._organizationIds.get(lookupUsingIdOrCentralToken); - let header: GetAuthorizationHeader = null; - if (organization) { - header = organization.getAuthorizationHeader(AppPurpose.Data) as GetAuthorizationHeader; - } else { - header = this.getPublicAuthorizationToken(); - } try { - const entity = await this.github.request(header, 'GET /organizations/:id', parameters, cacheOptions); + const entity = await this.github.request( + this.getCentralOperationsToken(), + 'GET /organizations/:id', + parameters, + cacheOptions + ); return entity; } catch (error) { if (error.status && error.status === 404) { @@ -1298,17 +1242,11 @@ export class Operations // Eventually link/unlink should move from context into operations here to centralize more than just the events - async fireLinkEvent(value: LinkEvent): Promise { - const companySpecific = getCompanySpecificDeployment(); - companySpecific?.events?.linking?.onLink && companySpecific.events.linking.onLink(this.providers, value); + async fireLinkEvent(value): Promise { await fireEvent(this.config, 'link', value); } - async fireUnlinkEvent(value: UnlinkEvent): Promise { - const corporateId = value?.aad?.id; - const companySpecific = getCompanySpecificDeployment(); - companySpecific?.events?.linking?.onUnlink && - companySpecific.events.linking.onUnlink(this.providers, corporateId); + async fireUnlinkEvent(value): Promise { await fireEvent(this.config, 'unlink', value); } @@ -1341,32 +1279,19 @@ export class Operations return false; } - getPublicReadOnlyStaticToken(): GetAuthorizationHeader { - const { config } = this.providers; - if (config?.github?.operations?.publicAccessToken) { - const capturedToken = config.github.operations.publicAccessToken; - return async () => { - return { - value: `token ${capturedToken}`, - purpose: null, - source: 'public read-only token', - }; - }; - } - throw CreateError.InvalidParameters('No configured read-only static token'); + getCentralOperationsToken(): IGetAuthorizationHeader { + const func = getCentralOperationsAuthorizationHeader.bind(null, this) as IGetAuthorizationHeader; + return func; } - getPublicAuthorizationToken(): GetAuthorizationHeader { - try { - return this._tokenManager.getAuthorizationHeaderForAnyApp.bind(this._tokenManager); - } catch (error) { - return this.getPublicReadOnlyStaticToken(); - } + getPublicReadOnlyToken(): IGetAuthorizationHeader { + const func = getReadOnlyAuthorizationHeader.bind(null, this) as IGetAuthorizationHeader; + return func; } getAccount(id: string) { const entity = { id }; - return new Account(entity, this, this.getPublicAuthorizationToken.bind(this)); + return new Account(entity, this, getCentralOperationsAuthorizationHeader.bind(null, this)); } async getAccountWithDetailsAndLink(id: string): Promise { @@ -1375,27 +1300,14 @@ export class Operations } async getAuthenticatedAccount(token: string): Promise { - // Returns an account instance based on the account identified in the token. const github = this.github; const parameters = {}; - const fullToken = `token ${token}`; - let tokenType: GitHubTokenType = null; try { - tokenType = getGitHubTokenTypeFromValue(fullToken); - } catch (error) { - // ignoring any issue here on identifying the type of token - } - try { - const entity = await github.post(fullToken, 'users.getAuthenticated', parameters); - const account = new Account(entity, this, this.getPublicAuthorizationToken.bind(this)); + const entity = await github.post(`token ${token}`, 'users.getAuthenticated', parameters); + const account = new Account(entity, this, getCentralOperationsAuthorizationHeader.bind(null, this)); return account; } catch (error) { - throw wrapError( - error, - `Could not get details about the authenticated account${ - tokenType ? ' using token type "' + tokenType + '"' : '.' - }` - ); + throw wrapError(error, 'Could not get details about the authenticated account'); } } @@ -1509,6 +1421,42 @@ async function fireEvent(config, configurationName, value): Promise { + return { + value: `token ${capturedToken}`, + purpose: null, + source: 'public read-only token', + }; + }; + } else { + throw new Error('No public read-only token configured.'); + } +} + +export function getCentralOperationsAuthorizationHeader(self: Operations): IPurposefulGetAuthorizationHeader { + const s = (self || this) as Operations; + if (s.config.github && s.config.github.operations && s.config.github.operations.centralOperationsToken) { + const capturedToken = s.config.github.operations.centralOperationsToken; + return async () => { + return { + value: `token ${capturedToken}`, + purpose: null, // legacy + source: 'central operations token', + }; + }; + } else if (s.getOrganizations().length === 0) { + throw new Error('No central operations token nor any organizations configured.'); + } + // Fallback to the first configured organization as a convenience + // CONSIDER: would randomizing the organization be better, or a priority based on known-rate limit remaining? + const firstOrganization = s.getOrganizations()[0]; + return firstOrganization.getAuthorizationHeader(); +} + function crossOrganizationResults(operations: Operations, results, keyProperty) { keyProperty = keyProperty || 'id'; const map: IMapPlusMetaCost = new Map(); diff --git a/business/operations/link.ts b/business/operations/link.ts index d4a269857..b41e2a6c2 100644 --- a/business/operations/link.ts +++ b/business/operations/link.ts @@ -12,7 +12,7 @@ import { ICorporateLink, } from '../../interfaces'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import { CreateError, ErrorHelper, setImmediateAsync } from '../../lib/transitional'; +import { CreateError, ErrorHelper, setImmediateAsync } from '../../transitional'; export async function linkAccounts( operations: Operations, diff --git a/business/operations/unlinkMail.ts b/business/operations/unlinkMail.ts index 50522e05f..78d4601d9 100644 --- a/business/operations/unlinkMail.ts +++ b/business/operations/unlinkMail.ts @@ -7,7 +7,7 @@ import { Operations } from '.'; import { Account } from '../account'; import { UnlinkPurpose, IUnlinkMailStatus, ICachedEmployeeInformation } from '../../interfaces'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import { assertUnreachable } from '../../lib/transitional'; +import { assertUnreachable } from '../../transitional'; export async function sendTerminatedAccountMail( operations: Operations, @@ -64,7 +64,7 @@ export async function sendTerminatedAccountMail( break; case UnlinkPurpose.Termination: subjectPrefix = '[UNLINKED] '; - headline = `${displayName} has had their GitHub access offboarded`; + headline = `${displayName} is not an active employee`; break; case UnlinkPurpose.Unknown: default: diff --git a/business/organization.ts b/business/organization.ts index ef8fa2b65..b25945d04 100644 --- a/business/organization.ts +++ b/business/organization.ts @@ -10,30 +10,29 @@ import { OrganizationMember } from './organizationMember'; import { Team } from './team'; import { Repository } from './repository'; -import { wrapError } from '../lib/utils'; +import { wrapError } from '../utils'; import { StripGitHubEntity } from '../lib/github/restApi'; import { GitHubResponseType } from '../lib/github/endpointEntities'; -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { AppPurpose, AppPurposeTypes } from './githubApps'; import { OrganizationFeature, OrganizationSetting, - SystemTeam, -} from './entities/organizationSettings/organizationSetting'; -import { createOrganizationSudoInstance, IOrganizationSudo } from './features'; + SpecialTeam, +} from '../entities/organizationSettings/organizationSetting'; +import { createOrganizationSudoInstance, IOrganizationSudo } from '../features'; import { CacheDefault, getMaxAgeSeconds, getPageSize, OperationsCore } from './operations/core'; import { CoreCapability, GitHubAuditLogEntry, - GitHubOrganizationInvite, GitHubRepositoryVisibility, IAccountBasics, IAddOrganizationMembershipOptions, - AuthorizationHeaderValue, + IAuthorizationHeaderValue, ICacheOptions, ICacheOptionsWithPurpose, ICorporateLink, ICreateRepositoryResult, - type GetAuthorizationHeader, + IGetAuthorizationHeader, IGetOrganizationAuditLogOptions, IGetOrganizationMembersOptions, IGitHubAccountDetails, @@ -49,7 +48,7 @@ import { IOrganizationMemberPair, IOrganizationMembership, IPagedCacheOptions, - type PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, IReposError, IReposRestRedisCacheCost, NoCacheNoBackground, @@ -59,17 +58,14 @@ import { OrganizationMembershipTwoFactorFilter, throwIfNotCapable, throwIfNotGitHubCapable, - GitHubRepositoryDetails, } from '../interfaces'; -import { CreateError, ErrorHelper } from '../lib/transitional'; +import { CreateError, ErrorHelper } from '../transitional'; import { jsonError } from '../middleware'; import getCompanySpecificDeployment from '../middleware/companySpecificDeployment'; import { ConfigGitHubTemplates } from '../config/github.templates.types'; -import { GitHubTokenManager } from '../lib/github/tokenManager'; +import { GitHubTokenManager } from './githubApps/tokenManager'; import { OrganizationProjects } from './projects'; import { OrganizationDomains } from './domains'; -import { OrganizationCopilot } from './organizationCopilot'; -import { OrganizationProperties } from './organizationProperties'; interface IGetMembersParameters { org: string; @@ -105,7 +101,7 @@ export interface IGitHubOrganizationPlanResponse { space: number; } -export type GitHubOrganizationResponse = { +export interface IGitHubOrganizationResponse { avatar_url?: string; billing_email?: string; blog?: string; @@ -139,73 +135,8 @@ export type GitHubOrganizationResponse = { type: string; updated_at: string; url: string; -}; - -// the only fields we want in this type based on GitHubOrganizationResponse are avatar_url, blog, company, created_at, description, email, id, location, login, name, updated_at -export type GitHubOrganizationResponseSanitized = Pick< - GitHubOrganizationResponse, - | 'avatar_url' - | 'blog' - | 'company' - | 'created_at' - | 'description' - | 'email' - | 'id' - | 'location' - | 'login' - | 'name' - | 'updated_at' ->; - -const sanitizedFields = [ - 'avatar_url', - 'blog', - 'company', - 'created_at', - 'description', - 'email', - 'id', - 'location', - 'login', - 'name', - 'updated_at', -]; - -export function getOrganizationDetailsSanitized( - details: GitHubOrganizationResponse -): GitHubOrganizationResponseSanitized { - if (details) { - const sanitized = {} as GitHubOrganizationResponseSanitized; - for (const field of sanitizedFields) { - if (details[field]) { - sanitized[field] = details[field]; - } - } - return sanitized; - } } -export interface RunnerData { - busy: boolean; - id: number; - name: string; - os: string; - status: string; - labels: { - id: number; - name: string; - type: string; - }; -} - -export interface IGitHubOrganizationRunners { - total_count: number; - runners: RunnerData[]; -} -type CreateRepositoryEntityById = Partial & Pick; -type CreateRepositoryEntityByName = Partial & Pick; -type CreateRepositoryEntity = CreateRepositoryEntityById | CreateRepositoryEntityByName; - export class Organization { private _name: string; private _baseUrl: string; @@ -213,21 +144,18 @@ export class Organization { private _nativeManagementUrl: string; private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _usesGitHubApp: boolean; private _settings: OrganizationSetting; - private _entity: GitHubOrganizationResponse; + private _entity: IGitHubOrganizationResponse; private _organizationSudo: IOrganizationSudo; private _projects: OrganizationProjects; private _domains: OrganizationDomains; - private _copilot: OrganizationCopilot; - private _customProperties: OrganizationProperties; - id: number; uncontrolled: boolean; @@ -235,8 +163,8 @@ export class Organization { operations: IOperationsInstance, name: string, settings: OrganizationSetting, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, public hasDynamicSettings: boolean ) { this._name = settings.organizationName || name; @@ -323,7 +251,7 @@ export class Organization { ); } - return values as object; + return values; } getManagementApproach() { @@ -360,28 +288,6 @@ export class Organization { return this._projects; } - get copilot() { - if (!this._copilot) { - this._copilot = new OrganizationCopilot( - this, - this._getSpecificAuthorizationHeader.bind(this), - this._operations - ); - } - return this._copilot; - } - - get customProperties() { - if (!this._customProperties) { - this._customProperties = new OrganizationProperties( - this, - this._getSpecificAuthorizationHeader.bind(this), - this._operations - ); - } - return this._customProperties; - } - get domains() { if (!this._domains) { this._domains = new OrganizationDomains( @@ -419,7 +325,7 @@ export class Organization { return tokenManager.getRateLimitInformation(purpose, this); } - repository(name: string, optionalEntity?: CreateRepositoryEntity) { + repository(name: string, optionalEntity?) { const entity = Object.assign({}, optionalEntity || {}, { name, }); @@ -450,24 +356,15 @@ export class Organization { cacheOptions.backgroundRefresh = options.backgroundRefresh; } try { - let entity: any = null; - if ((cacheOptions as any)?.noConditionalRequests === true) { - entity = await operations.github.requestAsPost( - this.authorize(AppPurpose.Data), - 'GET /repositories/:id', - parameters - ); - } else { - entity = await operations.github.request( - this.authorize(AppPurpose.Data), - 'GET /repositories/:id', - parameters, - cacheOptions - ); - } + const entity = await operations.github.request( + this.authorize(AppPurpose.Data), + 'GET /repositories/:id', + parameters, + cacheOptions + ); if (entity.owner.id !== this.id) { throw CreateError.NotFound( - `Repository ID ${id} has a different owner of ${entity.owner.login} instead of ${this.name}. It has been relocated and will be treated as a 404.` + `Repository ID ${parameters.id} has a different owner of ${entity.owner.login} instead of ${this.name}. It has been relocated and will be treated as a 404.` ); } return this.repositoryFromEntity(entity); @@ -514,29 +411,6 @@ export class Organization { return repositories; } - async getOrgRunners(options?: ICacheOptions): Promise { - options = options || {}; - const operations = throwIfNotGitHubCapable(this._operations); - const github = operations.github; - const orgName = this.name; - const parameters = { - orgName, - }; - const cacheOptions: ICacheOptions = { - maxAgeSeconds: 1, // getMaxAgeSeconds(operations, CacheDefault.accountDetailStaleSeconds, options), - }; - const runnerData = await operations.github.request( - this.authorize(AppPurpose.ActionsData), - 'GET /orgs/:orgName/actions/runners', - parameters, - cacheOptions - ); - return { - runners: runnerData.runners, - total_count: runnerData.total_count, - }; - } - get priority(): string { return this._settings.properties['priority'] || 'secondary'; } @@ -553,6 +427,10 @@ export class Organization { return this._settings.hasFeature(OrganizationFeature.Hidden) || false; } + get pilot_program() { + return this._settings.properties['1es']; + } + get createRepositoriesOnGitHub(): boolean { return this._settings.hasFeature(OrganizationFeature.CreateNativeRepositories) || false; } @@ -594,11 +472,7 @@ export class Organization { } get broadAccessTeams(): number[] { - return this.getSystemTeam(SystemTeam.Everyone, 'everyone membership'); - } - - get openAccessTeams(): number[] { - return this.getSystemTeam(SystemTeam.OpenAccess, 'open access'); + return this.getSpecialTeam(SpecialTeam.Everyone, 'everyone membership'); } get invitationTeam(): Team { @@ -610,7 +484,7 @@ export class Organization { } get systemSudoersTeam(): Team { - const teams = this.getSystemTeam(SystemTeam.GlobalSudo, 'system sudoers'); + const teams = this.getSpecialTeam(SpecialTeam.GlobalSudo, 'system sudoers'); if (teams.length > 1) { throw new Error('Multiple system sudoer teams are not supported.'); } @@ -622,7 +496,7 @@ export class Organization { } get sudoersTeam(): Team { - const teams = this.getSystemTeam(SystemTeam.Sudo, 'organization sudoers'); + const teams = this.getSpecialTeam(SpecialTeam.Sudo, 'organization sudoers'); if (teams.length > 1) { throw new Error('Multiple sudoer teams are not supported.'); } @@ -636,16 +510,16 @@ export class Organization { return this._settings; } - get specialSystemTeams() { + get specialRepositoryPermissionTeams() { return { - read: this.getSystemTeam(SystemTeam.SystemRead, 'read everything'), - write: this.getSystemTeam(SystemTeam.SystemWrite, 'write everything'), - admin: this.getSystemTeam(SystemTeam.SystemAdmin, 'administer everything'), + read: this.getSpecialTeam(SpecialTeam.SystemRead, 'read everything'), + write: this.getSpecialTeam(SpecialTeam.SystemWrite, 'write everything'), + admin: this.getSpecialTeam(SpecialTeam.SystemAdmin, 'administer everything'), }; } - getAuthorizationHeader(purpose: AppPurposeTypes): PurposefulGetAuthorizationHeader { - return purpose ? this._getAuthorizationHeader.bind(this, purpose) : this._getAuthorizationHeader; + getAuthorizationHeader(): IPurposefulGetAuthorizationHeader { + return this._getAuthorizationHeader; } async getUserDetailsByLogin(login: string, purpose?: AppPurposeTypes): Promise { @@ -718,13 +592,7 @@ export class Organization { teamIds.push(broadAccessTeams[i]); // is the actual ID, not the team object } } - const openAccessTeams = this.openAccessTeams; - if (openAccessTeams) { - for (let i = 0; i < openAccessTeams.length; i++) { - teamIds.push(openAccessTeams[i]); // is the actual ID, not the team object - } - } - const specialTeams = this.specialSystemTeams; + const specialTeams = this.specialRepositoryPermissionTeams; const keys = Object.getOwnPropertyNames(specialTeams); keys.forEach((type) => { const values = specialTeams[type]; @@ -757,12 +625,12 @@ export class Organization { ); } - async getRepositoryCreateGitHubToken(): Promise { + async getRepositoryCreateGitHubToken(): Promise { // This method leaks/releases the owner token. In the future a more crisp // way of accomplishing this without exposing the token should be created. // The function name is specific to the intended use instead of a general- // purpose token name. - const token = await (this.authorize(AppPurpose.Operations) as GetAuthorizationHeader)(); + const token = await (this.authorize(AppPurpose.Operations) as IGetAuthorizationHeader)(); token.source = 'repository create token'; return token; } @@ -806,7 +674,7 @@ export class Organization { } } - async getDetails(): Promise { + async getDetails(): Promise { const operations = throwIfNotGitHubCapable(this._operations); const parameters = { org: this.name, @@ -817,7 +685,7 @@ export class Organization { this.id = entity.id; } this._entity = entity; - return entity as GitHubOrganizationResponse; + return entity as IGitHubOrganizationResponse; } catch (error) { throw wrapError(error, `Could not get details about the ${this.name} organization: ${error.message}`); } @@ -842,42 +710,6 @@ export class Organization { return metadata; } - async getTeamById(id: number, options?: ICacheOptions): Promise { - options = options || {}; - const operations = throwIfNotGitHubCapable(this._operations); - const cacheOptions = { - maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgTeamDetailsStaleSeconds, options), - backgroundRefresh: false, - }; - if (options.backgroundRefresh !== undefined) { - cacheOptions.backgroundRefresh = options.backgroundRefresh; - } - const orgId = this.id; - if (!orgId) { - throw CreateError.InvalidParameters('The organization ID is not available.'); - } - const parameters = { - org_id: orgId, - team_id: id, - }; - try { - const entity = await operations.github.request( - this.authorize(AppPurpose.Data), - 'GET /organizations/:org_id/team/:team_id', - parameters, - cacheOptions - ); - return this.teamFromEntity(entity); - } catch (error) { - if (error.status && error.status === 404) { - throw CreateError.NotFound( - `The GitHub team with the ID ${id} could not be found for organization ${this.name} with ID ${orgId}.` - ); - } - throw error; - } - } - async getTeamFromSlug(slug: string, options?: ICacheOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this._operations); @@ -1294,7 +1126,7 @@ export class Organization { const getAuthorizationHeader = this._getAuthorizationHeader.bind( this, AppPurpose.Data - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; const github = operations.github; const parameters: IGetMembersParameters = { org: this.name, @@ -1409,7 +1241,7 @@ export class Organization { const getAuthorizationHeader = this._getAuthorizationHeader.bind( this, AppPurpose.Data - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; const teamEntities = await github.collections.getOrgTeams(getAuthorizationHeader, parameters, caching); const teams = common.createInstances(this, this.teamFromEntity, teamEntities); return teams; @@ -1435,12 +1267,12 @@ export class Organization { if (queryCache?.supportsOrganizationMembership) { try { if (!optionalId) { - const ops = operationsWithCapability( + const centralOps = operationsWithCapability( operations, CoreCapability.GitHubCentralOperations ); - if (ops) { - const account = await ops.getAccountByUsername(login); + if (centralOps) { + const account = await centralOps.getAccountByUsername(login); optionalId = account.id.toString(); } } @@ -1452,7 +1284,7 @@ export class Organization { } } - async getMembershipInvitations(): Promise { + async getMembershipInvitations(): Promise { const operations = throwIfNotGitHubCapable(this._operations); const parameters = { org: this.name, @@ -1463,7 +1295,7 @@ export class Organization { 'orgs.listPendingInvitations', parameters ); - return invitations as GitHubOrganizationInvite[]; + return invitations; } catch (error) { if (error.status == /* loose */ 404) { return null; @@ -1472,16 +1304,19 @@ export class Organization { } } - private authorize(purpose: AppPurpose): GetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose): IGetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } @@ -1613,7 +1448,7 @@ export class Organization { return this.team(entity.id, entity); } - repositoryFromEntity(entity: CreateRepositoryEntity): Repository { + repositoryFromEntity(entity): Repository { return this.repository(entity.name, entity); } @@ -1623,15 +1458,23 @@ export class Organization { return { settings, operations }; } - private getSystemTeam(teamType: SystemTeam, friendlyName: string, throwIfMissing?: boolean): number[] { - const allOrgSystemTeams = this._settings.specialTeams; - const matchingSystemTeamTypes = allOrgSystemTeams.filter((t) => t.specialTeam === teamType); - const teams: number[] = matchingSystemTeamTypes.map((t) => t.teamId); - if (throwIfMissing && teams.length === 0) { + private getSpecialTeam(specialTeam: SpecialTeam, friendlyName: string, throwIfMissing?: boolean): number[] { + let teamId: number = null; + for (const entry of this._settings.specialTeams) { + if (entry.specialTeam === specialTeam) { + teamId = entry.teamId; + break; + } + } + if (throwIfMissing) { throw new Error( - `Missing configured organization "${this.name}" special team ${teamType} - ${friendlyName}` + `Missing configured organization "${this.name}" special team ${specialTeam} - ${friendlyName}` ); } + const teams: number[] = []; + if (teamId) { + teams.push(teamId); + } return teams; } diff --git a/business/organizationCopilot.ts b/business/organizationCopilot.ts deleted file mode 100644 index 8081ba09f..000000000 --- a/business/organizationCopilot.ts +++ /dev/null @@ -1,126 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { - GetAuthorizationHeader, - ICacheOptions, - IOperationsInstance, - IPagedCacheOptions, - PurposefulGetAuthorizationHeader, - throwIfNotGitHubCapable, -} from '../interfaces'; -import type { CollectionCopilotSeatsOptions } from '../lib/github/collections'; -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; -import { CacheDefault, getMaxAgeSeconds, getPageSize, symbolizeApiResponse } from './operations/core'; -import { Organization } from './organization'; -import { HttpMethod } from '../lib/github'; - -export type CopilotSeatData = { - assignee: { - avatar_url: string; - id: number; - login: string; - }; - created_at: string; - updated_at: string; - last_activity_at: string; - last_activity_editor: string; -}; - -export type CopilotDailyBreakdown = { - language: string; - editor: string; - suggestions_count: number; - acceptances_count: number; - lines_suggested: number; - lines_accepted: number; - active_users: number; -}; - -export type CopilotDailySummary = { - day: string; - total_suggestions_count: number; - total_acceptances_count: number; - total_lines_suggested: number; - total_lines_accepted: number; - total_active_users: number; - breakdown: CopilotDailyBreakdown[]; -}; - -export type OrganizationCopilotSummary = CopilotDailySummary[]; - -export class OrganizationCopilot { - constructor( - private organization: Organization, - private getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, - private operations: IOperationsInstance - ) {} - - async getSeatActivity( - options?: IPagedCacheOptions, - appPurpose: AppPurposeTypes = AppPurpose.Data - ): Promise { - options = options || {}; - const operations = throwIfNotGitHubCapable(this.operations); - const getAuthorizationHeader = this.getSpecificAuthorizationHeader.bind( - this, - appPurpose - ) as GetAuthorizationHeader; - const github = operations.github; - const parameters: CollectionCopilotSeatsOptions = { - org: this.organization.name, - per_page: getPageSize(operations), - }; - const caching = { - maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgMembersStaleSeconds, options), - backgroundRefresh: true, - pageRequestDelay: options.pageRequestDelay, - }; - if (options && options.backgroundRefresh === false) { - caching.backgroundRefresh = false; - } - // (caching as any).pageLimit = 10; - const seats = (await github.collections.getOrganizationCopilotSeats( - getAuthorizationHeader, - parameters, - caching - )) as CopilotSeatData[]; - return seats; - } - - async getDailyActivitySummary( - options?: ICacheOptions, - appPurpose: AppPurposeTypes = AppPurpose.Data - ): Promise { - options = options || {}; - const operations = throwIfNotGitHubCapable(this.operations); - const getAuthorizationHeader = this.getSpecificAuthorizationHeader.bind( - this, - appPurpose - ) as GetAuthorizationHeader; - const github = operations.github; - const parameters = { - org: this.organization.name, - }; - const caching = { - maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgMembersStaleSeconds, options), - backgroundRefresh: true, - }; - if (options && options.backgroundRefresh === false) { - caching.backgroundRefresh = false; - } - try { - const result: OrganizationCopilotSummary = await github.request( - getAuthorizationHeader, - 'GET /orgs/:org/copilot/usage', - parameters, - caching - ); - return symbolizeApiResponse(result); - } catch (error) { - throw error; - } - } -} diff --git a/business/organizationProperties.ts b/business/organizationProperties.ts deleted file mode 100644 index 36080e05b..000000000 --- a/business/organizationProperties.ts +++ /dev/null @@ -1,198 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { - ICacheOptions, - ICacheOptionsWithPurpose, - GetAuthorizationHeader, - IOperationsInstance, - PurposefulGetAuthorizationHeader, - PagedCacheOptionsWithPurpose, - throwIfNotGitHubCapable, -} from '../interfaces'; -import { HttpMethod } from '../lib/github'; -import { CreateError } from '../lib/transitional'; -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; -import { - CacheDefault, - createPagedCacheOptions, - getMaxAgeSeconds, - getPageSize, - popPurpose, - symbolizeApiResponse, -} from './operations/core'; -import { Organization } from './organization'; - -export enum CustomPropertyValueType { - String = 'string', - SingleSelect = 'single_select', -} - -export type OrganizationCustomPropertyEntity = { - property_name: string; - value_type: CustomPropertyValueType; - required: boolean; - description?: string; - default_value?: string; - allowed_values?: string[]; -}; - -export type OrganizationCustomPropertySetPropertyValue = { - property_name: string; - value: string; -}; - -type CreateOrUpdateResponse = { - properties: OrganizationCustomPropertyEntity[]; -}; - -export class OrganizationProperties { - private _defaultPurpose = AppPurpose.Data; - - constructor( - private organization: Organization, - private getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, - private operations: IOperationsInstance - ) {} - - private authorize(purpose: AppPurposeTypes): GetAuthorizationHeader | string { - const getAuthorizationHeader = this.getSpecificAuthorizationHeader.bind( - this, - purpose - ) as GetAuthorizationHeader; - return getAuthorizationHeader; - } - - async getCustomProperties( - options?: PagedCacheOptionsWithPurpose - ): Promise { - options = options || {}; - const operations = throwIfNotGitHubCapable(this.operations); - const { github } = operations; - const purpose = popPurpose(options, this._defaultPurpose); - const parameters = { - org: this.organization.name, - per_page: getPageSize(operations), - }; - const cacheOptions = createPagedCacheOptions(operations, options); - try { - const entities = await github.collections.collectAllPagesViaHttpGet< - any, - OrganizationCustomPropertyEntity - >( - this.authorize(purpose), - 'orgCustomProps', - 'GET /orgs/:org/properties/schema', - parameters, - cacheOptions - ); - return symbolizeApiResponse(entities); - } catch (error) { - throw error; - } - } - - async getCustomProperty( - propertyName: string, - options?: ICacheOptionsWithPurpose - ): Promise { - options = options || {}; - const operations = throwIfNotGitHubCapable(this.operations); - const { github } = operations; - if (!propertyName) { - throw CreateError.InvalidParameters('propertyName'); - } - const purpose = popPurpose(options, this._defaultPurpose); - const parameters = { - org: this.organization.name, - custom_property_name: propertyName, - }; - const cacheOptions: ICacheOptions = { - maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.accountDetailStaleSeconds, options, 60), - }; - if (options.backgroundRefresh !== undefined) { - cacheOptions.backgroundRefresh = options.backgroundRefresh; - } - try { - const entity = (await github.request( - this.authorize(purpose), - 'GET /orgs/:org/properties/schema/:custom_property_name', - parameters, - cacheOptions - )) as OrganizationCustomPropertyEntity; - return symbolizeApiResponse(entity); - } catch (error) { - throw error; - } - } - - async deleteProperty(propertyName: string, purpose?: AppPurposeTypes): Promise { - const operations = throwIfNotGitHubCapable(this.operations); - const parameters = { - org: this.organization.name, - custom_property_name: propertyName, - }; - await operations.github.restApi( - this.authorize(purpose || this._defaultPurpose), - HttpMethod.Delete, - '/orgs/:org/properties/schema/:custom_property_name', - parameters - ); - } - - async createOrUpdate( - properties: OrganizationCustomPropertyEntity[], - purpose?: AppPurposeTypes - ): Promise { - const operations = throwIfNotGitHubCapable(this.operations); - const parameters = { - org: this.organization.name, - properties, - }; - const res = (await operations.github.restApi( - this.authorize(purpose || this._defaultPurpose), - HttpMethod.Patch, - '/orgs/:org/properties/schema', - parameters - )) as CreateOrUpdateResponse; - return res.properties; - } - - async createOrUpdateRepositoriesProperties( - organizationRepositoryNames: string[], - propertiesAndValues: Record, - purpose?: AppPurposeTypes - ): Promise { - const operations = throwIfNotGitHubCapable(this.operations); - if (organizationRepositoryNames.length > 30) { - throw CreateError.InvalidParameters( - 'GitHub has a hard limit of 30 repositories to update in a single patch' - ); - } - const parameters = { - org: this.organization.name, - properties: setPropertiesRecordToArray(propertiesAndValues), - repository_names: organizationRepositoryNames, - }; - (await operations.github.restApi( - this.authorize(purpose || this._defaultPurpose), - HttpMethod.Patch, - '/orgs/:org/properties/values', - parameters - )) as CreateOrUpdateResponse; - } -} - -function setPropertiesRecordToArray(propertiesAndValues: Record) { - const keys = Object.getOwnPropertyNames(propertiesAndValues); - const properties: OrganizationCustomPropertySetPropertyValue[] = []; - for (const key of keys) { - properties.push({ - property_name: key, - value: propertiesAndValues[key], - }); - } - return properties; -} diff --git a/business/project.ts b/business/project.ts index 54571be82..e1fb54c80 100644 --- a/business/project.ts +++ b/business/project.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { AppPurpose, AppPurposeTypes } from './githubApps'; import { Organization, Repository } from '.'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, throwIfNotGitHubCapable, - GetAuthorizationHeader, + IGetAuthorizationHeader, } from '../interfaces'; import { decorateIterable, @@ -17,7 +17,7 @@ import { IteratorResponse, PaginationPageSizeOptions, } from './iterable'; -import { CreateError, DefaultGraphqlPageSize } from '../lib/transitional'; +import { CreateError, DefaultGraphqlPageSize } from '../transitional'; import { OrganizationProjects } from './projects'; import { OrganizationProjectView } from './projectView'; @@ -117,8 +117,8 @@ export class OrganizationProject { private _projects: OrganizationProjects; private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _purpose: AppPurpose; private _id: string; @@ -126,8 +126,8 @@ export class OrganizationProject { constructor( organizationProjects: OrganizationProjects, operations: IOperationsInstance, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, projectId: string ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -413,16 +413,19 @@ export class OrganizationProject { } } - private authorize(purpose: AppPurpose = this._purpose): GetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose = this._purpose): IGetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/projectView.ts b/business/projectView.ts index b4386b4ec..0ab645ae8 100644 --- a/business/projectView.ts +++ b/business/projectView.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { AppPurpose, AppPurposeTypes } from './githubApps'; import { Organization } from '.'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, throwIfNotGitHubCapable, - GetAuthorizationHeader, + IGetAuthorizationHeader, } from '../interfaces'; import { decorateIterable, @@ -17,7 +17,7 @@ import { IteratorResponse, PaginationPageSizeOptions, } from './iterable'; -import { DefaultGraphqlPageSize } from '../lib/transitional'; +import { DefaultGraphqlPageSize } from '../transitional'; import { OrganizationProject, ProjectViewEssentials } from './project'; type ProjectViewDetails = { @@ -30,8 +30,8 @@ export class OrganizationProjectView { private _project: OrganizationProject; private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _purpose: AppPurpose; private _id: string; @@ -41,8 +41,8 @@ export class OrganizationProjectView { constructor( organizationProject: OrganizationProject, operations: IOperationsInstance, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, projectId: string, essentials?: ProjectViewEssentials ) { @@ -217,16 +217,19 @@ export class OrganizationProjectView { // } // } - private authorize(purpose: AppPurpose = this._purpose): GetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose = this._purpose): IGetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/projects.ts b/business/projects.ts index 60cc6b8e6..f010b3aaa 100644 --- a/business/projects.ts +++ b/business/projects.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { AppPurpose, AppPurposeTypes } from './githubApps'; import { Organization } from '.'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, throwIfNotGitHubCapable, - GetAuthorizationHeader, + IGetAuthorizationHeader, } from '../interfaces'; import { decorateIterable, @@ -17,7 +17,7 @@ import { IteratorResponse, PaginationPageSizeOptions, } from './iterable'; -import { DefaultGraphqlPageSize } from '../lib/transitional'; +import { DefaultGraphqlPageSize } from '../transitional'; import { OrganizationProject } from './project'; type ProjectResponse = { @@ -35,15 +35,15 @@ export class OrganizationProjects { private _organization: Organization; private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _purpose: AppPurpose; constructor( organization: Organization, operations: IOperationsInstance, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader ) { this._getAuthorizationHeader = getAuthorizationHeader; this._getSpecificAuthorizationHeader = getSpecificAuthorizationHeader; @@ -134,16 +134,19 @@ export class OrganizationProjects { } } - private authorize(purpose: AppPurpose = this._purpose): GetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose = this._purpose): IGetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/queryCache.ts b/business/queryCache.ts index d1610530d..03c586097 100644 --- a/business/queryCache.ts +++ b/business/queryCache.ts @@ -16,15 +16,15 @@ import Debug from 'debug'; -import { projectCollaboratorPermissionToGitHubRepositoryPermission } from '../lib/transitional'; -import { OrganizationMemberCacheEntity } from './entities/organizationMemberCache/organizationMemberCache'; +import { MassagePermissionsToGitHubRepositoryPermission } from '../transitional'; +import { OrganizationMemberCacheEntity } from '../entities/organizationMemberCache/organizationMemberCache'; import { Operations } from './operations'; -import { TeamMemberCacheEntity } from './entities/teamMemberCache/teamMemberCache'; +import { TeamMemberCacheEntity } from '../entities/teamMemberCache/teamMemberCache'; -import { TeamCacheEntity } from './entities/teamCache/teamCache'; -import { RepositoryTeamCacheEntity } from './entities/repositoryTeamCache/repositoryTeamCache'; -import { RepositoryCacheEntity } from './entities/repositoryCache/repositoryCache'; -import { RepositoryCollaboratorCacheEntity } from './entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; +import { TeamCacheEntity } from '../entities/teamCache/teamCache'; +import { RepositoryTeamCacheEntity } from '../entities/repositoryTeamCache/repositoryTeamCache'; +import { RepositoryCacheEntity } from '../entities/repositoryCache/repositoryCache'; +import { RepositoryCollaboratorCacheEntity } from '../entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; import { Repository } from '.'; import { IProviders, @@ -665,10 +665,9 @@ export default class QueryCache { try { const organization = this.operations.getOrganizationById(Number(cacheEntity.organizationId)); const team = organization.team(Number(cacheEntity.teamId)); - const idAsStringOrNumber = cacheEntity.repositoryId; - const repositoryIdAsNumber = Number(idAsStringOrNumber); + const iid = cacheEntity.repositoryId; const repository = organization.repository(cacheEntity.repositoryName, { - id: repositoryIdAsNumber, + id: cacheEntity.repositoryId, // a string version of repositoryId FYI private: cacheEntity.repositoryPrivate, }); return { @@ -836,8 +835,9 @@ export default class QueryCache { this.throwMethodNotSupported('repositoryCollaborators', 'repositoryCollaboratorCacheProvider'); } const repositoryCollaboratorCacheProvider = this._providers.repositoryCollaboratorCacheProvider; - const rawEntities = - await repositoryCollaboratorCacheProvider.queryCollaboratorsByRepositoryId(repositoryId); + const rawEntities = await repositoryCollaboratorCacheProvider.queryCollaboratorsByRepositoryId( + repositoryId + ); return rawEntities .map((cacheEntity) => this.hydrateRepositoryCollaborator(cacheEntity)) .filter((real) => real); @@ -894,10 +894,9 @@ export default class QueryCache { cacheEntity: RepositoryCollaboratorCacheEntity ): IQueryCacheRepositoryCollaborator { const organization = this.operations.getOrganizationById(Number(cacheEntity.organizationId)); - const idAsStringOrNumber = cacheEntity.repositoryId; - const repositoryIdAsNumber = Number(idAsStringOrNumber); + const iid = cacheEntity.repositoryId; const repository = organization.repository(cacheEntity.repositoryName, { - id: repositoryIdAsNumber, + id: cacheEntity.repositoryId, private: cacheEntity.repositoryPrivate, }); // a string version of repositoryId FYI return { @@ -905,7 +904,7 @@ export default class QueryCache { affiliation: cacheEntity.collaboratorType, cacheEntity, userId: cacheEntity.userId, - permission: projectCollaboratorPermissionToGitHubRepositoryPermission(cacheEntity.permission), + permission: MassagePermissionsToGitHubRepositoryPermission(cacheEntity.permission), }; } @@ -994,8 +993,9 @@ export default class QueryCache { this.throwMethodNotSupported('organizationMembers', 'organizationMemberCacheProvider'); } const organizationMemberCacheProvider = this._providers.organizationMemberCacheProvider; - const rawEntities = - await organizationMemberCacheProvider.queryOrganizationMembersByOrganizationId(organizationId); + const rawEntities = await organizationMemberCacheProvider.queryOrganizationMembersByOrganizationId( + organizationId + ); return this.hydrateOrganizationMembers(rawEntities); } diff --git a/business/repoSearch.ts b/business/repoSearch.ts index 945e54691..310f89ec8 100644 --- a/business/repoSearch.ts +++ b/business/repoSearch.ts @@ -7,10 +7,10 @@ import querystring from 'querystring'; import { Repository } from './repository'; import { IPersonalizedUserAggregateRepositoryPermission } from './graphManager'; -import { RepositoryMetadataEntity } from './entities/repositoryMetadata/repositoryMetadata'; -import { IRepositoryMetadataProvider } from './entities/repositoryMetadata/repositoryMetadataProvider'; +import { RepositoryMetadataEntity } from '../entities/repositoryMetadata/repositoryMetadata'; +import { IRepositoryMetadataProvider } from '../entities/repositoryMetadata/repositoryMetadataProvider'; import { TeamRepositoryPermission } from './teamRepositoryPermission'; -import { sortRepositoriesByNameCaseInsensitive } from '../lib/utils'; +import { sortRepositoriesByNameCaseInsensitive } from '../utils'; import { GitHubRepositoryPermission, IRepositorySearchOptions, RepositoryLockdownState } from '../interfaces'; const defaultPageSize = 20; // GitHub.com seems to use a value around 33 diff --git a/business/repository.ts b/business/repository.ts index f213ca64d..a1e82be00 100644 --- a/business/repository.ts +++ b/business/repository.ts @@ -18,10 +18,10 @@ import { TeamMember, OrganizationMember, } from '.'; -import { RepositoryMetadataEntity } from './entities/repositoryMetadata/repositoryMetadata'; -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { RepositoryMetadataEntity } from '../entities/repositoryMetadata/repositoryMetadata'; +import { AppPurpose, AppPurposeTypes } from './githubApps'; import { - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, IOperationsInstance, ICacheOptions, throwIfNotGitHubCapable, @@ -33,7 +33,7 @@ import { ITemporaryCommandOutput, NoCacheNoBackground, IGitHubProtectedBranchConfiguration, - RepositoryBranchAccessProtections as RepositoryBranchAccessProtections, + IRepositoryBranchAccessProtections, IListContributorsOptions, IGetCollaboratorsOptions, GitHubCollaboratorAffiliationQuery, @@ -44,24 +44,19 @@ import { IGitHubSecretScanningAlert, operationsWithCapability, IOperationsServiceAccounts, - GetAuthorizationHeader, + IGetAuthorizationHeader, IRepositoryGetIssuesOptions, IOperationsRepositoryMetadataProvider, IOperationsUrls, GitHubRepositoryPermission, - GitHubRepositoryVisibility, - GitHubRepositoryDetails, } from '../interfaces'; import { IListPullsParameters, GitHubPullRequestState } from '../lib/github/collections'; -import { wrapError } from '../lib/utils'; +import { wrapError } from '../utils'; import { RepositoryActions } from './repositoryActions'; import { RepositoryPullRequest } from './repositoryPullRequest'; -import { CreateError, ErrorHelper } from '../lib/transitional'; +import { ErrorHelper } from '../transitional'; import { augmentInertiaPreview, RepositoryProject } from './repositoryProject'; -import { RepositoryInvitation } from './repositoryInvitation'; -import { RepositoryProperties } from './repositoryProperties'; -import { WithGitHubRestHeaders } from '../lib/github/core'; interface IRepositoryMoments { created?: moment.Moment; @@ -165,46 +160,6 @@ interface IUnarchiveResponse { }; } -export type GitHubBranchProtectionParameters = { - owner: string; - repo: string; - branch: string; - required_status_checks: { - strict: boolean; - contexts: string[]; - checks?: string[]; - } | null; - enforce_admins: boolean | null; - required_pull_request_reviews: { - dismissal_restrictions: { - users: string[]; - teams: string[]; - apps: string[]; - }; - dismiss_stale_reviews: boolean; - require_code_owner_reviews: boolean; - required_approving_review_count: number; - require_last_push_approval: boolean; - bypass_pull_request_allowances: { - users: string[]; - teams: string[]; - apps: string[]; - }; - } | null; - restrictions: { - users: string[]; - teams: string[]; - apps: string[]; - }; - required_linear_history: boolean; - allow_force_pushes: boolean | null; - allow_deletions: boolean; - block_creations: boolean; - required_conversation_resolution: boolean; - lock_branch: boolean; - allow_fork_syncing: boolean; -}; - export type GitHubPagesResponse = { status: string; cname: string; @@ -248,7 +203,6 @@ const safeEntityFieldsForJsonSend = [ 'stargazers_count', 'open_issues_count', 'id', - 'visibility' ]; const sortByLogin = (list) => { @@ -264,7 +218,7 @@ const sortByLogin = (list) => { }; export class Repository { - private _entity: WithGitHubRestHeaders; + private _entity: any; private _baseUrl: string; private _absoluteBaseUrl: string; private _nativeUrl: string; @@ -272,18 +226,17 @@ export class Repository { private _awesomeness: number; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _operations: IOperationsInstance; private _organization: Organization; - private _customProperties: RepositoryProperties; private _name: string; private _moments: IRepositoryMoments; - getEntity(): WithGitHubRestHeaders { + getEntity(): any { return this._entity; } @@ -317,9 +270,6 @@ export class Repository { get private(): boolean { return this._entity ? this._entity.private : false; } - get visibility(): GitHubRepositoryVisibility { - return this._entity ? this._entity.visibility : null; - } get html_url(): string { return this._entity ? this._entity.html_url : null; } @@ -335,13 +285,13 @@ export class Repository { get archived(): boolean { return this._entity ? this._entity.archived : false; } - get created_at(): string { + get created_at(): Date { return this._entity ? this._entity.created_at : null; } - get updated_at(): string { + get updated_at(): Date { return this._entity ? this._entity.updated_at : null; } - get pushed_at(): string { + get pushed_at(): Date { return this._entity ? this._entity.pushed_at : null; } get git_url(): string { @@ -425,8 +375,8 @@ export class Repository { constructor( organization: Organization, entity: any, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, operations: IOperationsInstance ) { this._organization = organization; @@ -447,17 +397,6 @@ export class Repository { this._operations = operations; } - get customProperties() { - if (!this._customProperties) { - this._customProperties = new RepositoryProperties( - this, - this._operations, - this._getSpecificAuthorizationHeader.bind(this) - ); - } - return this._customProperties; - } - get moment(): IRepositoryMoments { if (!this._moments) { this._moments = { @@ -478,17 +417,6 @@ export class Repository { }; } - async getId(options?: ICacheOptions): Promise { - // Repositories by name may not actually have the ID; this ensures it's available - // and a number. Similar to previously checking "isDeleted" or "getDetails" first. - if (!this.id) { - await this.getDetails(options); - } - if (this.id) { - return typeof this.id === 'number' ? this.id : parseInt(this.id, 10); - } - } - async isDeleted(options?: ICacheOptions): Promise { try { await this.getDetails(options); @@ -509,22 +437,12 @@ export class Repository { ); } - async getDetails(options?: ICacheOptions): Promise> { + async getDetails(options?: ICacheOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this._operations); - const cacheOptions: ICacheOptions = { - maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgRepoDetailsStaleSeconds, options), - }; - if (options.backgroundRefresh !== undefined) { - cacheOptions.backgroundRefresh = options.backgroundRefresh; - } - if ((options as any).noConditionalRequests === true) { - (cacheOptions as any).noConditionalRequests = true; - } - // always prefer ID over name - if (this.id) { + if (this.id && !this.name) { try { - const lookupById = await this.organization.getRepositoryById(this.id, cacheOptions); + const lookupById = await this.organization.getRepositoryById(this.id); this._entity = lookupById.getEntity(); this._name = this._entity.name; } catch (getByIdError) { @@ -542,8 +460,17 @@ export class Repository { if (mediaType) { (parameters as any).mediaType = mediaType; } + const cacheOptions: ICacheOptions = { + maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgRepoDetailsStaleSeconds, options), + }; + if (options.backgroundRefresh !== undefined) { + cacheOptions.backgroundRefresh = options.backgroundRefresh; + } + if ((options as any).noConditionalRequests === true) { + (cacheOptions as any).noConditionalRequests = true; + } try { - let entity: WithGitHubRestHeaders = undefined; + let entity: any = undefined; if ((cacheOptions as any)?.noConditionalRequests === true) { entity = await operations.github.post(this.authorize(AppPurpose.Data), 'repos.get', parameters); } else { @@ -831,27 +758,6 @@ export class Repository { } } - async updateBranchProtectionRule2( - parameters: GitHubBranchProtectionParameters, - cacheOptions?: ICacheOptions - ): Promise { - cacheOptions = cacheOptions || {}; - const operations = throwIfNotGitHubCapable(this._operations); - const github = operations.github; - - Object.assign(parameters, cacheOptions); - // PUT /repos/{owner}/{repo}/branches/{branch}/protection - const protections = await github.call( - this.authorize(AppPurpose.Data), - 'repos.updateBranchProtection', - parameters - ); - if (protections.length >= 100) { - console.warn('This API does not support pagination currently... there may be more items'); - } - return protections as RepositoryBranchAccessProtections; - } - async listBranchProtectionRules(): Promise { await this.organization.requireUpdatesApp('listBranchProtectionRules'); const query = `query($owner: String!, $repo: String!) { @@ -904,7 +810,7 @@ export class Repository { async getProtectedBranchAccessRestrictions( branchName: string, cacheOptions?: ICacheOptions - ): Promise { + ): Promise { // NOTE: GitHub has a "100-item limit" currently. This is an object response and not // technically paginated. cacheOptions = cacheOptions || {}; @@ -928,31 +834,7 @@ export class Repository { 'repos.getBranchProtection', parameters ); - return protections as RepositoryBranchAccessProtections; - } - - async getAdminProtectedBranchAccessRestrictions( - branchName: string, - cacheOptions?: ICacheOptions - ): Promise { - // NOTE: GitHub has a "100-item limit" currently. This is an object response and not - // technically paginated. - cacheOptions = cacheOptions || {}; - const operations = throwIfNotGitHubCapable(this._operations); - const github = operations.github; - const parameters = { - owner: this.organization.name, - repo: this.name, - branch: branchName, - }; - Object.assign(parameters, cacheOptions); - // GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins - const protections = await github.call( - this.authorize(AppPurpose.Data), - 'repos.getAdminBranchProtection', - parameters - ); - return protections as RepositoryBranchAccessProtections; + return protections as IRepositoryBranchAccessProtections; } async setDefaultBranch(defaultBranchName: string): Promise { @@ -1000,8 +882,9 @@ export class Repository { cacheOptions.backgroundRefresh = options.backgroundRefresh; } try { - // CONSIDER: need a fallback authentication approach: try and app for a specific capability - const tokenSource = this._getSpecificAuthorizationHeader(AppPurpose.Data); + // CONSIDER: need a fallback authentication approach: try and app for a specific capability (the installation knows) and fallback to central ops + // const centralOps = operationsWithCapability(operations, CoreCapability.GitHubCentralOperations); + const tokenSource = this._getSpecificAuthorizationHeader(AppPurpose.Data); // centralOps ? centralOps.getCentralOperationsToken()(AppPurpose.Data) : const token = await tokenSource; return await operations.github.call(token, 'repos.getPages', parameters, cacheOptions); } catch (error) { @@ -1173,39 +1056,6 @@ export class Repository { return collaborators; } - async listCollaboratorInvitations(cacheOptions?: IPagedCacheOptions): Promise { - cacheOptions = cacheOptions || {}; - const operations = throwIfNotGitHubCapable(this._operations); - const github = operations.github; - const parameters = { - owner: this.organization.name, - repo: this.name, - per_page: getPageSize(operations), - }; - if (!cacheOptions.maxAgeSeconds) { - cacheOptions.maxAgeSeconds = getMaxAgeSeconds( - operations, - CacheDefault.orgRepoCollaboratorsStaleSeconds - ); - } - if (cacheOptions.backgroundRefresh === undefined) { - cacheOptions.backgroundRefresh = true; - } - const invitationEntities = await github.collections.getRepoInvitations( - this.authorize(AppPurpose.Data), - parameters, - cacheOptions - ); - const invitations = common.createInstances( - this, - invitationFromEntity, - invitationEntities - ); - invitationEntities?.cost && ((invitations as any).cost = invitationEntities.cost); - invitationEntities?.headers && ((invitations as any).headers = invitationEntities.headers); - return invitations; - } - async addCollaborator( username: string, permission: GitHubRepositoryPermission @@ -1480,6 +1330,9 @@ export class Repository { private: options.private, } ); + // BUG: GitHub Apps do not work with locking down no repository permissions as documented here: https://github.community/t5/GitHub-API-Development-and/GitHub-App-cannot-patch-repo-visibility-in-org-with-repo/m-p/33448#M3150 + // const token = this._operations.getCentralOperationsToken(); + // return this._operations.github.post(token, 'repos.update', parameters); return operations.github.post(this.authorize(AppPurpose.Operations), 'repos.update', parameters); } @@ -1701,10 +1554,7 @@ export class Repository { const teams = (await this.getTeamPermissions()).filter((tp) => tp.permission === 'admin'); for (let i = 0; i < teams.length; i++) { const team = teams[i]; - if ( - excludeBroadAndSystemTeams && - (team.team.isSystemTeam || team.team.isBroadAccessTeam || team.team.isOpenAccessTeam) - ) { + if (excludeBroadAndSystemTeams && (team.team.isSystemTeam || team.team.isBroadAccessTeam)) { // Do not include broad access teams continue; } @@ -1884,16 +1734,19 @@ export class Repository { return Array.from(users.values()); } - private authorize(purpose: AppPurposeTypes): GetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } - private specificAuthorization(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + private specificAuthorization(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { const getSpecificHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getSpecificHeader; } @@ -2161,9 +2014,3 @@ function collaboratorPermissionFromEntity(entity) { const permission = new Collaborator(entity); return permission; } - -function invitationFromEntity(entity) { - // 'this' is bound for this function to be a private method - const invitation = new RepositoryInvitation(this, entity); - return invitation; -} diff --git a/business/repositoryActions.ts b/business/repositoryActions.ts index fff60e0c7..ec2d2b539 100644 --- a/business/repositoryActions.ts +++ b/business/repositoryActions.ts @@ -5,13 +5,16 @@ import { Repository } from './repository'; import { getPageSize, getMaxAgeSeconds, CacheDefault } from '.'; -import { AppPurpose } from '../lib/github/appPurposes'; +import { AppPurpose } from './githubApps'; import { - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, IOperationsInstance, + IGetBranchesOptions, + IGitHubBranch, throwIfNotGitHubCapable, + IGetPullsOptions, ICacheOptions, - GetAuthorizationHeader, + IGetAuthorizationHeader, } from '../interfaces'; export interface IGitHubActionWorkflowsResponse { @@ -33,16 +36,16 @@ export interface IGitHubActionWorkflow { } export class RepositoryActions { - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _operations: IOperationsInstance; private _repository: Repository; constructor( repository: Repository, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, operations: IOperationsInstance ) { this._repository = repository; @@ -175,11 +178,11 @@ export class RepositoryActions { return entity; } - private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { + private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/repositoryInvitation.ts b/business/repositoryInvitation.ts deleted file mode 100644 index 449774cbb..000000000 --- a/business/repositoryInvitation.ts +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { GitHubRepositoryPermission, GitHubSimpleAccount } from '../interfaces'; -import * as common from './common'; -import { Repository } from './repository'; - -const primaryProperties = ['inviter', 'invitee', 'permissions', 'created_at', 'html_url', 'node_id']; - -export type RepositoryInvitationClientJson = { - inviter: { - id: number; - login: string; - }; - invitee: { - id: number; - login: string; - }; - permissions: GitHubRepositoryPermission; - created_at: string; - html_url: string; - // node_id: string; -}; - -export class RepositoryInvitation { - public static PrimaryProperties = primaryProperties; - - private _inviter: GitHubSimpleAccount; - private _invitee: GitHubSimpleAccount; - private _permissions: GitHubRepositoryPermission; - private _html_url: string; - private _created_at: string; - - constructor( - private repository: Repository, - entity: unknown - ) { - if (entity) { - common.assignKnownFieldsPrefixed(this, entity, 'invitation', primaryProperties); - } - } - - asJson(): RepositoryInvitationClientJson { - return { - invitee: this.invitee, - inviter: this.inviter, - permissions: this.permission, - html_url: this.invitationUrl, - created_at: this._created_at, - }; - } - - get permission(): GitHubRepositoryPermission { - return this._permissions; - } - - // getHighestPermission() { - // if (!this._permissions) { - // return GitHubRepositoryPermission.None; - // } - // return projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(this._permissions); - // } - - get inviter(): GitHubSimpleAccount { - return this._inviter; - } - - get invitee(): GitHubSimpleAccount { - return this._invitee; - } - - get invitationUrl(): string { - return this._html_url; - } -} diff --git a/business/repositoryIssue.ts b/business/repositoryIssue.ts index 3e80750e0..936bc606b 100644 --- a/business/repositoryIssue.ts +++ b/business/repositoryIssue.ts @@ -4,25 +4,25 @@ // import { Repository } from './repository'; -import { wrapError } from '../lib/utils'; -import { AppPurpose } from '../lib/github/appPurposes'; +import { wrapError } from '../utils'; +import { AppPurpose } from './githubApps'; import { CacheDefault, getMaxAgeSeconds, Operations } from '.'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, GitHubIssueState, IIssueLabel, throwIfNotGitHubCapable, ICacheOptions, - GetAuthorizationHeader, + IGetAuthorizationHeader, GitHubIssuePatchParameters, GitHubStateReason, } from '../interfaces'; -import { CreateError, ErrorHelper } from '../lib/transitional'; +import { CreateError, ErrorHelper } from '../transitional'; export class RepositoryIssue { private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _number: number; private _repository: Repository; @@ -33,7 +33,7 @@ export class RepositoryIssue { repository: Repository, issueNumber: number, operations: IOperationsInstance, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, entity?: any ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -211,8 +211,11 @@ export class RepositoryIssue { return false; } - private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } diff --git a/business/repositoryPermission.ts b/business/repositoryPermission.ts index a0dbcca24..daea8021f 100644 --- a/business/repositoryPermission.ts +++ b/business/repositoryPermission.ts @@ -9,21 +9,17 @@ import { GitHubCollaboratorPermissionLevel, ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermission, GitHubRepositoryPermission, - IGitHubCollaboratorPermissions, } from '../interfaces'; -import type { CollaboratorAccount, CollaboratorJson } from './collaborator'; // prettier-ignore const repoPermissionProperties = [ 'permission', 'user', - 'role_name', ]; export class RepositoryPermission { - private _id: number; - private _user: CollaboratorAccount; - private _role_name: string; + private _id: string; + private _user: any; private _permission: GitHubCollaboratorPermissionLevel; @@ -36,86 +32,17 @@ export class RepositoryPermission { } } - get id(): number { + get id(): string { return this._id; } - - get roleName(): string { - return this._role_name; - } - get permission(): GitHubCollaboratorPermissionLevel { return this._permission; } - - get user(): CollaboratorAccount { + get user(): any { return this._user; } - asCollaboratorJson(): CollaboratorJson { - return { - avatar_url: null, - id: this._id, - login: this._user?.login, - permissions: this.asCollaboratorPermissions(), - }; - } - - asCollaboratorPermissions(): IGitHubCollaboratorPermissions { - return repositoryPermissionToPermissionsObject(this.asGitHubLegacyRepositoryPermission()); - } - - asGitHubLegacyRepositoryPermission(): GitHubRepositoryPermission { - // GitHub's API will only return "admin", "read", "write"; while the function - // implements recognition of maintain, etc., it isn't a thing. + public asGitHubRepositoryPermission(): GitHubRepositoryPermission { return ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermission(this._permission); } - - hasCustomRolePermission() { - switch (this._role_name) { - case GitHubRepositoryPermission.Admin: - case GitHubRepositoryPermission.Maintain: - case GitHubRepositoryPermission.Triage: - case GitHubRepositoryPermission.Push: - case GitHubRepositoryPermission.Pull: - return false; - default: - return true; - } - } - - interpretRoleAsDetailedPermission(): GitHubRepositoryPermission { - if (!this.hasCustomRolePermission()) { - return this._role_name as GitHubRepositoryPermission; - } - return this.asGitHubLegacyRepositoryPermission(); - } -} - -export function repositoryPermissionToPermissionsObject( - permission: GitHubRepositoryPermission -): IGitHubCollaboratorPermissions { - const permissions: IGitHubCollaboratorPermissions = { - admin: false, - maintain: false, - push: false, - triage: false, - pull: false, - }; - if (permission === GitHubRepositoryPermission.Admin) { - permissions.admin = true; - } - if (permission === GitHubRepositoryPermission.Maintain || permissions.admin === true) { - permissions.maintain = true; - } - if (permission === GitHubRepositoryPermission.Push || permissions.maintain === true) { - permissions.push = true; - } - if (permission === GitHubRepositoryPermission.Triage || permissions.push === true) { - permissions.triage = true; - } - if (permission === GitHubRepositoryPermission.Pull || permissions.triage === true) { - permissions.pull = true; - } - return permissions; } diff --git a/business/repositoryProject.ts b/business/repositoryProject.ts index 034eea1d9..5bf5d084e 100644 --- a/business/repositoryProject.ts +++ b/business/repositoryProject.ts @@ -4,26 +4,26 @@ // import { Repository } from './repository'; -import { wrapError } from '../lib/utils'; -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { wrapError } from '../utils'; +import { AppPurpose, AppPurposeTypes } from './githubApps'; import { CacheDefault, getMaxAgeSeconds } from '.'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, GitHubIssueState, throwIfNotGitHubCapable, ICacheOptions, - GetAuthorizationHeader, + IGetAuthorizationHeader, ICacheOptionsWithPurpose, } from '../interfaces'; -import { ErrorHelper } from '../lib/transitional'; +import { ErrorHelper } from '../transitional'; import { RepositoryProjectColumn } from './repositoryProjectColumn'; import * as common from './common'; export class RepositoryProject { private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _id: number; private _repository: Repository; @@ -36,8 +36,8 @@ export class RepositoryProject { repository: Repository, projectId: number, operations: IOperationsInstance, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, entity?: any ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -213,11 +213,11 @@ export class RepositoryProject { return false; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/repositoryProjectCard.ts b/business/repositoryProjectCard.ts index 2e052422c..596c3a14d 100644 --- a/business/repositoryProjectCard.ts +++ b/business/repositoryProjectCard.ts @@ -3,13 +3,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose } from '../lib/github/appPurposes'; -import { IOperationsInstance, PurposefulGetAuthorizationHeader, GetAuthorizationHeader } from '../interfaces'; +import { AppPurpose } from './githubApps'; +import { + IOperationsInstance, + IPurposefulGetAuthorizationHeader, + IGetAuthorizationHeader, +} from '../interfaces'; import { RepositoryProjectColumn } from './repositoryProjectColumn'; export class RepositoryProjectCard { private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _id: number; private _column: RepositoryProjectColumn; @@ -20,7 +24,7 @@ export class RepositoryProjectCard { column: RepositoryProjectColumn, cardId: number, operations: IOperationsInstance, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, entity?: any ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -60,8 +64,11 @@ export class RepositoryProjectCard { return this._column; } - private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } diff --git a/business/repositoryProjectColumn.ts b/business/repositoryProjectColumn.ts index d0dd408d2..c69fc7017 100644 --- a/business/repositoryProjectColumn.ts +++ b/business/repositoryProjectColumn.ts @@ -4,11 +4,11 @@ // import { CacheDefault, getMaxAgeSeconds, RepositoryIssue } from '.'; -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { AppPurpose, AppPurposeTypes } from './githubApps'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, - GetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, + IGetAuthorizationHeader, ICacheOptionsWithPurpose, throwIfNotGitHubCapable, ICacheOptions, @@ -16,11 +16,11 @@ import { import { augmentInertiaPreview, RepositoryProject } from './repositoryProject'; import { RepositoryProjectCard } from './repositoryProjectCard'; import * as common from './common'; -import { CreateError } from '../lib/transitional'; +import { CreateError } from '../transitional'; export class RepositoryProjectColumn { private _operations: IOperationsInstance; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _id: number; private _project: RepositoryProject; @@ -31,7 +31,7 @@ export class RepositoryProjectColumn { project: RepositoryProject, columnId: number, operations: IOperationsInstance, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, entity?: any ) { this._getSpecificAuthorizationHeader = getSpecificAuthorizationHeader; @@ -136,11 +136,11 @@ export class RepositoryProjectColumn { return card; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/repositoryProperties.ts b/business/repositoryProperties.ts deleted file mode 100644 index f653ebff6..000000000 --- a/business/repositoryProperties.ts +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { Repository } from './repository'; -import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; -import { createCacheOptions, popPurpose, symbolizeApiResponse } from '.'; -import { - IOperationsInstance, - PurposefulGetAuthorizationHeader, - throwIfNotGitHubCapable, - GetAuthorizationHeader, - ICacheOptionsWithPurpose, -} from '../interfaces'; -import { OrganizationCustomPropertySetPropertyValue } from './organizationProperties'; - -export class RepositoryProperties { - private _defaultPurpose = AppPurpose.Data; - private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; - - constructor( - public readonly repository: Repository, - private operations: IOperationsInstance, - getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader - ) { - this._getSpecificAuthorizationHeader = getSpecificAuthorizationHeader; - } - - createOrUpdateProperties( - propertiesAndValues: Record, - purpose?: AppPurposeTypes - ): Promise { - const names = [this.repository.name]; - const organizationProperties = this.repository.organization.customProperties; - return organizationProperties.createOrUpdateRepositoriesProperties(names, propertiesAndValues, purpose); - } - - async getProperties(options?: ICacheOptionsWithPurpose): Promise> { - options = options || {}; - const operations = throwIfNotGitHubCapable(this.operations); - const { github } = operations; - const purpose = popPurpose(options, this._defaultPurpose); - const parameters = { - owner: this.repository.organization.name, - repo: this.repository.name, - }; - const cacheOptions = createCacheOptions(operations, options); - try { - const responseArray = await github.request( - this.authorize(purpose), - 'GET /repos/:owner/:repo/properties/values', - parameters, - cacheOptions - ); - return symbolizeApiResponse(arrayToSetProperties(responseArray)); - } catch (error) { - throw error; - } - } - - private authorize(purpose: AppPurposeTypes): GetAuthorizationHeader | string { - const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( - this, - purpose - ) as GetAuthorizationHeader; - return getAuthorizationHeader; - } -} - -function arrayToSetProperties(properties: OrganizationCustomPropertySetPropertyValue[]) { - const propertiesAndValues: Record = {}; - for (const property of properties) { - propertiesAndValues[property.property_name] = property.value; - } - return propertiesAndValues; -} diff --git a/business/repositoryPullRequest.ts b/business/repositoryPullRequest.ts index 41fad1c01..81d2b8a51 100644 --- a/business/repositoryPullRequest.ts +++ b/business/repositoryPullRequest.ts @@ -4,26 +4,26 @@ // import { Repository } from './repository'; -import { wrapError } from '../lib/utils'; -import { AppPurpose } from '../lib/github/appPurposes'; +import { wrapError } from '../utils'; +import { AppPurpose } from './githubApps'; import { CacheDefault, getMaxAgeSeconds } from '.'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, GitHubIssueState, IIssueLabel, throwIfNotGitHubCapable, ICacheOptions, - GetAuthorizationHeader, + IGetAuthorizationHeader, } from '../interfaces'; -import { ErrorHelper } from '../lib/transitional'; +import { ErrorHelper } from '../transitional'; // Pull requests are issues but not all issues are pull requests. So this is mostly a clone of repositoryIssue.ts // right now, with slightly different endpoints. export class RepositoryPullRequest { private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _number: number; private _repository: Repository; @@ -34,7 +34,7 @@ export class RepositoryPullRequest { repository: Repository, pullRequestNumber: number, operations: IOperationsInstance, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, entity?: any ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -219,8 +219,11 @@ export class RepositoryPullRequest { return false; } - private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/team.ts b/business/team.ts index 33e17002f..d2950b1e6 100644 --- a/business/team.ts +++ b/business/team.ts @@ -8,16 +8,16 @@ import _ from 'lodash'; import * as common from './common'; -import { wrapError } from '../lib/utils'; +import { wrapError } from '../utils'; import { TeamMember } from './teamMember'; import { TeamRepositoryPermission } from './teamRepositoryPermission'; -import { IApprovalProvider } from './entities/teamJoinApproval/approvalProvider'; -import { TeamJoinApprovalEntity } from './entities/teamJoinApproval/teamJoinApproval'; -import { AppPurpose } from '../lib/github/appPurposes'; +import { IApprovalProvider } from '../entities/teamJoinApproval/approvalProvider'; +import { TeamJoinApprovalEntity } from '../entities/teamJoinApproval/teamJoinApproval'; +import { AppPurpose } from './githubApps'; import { CacheDefault, getMaxAgeSeconds, getPageSize, Organization } from '.'; import { IOperationsInstance, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, TeamJsonFormat, throwIfNotCapable, IOperationsUrls, @@ -25,7 +25,7 @@ import { ICacheOptions, throwIfNotGitHubCapable, IPagedCacheOptions, - GetAuthorizationHeader, + IGetAuthorizationHeader, IUpdateTeamMembershipOptions, GitHubTeamRole, ITeamMembershipRoleState, @@ -36,9 +36,8 @@ import { IGetTeamRepositoriesOptions, GitHubRepositoryType, IOperationsProviders, - GitHubTeamDetails, } from '../interfaces'; -import { validateGitHubLogin, ErrorHelper } from '../lib/transitional'; +import { validateGitHubLogin, ErrorHelper } from '../transitional'; const teamPrimaryProperties = [ 'id', @@ -83,7 +82,7 @@ export class Team { private _organization: Organization; private _operations: IOperationsInstance; - private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; private _id: number; @@ -140,7 +139,7 @@ export class Team { constructor( organization: Organization, entity, - getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getAuthorizationHeader: IPurposefulGetAuthorizationHeader, operations: IOperationsInstance ) { if (!entity || !entity.id) { @@ -182,7 +181,6 @@ export class Team { clone.corporateMetadata = { isSystemTeam: this.isSystemTeam, isBroadAccessTeam: this.isBroadAccessTeam, - isOpenAccessTeam: this.isOpenAccessTeam, }; return clone; } @@ -218,7 +216,7 @@ export class Team { if (this._name && this._slug) { return; } - await this.getDetails(); + return await this.getDetails(); } async isDeleted(options?: ICacheOptions): Promise { @@ -232,7 +230,7 @@ export class Team { return false; } - async getDetails(options?: ICacheOptions): Promise { + async getDetails(options?: ICacheOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this._operations); const cacheOptions = { @@ -305,7 +303,7 @@ export class Team { const getAuthorizationHeader = this._getAuthorizationHeader.bind( this, AppPurpose.Data - ) as GetAuthorizationHeader; + ) as IGetAuthorizationHeader; const teamEntities = await github.collections.getTeamChildTeams( getAuthorizationHeader, parameters, @@ -325,15 +323,6 @@ export class Team { return res >= 0; } - get isOpenAccessTeam(): boolean { - const teams = this._organization.openAccessTeams; - if (typeof this._id !== 'number') { - throw new Error('Team.id must be a number'); - } - const res = teams.indexOf(this._id); - return res >= 0; - } - get isSystemTeam(): boolean { const systemTeams = this._organization.systemTeamIds; const res = systemTeams.indexOf(this._id); @@ -698,8 +687,11 @@ export class Team { }; } - private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; + private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind( + this, + purpose + ) as IGetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/teamMember.ts b/business/teamMember.ts index 7e68c535f..bca38e787 100644 --- a/business/teamMember.ts +++ b/business/teamMember.ts @@ -23,12 +23,6 @@ const memberPrimaryProperties = [ ]; const memberSecondaryProperties = []; -export type TeamMemberJson = { - id: number; - login: string; - avatar_url: string; -}; - export class TeamMember { private _team: Team; private _operations: IOperationsInstance; @@ -82,7 +76,7 @@ export class TeamMember { this._operations = operations; } - asJson(): TeamMemberJson { + asJson() { return { id: this.id, login: this.login, diff --git a/business/teamPermission.ts b/business/teamPermission.ts index 3fd781410..f05f49d28 100644 --- a/business/teamPermission.ts +++ b/business/teamPermission.ts @@ -9,61 +9,24 @@ import { Organization } from './organization'; import { TeamMember } from './teamMember'; import { Team } from '.'; import { - type IOperationsInstance, + IOperationsInstance, GitHubTeamPrivacy, TeamJsonFormat, - type IGetMembersOptions, + IGetMembersOptions, GitHubRepositoryPermission, - type IGitHubTeamBasics, } from '../interfaces'; -import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../lib/transitional'; - -export interface ITeamRepositoryPermission { - pull: boolean; - triage: boolean; - push: boolean; - maintain: boolean; - admin: boolean; -} - -export function isStandardGitHubTeamPermission(val: string | GitHubRepositoryPermission) { - switch (val) { - case GitHubRepositoryPermission.Pull: - case GitHubRepositoryPermission.Triage: - case GitHubRepositoryPermission.Push: - case GitHubRepositoryPermission.Maintain: - case GitHubRepositoryPermission.Admin: - return true; - default: - return false; - } -} - -type TeamPermissionIncomingEntity = { - name: string; - id: number; - // node_id: we remove this currently - slug: string; - description: string; - privacy: GitHubTeamPrivacy; - permission: GitHubRepositoryPermission | string; - permissions: ITeamRepositoryPermission; - parent: IGitHubTeamBasics; -}; export class TeamPermission { - // private _operations: IOperationsInstance; private _organization: Organization; + private _operations: IOperationsInstance; private _team: Team; - private _permission: GitHubRepositoryPermission | string; + private _permission: GitHubRepositoryPermission; private _privacy: GitHubTeamPrivacy; private _teamMembersIfSet: TeamMember[]; - private _entity: TeamPermissionIncomingEntity; - [util.inspect.custom](depth, options) { return `GitHub Team Permission: team=${this.team?.slug || this.team?.id} permission=${this._permission}`; } @@ -78,7 +41,7 @@ export class TeamPermission { }; } - get permission(): string | GitHubRepositoryPermission { + get permission(): GitHubRepositoryPermission { return this._permission; } @@ -90,13 +53,8 @@ export class TeamPermission { return this._team; } - constructor( - organization: Organization, - entity: TeamPermissionIncomingEntity, - operations: IOperationsInstance - ) { + constructor(organization: Organization, entity: any, operations: IOperationsInstance) { this._organization = organization; - this._entity = entity; this._permission = entity.permission; this._privacy = entity.privacy; @@ -107,7 +65,7 @@ export class TeamPermission { const id = entity.id; this._team = organization.team(id, entity); - // this._operations = operations; + this._operations = operations; } get relativeJoinLink() { @@ -124,20 +82,6 @@ export class TeamPermission { } } - get customRoleName() { - if (!isStandardGitHubTeamPermission(this._entity.permission)) { - return this._entity.permission; - } - } - - get permissions(): ITeamRepositoryPermission { - return this._entity.permissions; - } - - getAsPermission(): GitHubRepositoryPermission { - return projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(this._entity.permissions); - } - async resolveTeamMembers(options?: IGetMembersOptions): Promise { this._teamMembersIfSet = await this.team.getMembers(options); } diff --git a/business/teamRepositoryPermission.ts b/business/teamRepositoryPermission.ts index 972d8e51d..1ed650604 100644 --- a/business/teamRepositoryPermission.ts +++ b/business/teamRepositoryPermission.ts @@ -5,48 +5,29 @@ import { Team } from './team'; import { Repository } from './repository'; - -import type { GitHubRepositoryPermission, IOperationsInstance } from '../interfaces'; -import { isStandardGitHubTeamPermission, type ITeamRepositoryPermission } from './teamPermission'; -import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../lib/transitional'; - -// this is used when a team returns the repositories it can work with; -// the GitHub API is pretty inconsistent. The actual entities are a combination of -// repository AND permission here. - -type RepositoryWithTeamPermissionsEntity = { - id: number; - name: string; - full_name: string; - private: boolean; - description: string; - fork: boolean; - permissions: ITeamRepositoryPermission; - role_name: string; -}; +import { IOperationsInstance } from '../interfaces'; export class TeamRepositoryPermission { - // private _operations: IOperationsInstance; - - private _entity: RepositoryWithTeamPermissionsEntity; - private _team: Team; + private _operations: IOperationsInstance; + private _permissions: any; private _repository: Repository; private _id: number; - constructor(team: Team, entity: RepositoryWithTeamPermissionsEntity, operations: IOperationsInstance) { + constructor(team: Team, entity: any, operations: IOperationsInstance) { this._team = team; if (!entity) { throw new Error('TeamRepositoryPermission: requires entity'); } - this._entity = entity; + this._permissions = entity.permissions; this._repository = team.organization.repositoryFromEntity(entity); this._id = this._repository.id; + this._operations = operations; } asJson() { const repo = this._repository.asJson(); - const permissions = this.permissions; + const permissions = this._permissions; const combined = { ...repo, permissions }; return combined; } @@ -63,18 +44,8 @@ export class TeamRepositoryPermission { return this._id; } - get customRoleName() { - if (!isStandardGitHubTeamPermission(this._entity.role_name)) { - return this._entity.role_name; - } - } - - get permissions(): ITeamRepositoryPermission { - return this._entity.permissions; - } - - getAsPermission(): GitHubRepositoryPermission { - return projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(this._entity.permissions); + get permissions(): any { + return this._permissions; } get name(): string { diff --git a/business/user/aggregate.ts b/business/user/aggregate.ts index 63116e9e5..30aabe83f 100644 --- a/business/user/aggregate.ts +++ b/business/user/aggregate.ts @@ -19,7 +19,7 @@ import { OrganizationMembershipRoleQuery, GitHubRepositoryPermission, } from '../../interfaces'; -import { SettleToStateValue, isPermissionBetterThan, ErrorHelper } from '../../lib/transitional'; +import { SettleToStateValue, isPermissionBetterThan, ErrorHelper } from '../../transitional'; import LinkManager from './linkManager'; // PLANNING once consolidated @@ -267,11 +267,7 @@ export class UserContext { const permission = tp.permission; const entity = { ...team.toSimpleJsonObject() }; entity['permission'] = permission; - const teamRepositoryPermission = new TeamRepositoryPermission( - team, - entity as any /* RepositoryWithTeamPermissionsEntity */, - this._operations - ); + const teamRepositoryPermission = new TeamRepositoryPermission(team, entity, this._operations); if (isPermissionBetterThan(bestPermission, permission)) { bestPermission = permission; } diff --git a/business/user/index.ts b/business/user/index.ts index e74c64fdd..93d52895e 100644 --- a/business/user/index.ts +++ b/business/user/index.ts @@ -10,7 +10,7 @@ import objectPath from 'object-path'; import Debug from 'debug'; const debug = Debug.debug('context'); -import { addBreadcrumb, isCodespacesAuthenticating } from '../../lib/utils'; +import { addBreadcrumb, isCodespacesAuthenticating } from '../../utils'; import { Operations } from '../operations'; import { UserContext } from './aggregate'; import { @@ -537,7 +537,7 @@ export class IndividualContext { async isPortalAdministrator(): Promise { const operations = this._operations; - const ghi = this.getGitHubIdentity()?.username; + const ghi = this.getGitHubIdentity().username; const link = this._link; this._isPortalAdministrator = await operations.isPortalSudoer(ghi, link); return this._isPortalAdministrator; diff --git a/config/brand.types.ts b/config/brand.types.ts index 62c89a816..4c16aa981 100644 --- a/config/brand.types.ts +++ b/config/brand.types.ts @@ -17,4 +17,5 @@ export type ConfigBrand = { operationsMail: string; forkApprovalMail: string; electionMail: string; + infrastructureNotificationsMail: string; }; diff --git a/config/continuousDeployment.types.ts b/config/continuousDeployment.types.ts index 52602db41..4c7d22560 100644 --- a/config/continuousDeployment.types.ts +++ b/config/continuousDeployment.types.ts @@ -8,9 +8,6 @@ export type ConfigRootContinuousDeployment = { }; export type ConfigContinuousDeployment = { - branchName: string; - build: string; - commitId: string; version: string; name: string; }; diff --git a/config/debug.json b/config/debug.json index 1f904f311..56175a688 100644 --- a/config/debug.json +++ b/config/debug.json @@ -2,7 +2,5 @@ "environmentName": "env://ENVIRONMENT_NAME?default=Unknown", "showUsers": "env://SITE_SHOW_USERS?trueIf=show", "showDebugFooter": "env://DEBUG_SHOW_FOOTER?trueIf=1", - "exitImmediately": "env://EXIT_IMMEDIATELY?trueIf=1", - "unlinkWithoutDrops": "env://DEBUG_UNLINK_WITHOUT_DROPS?trueIf=1", - "breakConsoleEveryMinute": "env://DEBUG_MINUTE_BREAKS?trueIf=1" + "unlinkWithoutDrops": "env://DEBUG_UNLINK_WITHOUT_DROPS?trueIf=1" } diff --git a/config/debug.types.ts b/config/debug.types.ts index 2dc85bd95..4c6c7b2a9 100644 --- a/config/debug.types.ts +++ b/config/debug.types.ts @@ -12,6 +12,4 @@ export type ConfigDebug = { showUsers: boolean; showDebugFooter: boolean; unlinkWithoutDrops: boolean; - exitImmediately: boolean; - breakConsoleEveryMinute?: boolean; }; diff --git a/config/github.operations.json b/config/github.operations.json index 22222b72d..73b95dee3 100644 --- a/config/github.operations.json +++ b/config/github.operations.json @@ -1,4 +1,5 @@ { + "centralOperationsToken": "env://GITHUB_CENTRAL_OPERATIONS_TOKEN", "publicAccessToken": "env://GITHUB_PUBLIC_OPERATIONS_TOKEN", "primaryOrganizationId": "env://GITHUB_PRIMARY_ORGANIZATION_ID?type=integer" } diff --git a/config/github.organizations.types.ts b/config/github.organizations.types.ts index 3e0ba49a1..b33c37ada 100644 --- a/config/github.organizations.types.ts +++ b/config/github.organizations.types.ts @@ -19,7 +19,6 @@ export type ConfigGitHubOrganization = { teamAllReposRead: string; // | number teamAllReposWrite: string; // | number teamAllReposAdmin: string; - teamOpenAccess: string; teamSudoers: string; templates: string[]; onboarding: boolean; diff --git a/config/npm.publishing.json b/config/npm.publishing.json new file mode 100644 index 000000000..a6b728dac --- /dev/null +++ b/config/npm.publishing.json @@ -0,0 +1,6 @@ +{ + "former_token": "env://NPM_PUBLISHING_TOKEN", + "token": "", + "notify": "env://NPM_PUBLISHING_NOTIFICATION_EMAIL", + "notifyFrom": "env://NPM_PUBLISHING_NOTIFICATION_FROM" +} diff --git a/config/npm.publishing.types.ts b/config/npm.publishing.types.ts new file mode 100644 index 000000000..6eccf0230 --- /dev/null +++ b/config/npm.publishing.types.ts @@ -0,0 +1,17 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +export type ConfigNpmRootPublishing = { + publishing: ConfigNpmPublishing; +}; + +// NOTE: this config and associated concept is no longer part of this application + +export type ConfigNpmPublishing = { + former_token: string; + token: string; + notify: string; + notifyFrom: string; +}; diff --git a/config/npm.types.ts b/config/npm.types.ts index e3e943afa..1299e552a 100644 --- a/config/npm.types.ts +++ b/config/npm.types.ts @@ -3,10 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import type { ConfigNpmRootPublishing } from './npm.publishing.types'; + export type ConfigRootNpm = { npm: ConfigNpm; }; -export type ConfigNpm = { +export type ConfigNpm = ConfigNpmRootPublishing & { privateFeedScope: string; }; diff --git a/config/webServer.json b/config/webServer.json index f5f9bf26f..5ad274329 100644 --- a/config/webServer.json +++ b/config/webServer.json @@ -4,18 +4,7 @@ "appService": { "slot": "env://WEBSITE_SLOT_NAME", "name": "env://WEBSITE_SITE_NAME", - "region": "env://REGION_NAME", - "advanced": { - "resourceGroup": "env://WEBSITE_RESOURCE_GROUP", - "warmup": "env://WEBSITE_WARMUP_PATH", - "swapWarmup": "env://WEBSITE_SWAP_WARMUP_PING_PATH", - "containerName": "env://WEBSITES_WEB_CONTAINER_NAME", - "instanceId": "env://WEBSITE_INSTANCE_ID", - "sku": "env://WEBSITE_SKU", - "hostname": "env://WEBSITE_HOSTNAME", - "alwaysOn": "env://WEBSITE_SCM_ALWAYS_ON_ENABLED", - "slotType": "env://SITE_SLOT_TYPE" - } + "region": "env://REGION_NAME" }, "baseUrl": "env://SITE_BASE_URL", "sslify": { diff --git a/config/webServer.types.ts b/config/webServer.types.ts index c716230d7..b531fe90b 100644 --- a/config/webServer.types.ts +++ b/config/webServer.types.ts @@ -14,17 +14,6 @@ export type ConfigWebServer = { slot: string; name: string; region: string; - advanced?: { - resourceGroup: string; - warmup: string; - swapWarmup: string; - containerName: string; - instanceId: string; - sku: string; - hostname: string; - alwaysOn: string; - slotType: 'production' | 'staging' | undefined; - }; }; baseUrl: string; sslify: { diff --git a/default-assets-package/package-lock.json b/default-assets-package/package-lock.json index 1306cdac6..35d2a3b52 100644 --- a/default-assets-package/package-lock.json +++ b/default-assets-package/package-lock.json @@ -36,6 +36,23 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -132,18 +149,79 @@ "node": ">=0.10.0" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true, + "optional": true + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/async": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true, + "optional": true + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true, + "optional": true + }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "optional": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/blockui": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/blockui/-/blockui-1.0.0.tgz", @@ -198,6 +276,13 @@ "d3": "~3.5.0" } }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true, + "optional": true + }, "node_modules/chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -214,6 +299,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -241,6 +335,19 @@ "node": ">=0.1.90" } }, + "node_modules/combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "optional": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/components-font-awesome": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/components-font-awesome/-/components-font-awesome-4.2.0.tgz", @@ -252,17 +359,12 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "node_modules/copy-anything": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", - "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, - "dependencies": { - "is-what": "^3.14.1" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } + "optional": true }, "node_modules/d3": { "version": "3.5.17", @@ -270,6 +372,19 @@ "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=", "dev": true }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -279,6 +394,16 @@ "node": "*" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -293,6 +418,17 @@ "resolved": "https://registry.npmjs.org/dom/-/dom-0.0.2.tgz", "integrity": "sha1-4V+3WV4ym9Enj8yFjQ97jPOOS1E=" }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "optional": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -361,6 +497,30 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "optional": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "optional": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true, + "optional": true + }, "node_modules/file-sync-cmp": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", @@ -453,6 +613,31 @@ "node": ">=0.10.0" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -474,6 +659,16 @@ "node": ">=10" } }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -881,6 +1076,31 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "deprecated": "this library is no longer supported", + "dev": true, + "optional": true, + "dependencies": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -935,6 +1155,22 @@ "node": "*" } }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1067,6 +1303,13 @@ "node": ">=0.10.0" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true, + "optional": true + }, "node_modules/is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", @@ -1079,12 +1322,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", - "dev": true - }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -1109,6 +1346,13 @@ "node": ">=0.10.0" } }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true, + "optional": true + }, "node_modules/jquery": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz", @@ -1127,6 +1371,50 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true, + "optional": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "optional": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true, + "optional": true + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -1137,27 +1425,27 @@ } }, "node_modules/less": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz", - "integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", + "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", "dev": true, "dependencies": { - "copy-anything": "^2.0.1", - "tslib": "^1.10.0" + "clone": "^2.1.2" }, "bin": { "lessc": "bin/lessc" }, "engines": { - "node": ">=6" + "node": ">=4" }, "optionalDependencies": { "errno": "^0.1.1", "graceful-fs": "^4.1.2", "image-size": "~0.5.0", - "make-dir": "^2.1.0", "mime": "^1.4.1", - "native-request": "^1.0.5", + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "^2.83.0", "source-map": "~0.6.0" } }, @@ -1251,20 +1539,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "optional": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -1312,6 +1586,29 @@ "node": ">=4" } }, + "node_modules/mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "optional": true, + "dependencies": { + "mime-db": "~1.38.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", @@ -1324,6 +1621,26 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true, + "optional": true + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "optional": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/multimatch": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", @@ -1339,13 +1656,6 @@ "node": ">=0.10.0" } }, - "node_modules/native-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.0.tgz", - "integrity": "sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw==", - "dev": true, - "optional": true - }, "node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -1358,6 +1668,16 @@ "nopt": "bin/nopt.js" } }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -1533,6 +1853,13 @@ "node": ">=0.10.0" } }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true, + "optional": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1545,16 +1872,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", @@ -1579,6 +1896,16 @@ "node": ">=4" } }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "optional": true, + "dependencies": { + "asap": "~2.0.3" + } + }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -1586,6 +1913,33 @@ "dev": true, "optional": true }, + "node_modules/psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true, + "optional": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", @@ -1598,6 +1952,39 @@ "node": ">= 0.10" } }, + "node_modules/request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "optional": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -1661,22 +2048,19 @@ "rimraf": "bin.js" } }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "optional": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -1692,6 +2076,32 @@ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "optional": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -1749,11 +2159,46 @@ "node": ">=8.0" } }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "node_modules/tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "optional": true, + "dependencies": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true, + "optional": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true }, "node_modules/typeahead": { "version": "0.2.2", @@ -1794,12 +2239,33 @@ "node": "*" } }, + "node_modules/uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "optional": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "optional": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", @@ -1812,6 +2278,21 @@ "node": ">= 0.10" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -1846,6 +2327,19 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "optional": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -1917,18 +2411,73 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true, + "optional": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "optional": true + }, "async": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true, + "optional": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, "blockui": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/blockui/-/blockui-1.0.0.tgz", @@ -1974,6 +2523,13 @@ "d3": "~3.5.0" } }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true, + "optional": true + }, "chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -1984,6 +2540,12 @@ "supports-color": "^7.1.0" } }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2005,6 +2567,16 @@ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "optional": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "components-font-awesome": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/components-font-awesome/-/components-font-awesome-4.2.0.tgz", @@ -2016,14 +2588,12 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "copy-anything": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", - "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, - "requires": { - "is-what": "^3.14.1" - } + "optional": true }, "d3": { "version": "3.5.17", @@ -2031,12 +2601,29 @@ "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=", "dev": true }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "optional": true + }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -2048,6 +2635,17 @@ "resolved": "https://registry.npmjs.org/dom/-/dom-0.0.2.tgz", "integrity": "sha1-4V+3WV4ym9Enj8yFjQ97jPOOS1E=" }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -2097,6 +2695,27 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "optional": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "optional": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true, + "optional": true + }, "file-sync-cmp": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", @@ -2170,6 +2789,25 @@ "for-in": "^1.0.1" } }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2188,6 +2826,16 @@ "integrity": "sha512-tj18lLe+917AACr6BdVoUuHnBPTVd9BEJp1vxnMZ58ztNvuxz9Ufa+wf3g37tlGITH35jggwZ2d9lcgHJJgXfQ==", "dev": true }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -2502,6 +3150,24 @@ } } }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "optional": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "optional": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2541,6 +3207,18 @@ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2643,6 +3321,13 @@ "is-unc-path": "^1.0.0" } }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true, + "optional": true + }, "is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", @@ -2652,12 +3337,6 @@ "unc-path-regex": "^0.1.2" } }, - "is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -2676,6 +3355,13 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true, + "optional": true + }, "jquery": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz", @@ -2691,6 +3377,47 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true, + "optional": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "optional": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -2698,20 +3425,20 @@ "dev": true }, "less": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz", - "integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", + "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", "dev": true, "requires": { - "copy-anything": "^2.0.1", + "clone": "^2.1.2", "errno": "^0.1.1", "graceful-fs": "^4.1.2", "image-size": "~0.5.0", - "make-dir": "^2.1.0", "mime": "^1.4.1", - "native-request": "^1.0.5", - "source-map": "~0.6.0", - "tslib": "^1.10.0" + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "^2.83.0", + "source-map": "~0.6.0" }, "dependencies": { "source-map": { @@ -2789,17 +3516,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "optional": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -2832,6 +3548,23 @@ "dev": true, "optional": true }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true, + "optional": true + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "optional": true, + "requires": { + "mime-db": "~1.38.0" + } + }, "minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", @@ -2841,6 +3574,23 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true, + "optional": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.6" + } + }, "multimatch": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", @@ -2853,13 +3603,6 @@ "minimatch": "^3.0.0" } }, - "native-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.0.tgz", - "integrity": "sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw==", - "dev": true, - "optional": true - }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -2869,6 +3612,13 @@ "abbrev": "1" } }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "optional": true + }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -3005,19 +3755,19 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true, + "optional": true + }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "optional": true - }, "pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", @@ -3038,6 +3788,16 @@ } } }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "optional": true, + "requires": { + "asap": "~2.0.3" + } + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -3045,6 +3805,27 @@ "dev": true, "optional": true }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true, + "optional": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "optional": true + }, "rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", @@ -3054,6 +3835,35 @@ "resolve": "^1.9.0" } }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, "resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -3099,19 +3909,19 @@ "glob": "^7.1.3" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "optional": true - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -3124,6 +3934,24 @@ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "optional": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -3166,11 +3994,42 @@ "is-number": "^7.0.0" } }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "optional": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true, + "optional": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true }, "typeahead": { "version": "0.2.2", @@ -3205,12 +4064,29 @@ "util-deprecate": "^1.0.2" } }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "optional": true, + "requires": { + "punycode": "^2.1.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true, + "optional": true + }, "v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", @@ -3220,6 +4096,18 @@ "homedir-polyfill": "^1.0.1" } }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/default-assets-package/package.json b/default-assets-package/package.json index 7990f1aff..3ec400fe0 100644 --- a/default-assets-package/package.json +++ b/default-assets-package/package.json @@ -26,7 +26,7 @@ "grunt-contrib-copy": "^1.0.0", "grunt-contrib-less": "^2.0.0", "grunt-exec": "3.0.0", - "jquery": "^3.5.1", + "jquery": "^3.4.0", "load-grunt-tasks": "^4.0.0", "octicons": "4.4.0", "timeago": "1.6.4" diff --git a/docker-compose.yml b/docker-compose.yml index a4d057139..52c7929cd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: - portal volumes: - portal_postgres_data:/var/lib/postgresql/data - - ./data/pg.sql:/docker-entrypoint-initdb.d/pg.sql + - ./pg.sql:/docker-entrypoint-initdb.d/pg.sql environment: POSTGRES_DB: portal-repos POSTGRES_USER: portal diff --git a/docs/api.md b/docs/api.md index b912d44a9..261e6b6aa 100644 --- a/docs/api.md +++ b/docs/api.md @@ -147,7 +147,7 @@ This API will retrieve information about a specific user. The first API version Where `login` is a GitHub username, case insensitive. -##### Response: by GitHub username +##### Response If a link is not found for the GitHub user @@ -188,7 +188,7 @@ This API returns an array if there is at least one matching account or accounts. Where `id` is an AAD ID. -##### Response: by AAD ID +##### Response If a link is not registered for this user @@ -233,7 +233,7 @@ Required API scope: `link` > POST /api/people/links -#### Request: create a link +#### Request ```text BODY @@ -249,7 +249,7 @@ BODY > If the account is a Service Account, the `corporate` object should also include a field called `serviceAccountMail` that points to a contact for the service account. -#### Response: create a link +#### Response ```http Status: 201 OK @@ -261,7 +261,7 @@ Status: 201 OK ### Create a repo -> This API requires that your API key be authorized for the `repo/create` scope +> This API requires that your API key be authorized for the `createRepo` scope This example uses a pure POST request plus headers for authorization: diff --git a/docs/configuration.md b/docs/configuration.md index a2ce8965a..53cd38b68 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -85,7 +85,7 @@ Here is a short overview about the meanings of the different parameters: - **setupbycorporateusername** (string) - Username (from the corporate identity system) of the user who set up the organization - **setupbycorporateid** (string) - Unique identifier (from the corporate identity system) for the user who set up the organization - **setupbycorporatedisplayname** (string) - Display name (from the corporate identity system) for the user who set up the organization -- **specialteams** (object{specialTeam: string, teamId: integer}) - Special team configuration for the organization supported values for `specialTeam` types are: `everyone, sudo, globalSudo, systemWrite, systemRead, systemAdmin, openAccess`. The `teamId` is the GitHub team ID for the special team. +- **specialteams** (object{specialTeam: string, teamId: integer}) - Special team configuration for the organization supported values for `specialTeam` types are: `everyone, sudo, globalSudo, systemWrite, systemRead, systemAdmin`. The `teamId` is the GitHub team ID for the special team. ### Static settings @@ -125,13 +125,13 @@ The opensource-portal can also be configured to read organization configurations ## PostgreSQL Configuration -To run the opensource-portal with a postgres database, you need to [setup postgres](https://www.postgresql.org/docs/11/runtime.html) and initialize the database by running the `data/pg.sql`-file in the psql-terminal. +To run the opensource-portal with a postgres database, you need to [setup postgres](https://www.postgresql.org/docs/11/runtime.html) and initialize the database by running the `pg.sql`-file in the psql-terminal. It's recommended to [run postgres in a docker container](https://hub.docker.com/_/postgres), there is also an official docker image called `postgres` for building. Once the setup is done, set the `host`, `database`, `user`, `password`, `ssl` (as boolean) and `port` of the postgres in the `config/data.postgres.json`-file. -Additionally set the name of the linking-table (`tableName` parameter), if the tables were created with the `data/pg.sql`-file, the name for this table is `links`. +Additionally set the name of the linking-table (`tableName` parameter), if the tables were created with the `pg.sql`-file, the name for this table is `links`. -There is also a script in the `scripts` folder that can blast the `data/pg.sql` insertions into a new database. Be +There is also a script in the `scripts` folder that can blast the `pg.sql` insertions into a new database. Be sure to configure grants and your user accounts with the concept of least privilege required. ## Cache Configuration diff --git a/docs/jobs.md b/docs/jobs.md new file mode 100644 index 000000000..56173c8fc --- /dev/null +++ b/docs/jobs.md @@ -0,0 +1,20 @@ +# Jobs + +There are automated cronjobs available to help keep things running smoothly, +if you choose to use them. + +Jobs are an alternate entrypoint into the application, and have full use of +the same set of [providers](./providers.md). + +## list of cronjobs + +Several jobs are available in the container or the `jobs/` folder. These can +optionally provide useful operational and services support. Often a Kubernetes +CronJob can help. + +- `cleanupInvites`: if configured for an org, cleanup old unaccepted invites +- `firehose`: ongoing processing of GitHub events for keeping cache up-to-date +- `managers`: cache the last-known manager for links, to use in notifications after a departure may remove someone from the graph +- `permissions`: updating permissions for all-write/all-read/all-admin teams when configured +- `refreshUsernames`: keeping link data fresh with GitHub username renames, corporate username and display name updates, and removing links for deleted GitHub users who remove their accounts permanently from GitHub.com +- `reports`: processing the building of report data about use, abandoned repos, etc. **this job is broken** diff --git a/docs/scripts.md b/docs/scripts.md new file mode 100644 index 000000000..25064f56b --- /dev/null +++ b/docs/scripts.md @@ -0,0 +1,5 @@ +# Scripts + +> this file is incomplete + +- `migrateLinks`: a one-time migration script to help when moving link source of truth diff --git a/docs/service-dependencies.md b/docs/service-dependencies.md deleted file mode 100644 index 69269e5ce..000000000 --- a/docs/service-dependencies.md +++ /dev/null @@ -1,26 +0,0 @@ -# Service dependencies - -_This content was moved from the `README.md` to reduce clutter. More content would be helpful._ - -- GitHub organization(s) -- Hosting environment -- Background job environment for eventual consistency work and maintenance cronjobs -- Daemon hosting for near-real-time process -- Queue system -- A cache system or multi-tiered cache implementation -- Azure Active Directory and the Microsoft Graph -- An email service to send mail -- Optional insights or telemetry system - -## Source of truth store - -The backend maintains in a data store of your choice key metadata for -repositories, links, and general compliance info. The backend supports -natively Azure Storage, Azure Table, Azure CosmosDB, and Postgres. - -We use **Postgres** for source of truth including: - -- GitHub organization configuration -- corporate GitHub repository metadata -- corporate identity-to-GitHub login links -- compliance metadata (enable/disabled repos) diff --git a/business/entities/auditLogRecord/auditLogRecord.ts b/entities/auditLogRecord/auditLogRecord.ts similarity index 94% rename from business/entities/auditLogRecord/auditLogRecord.ts rename to entities/auditLogRecord/auditLogRecord.ts index 08f2311ea..a80b77e0a 100644 --- a/business/entities/auditLogRecord/auditLogRecord.ts +++ b/entities/auditLogRecord/auditLogRecord.ts @@ -5,23 +5,23 @@ import { randomUUID } from 'crypto'; -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; +} from '../../lib/entityMetadataProvider/declarations'; import { Type } from './type'; import { PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; -import { IDictionary } from '../../../interfaces'; +} from '../../lib/entityMetadataProvider/postgres'; +import { IDictionary } from '../../interfaces'; import { AuditLogSource } from '.'; -import { stringOrNumberAsString } from '../../../lib/utils'; -import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +import { stringOrNumberAsString } from '../../utils'; +import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; const type = Type; diff --git a/business/entities/auditLogRecord/auditLogRecordProvider.ts b/entities/auditLogRecord/auditLogRecordProvider.ts similarity index 98% rename from business/entities/auditLogRecord/auditLogRecordProvider.ts rename to entities/auditLogRecord/auditLogRecordProvider.ts index 709df08c9..df7b7647a 100644 --- a/business/entities/auditLogRecord/auditLogRecordProvider.ts +++ b/entities/auditLogRecord/auditLogRecordProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { AuditLogRecord, AuditLogRecordQueryUndoCandidatesByThirdPartyId, diff --git a/business/entities/auditLogRecord/index.ts b/entities/auditLogRecord/index.ts similarity index 100% rename from business/entities/auditLogRecord/index.ts rename to entities/auditLogRecord/index.ts diff --git a/business/entities/auditLogRecord/type.ts b/entities/auditLogRecord/type.ts similarity index 69% rename from business/entities/auditLogRecord/type.ts rename to entities/auditLogRecord/type.ts index fb9ba2b8f..de552af45 100644 --- a/business/entities/auditLogRecord/type.ts +++ b/entities/auditLogRecord/type.ts @@ -3,6 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataType } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataType } from '../../lib/entityMetadataProvider/entityMetadata'; export const Type = new EntityMetadataType('AuditLogRecord'); diff --git a/business/entities/localExtensionKey/index.ts b/entities/localExtensionKey/index.ts similarity index 91% rename from business/entities/localExtensionKey/index.ts rename to entities/localExtensionKey/index.ts index 015a8b11f..0aff67b8e 100644 --- a/business/entities/localExtensionKey/index.ts +++ b/entities/localExtensionKey/index.ts @@ -5,7 +5,7 @@ import { LocalExtensionKeyProvider } from './localExtensionKeyProvider'; import { LocalExtensionKey } from './localExtensionKey'; -import { IEntityMetadataProvider } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadataProvider } from '../../lib/entityMetadataProvider/entityMetadataProvider'; export interface ILocalExtensionKeyProvider { initialize(): Promise; diff --git a/business/entities/localExtensionKey/localExtensionKey.ts b/entities/localExtensionKey/localExtensionKey.ts similarity index 90% rename from business/entities/localExtensionKey/localExtensionKey.ts rename to entities/localExtensionKey/localExtensionKey.ts index 62dc3dd7c..0a0adb6ac 100644 --- a/business/entities/localExtensionKey/localExtensionKey.ts +++ b/entities/localExtensionKey/localExtensionKey.ts @@ -5,15 +5,15 @@ import crypto from 'crypto'; -import { IObjectWithDefinedKeys } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IObjectWithDefinedKeys } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; import { MetadataMappingDefinition, EntityMetadataMappings, -} from '../../../lib/entityMetadataProvider/declarations'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; -import { TableSettings } from '../../../lib/entityMetadataProvider/table'; -import { MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +} from '../../lib/entityMetadataProvider/declarations'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { TableSettings } from '../../lib/entityMetadataProvider/table'; +import { MemorySettings } from '../../lib/entityMetadataProvider/memory'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; const type = new EntityMetadataType('LocalExtensionKey'); diff --git a/business/entities/localExtensionKey/localExtensionKeyProvider.ts b/entities/localExtensionKey/localExtensionKeyProvider.ts similarity index 94% rename from business/entities/localExtensionKey/localExtensionKeyProvider.ts rename to entities/localExtensionKey/localExtensionKeyProvider.ts index adb37e2fd..8b3c99097 100644 --- a/business/entities/localExtensionKey/localExtensionKeyProvider.ts +++ b/entities/localExtensionKey/localExtensionKeyProvider.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataBase } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataBase } from '../../lib/entityMetadataProvider/entityMetadata'; import { LocalExtensionKey, EntityImplementation } from './localExtensionKey'; import { ILocalExtensionKeyProvider, ILocalExtensionKeyProviderOptions } from '.'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; const thisProviderType = EntityImplementation.Type; diff --git a/business/entities/organizationAnnotation.ts b/entities/organizationAnnotation.ts similarity index 90% rename from business/entities/organizationAnnotation.ts rename to entities/organizationAnnotation.ts index 61b428b77..0fe6daf74 100644 --- a/business/entities/organizationAnnotation.ts +++ b/entities/organizationAnnotation.ts @@ -22,16 +22,16 @@ import { EntityMetadataType, IEntityMetadataBaseOptions, EntityMetadataBase, -} from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, QueryBase } from '../../lib/entityMetadataProvider/query'; +} from '../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, QueryBase } from '../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; -import { PostgresSettings, PostgresConfiguration } from '../../lib/entityMetadataProvider/postgres'; -import { IDictionary } from '../../interfaces'; -import { CreateError, ErrorHelper } from '../../lib/transitional'; -import { MemoryConfiguration, TableConfiguration } from '../../lib/entityMetadataProvider'; +} from '../lib/entityMetadataProvider/declarations'; +import { PostgresSettings, PostgresConfiguration } from '../lib/entityMetadataProvider/postgres'; +import { IDictionary } from '../interfaces'; +import { CreateError, ErrorHelper } from '../transitional'; +import { MemoryConfiguration, TableConfiguration } from '../lib/entityMetadataProvider'; const type = new EntityMetadataType('OrganizationAnnotation'); const thisProviderType = type; @@ -41,10 +41,7 @@ const defaultPostgresTableName = 'organizationannotations'; const organizationId = 'organizationId'; const primaryKeyFieldName = organizationId; -export enum OrganizationAnnotationProperty { - Governance = 'governance', -} - +export enum OrganizationAnnotationProperty {} export enum OrganizationAnnotationFeature {} export interface IOrganizationAnnotationChange { @@ -55,11 +52,6 @@ export interface IOrganizationAnnotationChange { text: string; } -export function getOrganizationAnnotationRestrictedPropertyNames(isSystemAdministrator?: boolean): string[] { - const restrictedProperties = ['administratorNodes', 'history']; - return isSystemAdministrator ? [] : restrictedProperties; -} - interface IOrganizationAnnotationMetadataProperties { // organizationId: string; // primary ID diff --git a/business/entities/organizationMemberCache/index.ts b/entities/organizationMemberCache/index.ts similarity index 100% rename from business/entities/organizationMemberCache/index.ts rename to entities/organizationMemberCache/index.ts diff --git a/business/entities/organizationMemberCache/organizationMemberCache.ts b/entities/organizationMemberCache/organizationMemberCache.ts similarity index 93% rename from business/entities/organizationMemberCache/organizationMemberCache.ts rename to entities/organizationMemberCache/organizationMemberCache.ts index 98d9506a5..87a2e5b27 100644 --- a/business/entities/organizationMemberCache/organizationMemberCache.ts +++ b/entities/organizationMemberCache/organizationMemberCache.ts @@ -3,25 +3,25 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; -import { OrganizationMembershipRole } from '../../../interfaces'; -import { stringOrNumberAsString } from '../../../lib/utils'; +} from '../../lib/entityMetadataProvider/declarations'; +import { OrganizationMembershipRole } from '../../interfaces'; +import { stringOrNumberAsString } from '../../utils'; import { PostgresJsonEntityQuery, PostgresGetAllEntities, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; -import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; -import { TableConfiguration, TableSettings } from '../../../lib/entityMetadataProvider'; +} from '../../lib/entityMetadataProvider/postgres'; +import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; +import { TableConfiguration, TableSettings } from '../../lib/entityMetadataProvider'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; -import { CreateError } from '../../../lib/transitional'; +import { CreateError } from '../../transitional'; const type = new EntityMetadataType('OrganizationMemberCache'); diff --git a/business/entities/organizationMemberCache/organizationMemberCacheProvider.ts b/entities/organizationMemberCache/organizationMemberCacheProvider.ts similarity index 98% rename from business/entities/organizationMemberCache/organizationMemberCacheProvider.ts rename to entities/organizationMemberCache/organizationMemberCacheProvider.ts index 2aa1bdcb4..66e789707 100644 --- a/business/entities/organizationMemberCache/organizationMemberCacheProvider.ts +++ b/entities/organizationMemberCache/organizationMemberCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { OrganizationMemberCacheEntity, EntityImplementation, diff --git a/business/entities/organizationSettings/index.ts b/entities/organizationSettings/index.ts similarity index 100% rename from business/entities/organizationSettings/index.ts rename to entities/organizationSettings/index.ts diff --git a/business/entities/organizationSettings/organizationSetting.ts b/entities/organizationSettings/organizationSetting.ts similarity index 89% rename from business/entities/organizationSettings/organizationSetting.ts rename to entities/organizationSettings/organizationSetting.ts index 5ce2cee28..3b1705f60 100644 --- a/business/entities/organizationSettings/organizationSetting.ts +++ b/entities/organizationSettings/organizationSetting.ts @@ -3,15 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; +} from '../../lib/entityMetadataProvider/declarations'; import { Type } from './type'; -import { PostgresGetAllEntities } from '../../../lib/entityMetadataProvider/postgres'; +import { PostgresGetAllEntities } from '../../lib/entityMetadataProvider/postgres'; import { MemoryConfiguration, MemorySettings, @@ -19,8 +19,8 @@ import { PostgresConfiguration, TableConfiguration, TableSettings, -} from '../../../lib/entityMetadataProvider'; -import { ConfigGitHubOrganization } from '../../../config/github.organizations.types'; +} from '../../lib/entityMetadataProvider'; +import { ConfigGitHubOrganization } from '../../config/github.organizations.types'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; export interface IBasicGitHubAppInstallation { @@ -29,9 +29,8 @@ export interface IBasicGitHubAppInstallation { appPurposeId?: string; } -export enum SystemTeam { +export enum SpecialTeam { Everyone = 'everyone', // teamAllMembers - OpenAccess = 'openAccess', Sudo = 'sudo', // teamSudoers GlobalSudo = 'globalSudo', // teamPortalSudoers SystemWrite = 'systemWrite', // teamAllReposWrite @@ -57,7 +56,7 @@ export enum OrganizationProperty { } export interface ISpecialTeam { - specialTeam: SystemTeam; + specialTeam: SpecialTeam; teamId: number; } @@ -159,16 +158,6 @@ export class OrganizationSetting implements IOrganizationSettingProperties { return this.#ownerToken; } - static CreateEmptyWithOldToken(token: string, notes: string, organizationId?: number) { - const settings = new OrganizationSetting(); - settings.#ownerToken = token; - if (organizationId) { - settings.organizationId = organizationId; - } - settings.operationsNotes = notes; - return settings; - } - static CreateFromStaticSettings(staticSettings: ConfigGitHubOrganization): OrganizationSetting { const clone = { ...staticSettings }; const settings = new OrganizationSetting(); @@ -271,33 +260,20 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamAllMembers as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SystemTeam.Everyone, + specialTeam: SpecialTeam.Everyone, teamId: Number(value), }); } } delete clone.teamAllMembers; - if (clone.teamOpenAccess) { - const arr = Array.isArray(clone.teamOpenAccess) - ? (clone.teamOpenAccess as any[]) - : [clone.teamOpenAccess as any]; - for (const value of arr) { - settings.specialTeams.push({ - specialTeam: SystemTeam.OpenAccess, - teamId: Number(value), - }); - } - } - delete clone.teamOpenAccess; - if (clone.teamAllReposRead) { const arr = Array.isArray(clone.teamAllReposRead) ? (clone.teamAllReposRead as any[]) : [clone.teamAllReposRead as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SystemTeam.SystemRead, + specialTeam: SpecialTeam.SystemRead, teamId: Number(value), }); } @@ -310,7 +286,7 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamAllReposWrite as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SystemTeam.SystemWrite, + specialTeam: SpecialTeam.SystemWrite, teamId: Number(value), }); } @@ -323,7 +299,7 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamAllReposAdmin as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SystemTeam.SystemAdmin, + specialTeam: SpecialTeam.SystemAdmin, teamId: Number(value), }); } @@ -336,7 +312,7 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamSudoers as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SystemTeam.Sudo, + specialTeam: SpecialTeam.Sudo, teamId: Number(value), }); } @@ -349,7 +325,7 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamPortalSudoers as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SystemTeam.GlobalSudo, + specialTeam: SpecialTeam.GlobalSudo, teamId: Number(value), }); } diff --git a/business/entities/organizationSettings/organizationSettingProvider.ts b/entities/organizationSettings/organizationSettingProvider.ts similarity index 97% rename from business/entities/organizationSettings/organizationSettingProvider.ts rename to entities/organizationSettings/organizationSettingProvider.ts index c7b7944dd..6cbf908cc 100644 --- a/business/entities/organizationSettings/organizationSettingProvider.ts +++ b/entities/organizationSettings/organizationSettingProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { OrganizationSetting, OrganizationSettingFixedQueryAll } from './organizationSetting'; import { EntityImplementation } from './organizationSetting'; diff --git a/business/entities/organizationSettings/type.ts b/entities/organizationSettings/type.ts similarity index 69% rename from business/entities/organizationSettings/type.ts rename to entities/organizationSettings/type.ts index 0d4bc1a6c..6f3cd7419 100644 --- a/business/entities/organizationSettings/type.ts +++ b/entities/organizationSettings/type.ts @@ -3,6 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataType } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataType } from '../../lib/entityMetadataProvider/entityMetadata'; export const Type = new EntityMetadataType('OrganizationSetting'); diff --git a/business/entities/repository.ts b/entities/repository.ts similarity index 92% rename from business/entities/repository.ts rename to entities/repository.ts index bb1b5bd5a..c2ca9ce3c 100644 --- a/business/entities/repository.ts +++ b/entities/repository.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { GitHubRepositoryVisibility } from '../../interfaces'; +import { GitHubRepositoryVisibility } from '../interfaces'; import { EntityMetadataBase, EntityMetadataMappings, @@ -14,9 +14,8 @@ import { keyValueMetadataField, MetadataMappingDefinition, QueryBase, -} from '../../lib/entityMetadataProvider'; -import { PostgresConfiguration, PostgresSettings } from '../../lib/entityMetadataProvider/postgres'; -import { ErrorHelper } from '../../lib/transitional'; +} from '../lib/entityMetadataProvider'; +import { PostgresConfiguration, PostgresSettings } from '../lib/entityMetadataProvider/postgres'; const type = new EntityMetadataType('RepositoryDetails'); const typeColumnValue = 'repositorydetails'; @@ -35,10 +34,7 @@ class ThisQueryBase extends QueryBase { } class ThisQuery extends ThisQueryBase { - constructor( - query: Query, - public parameters: T - ) { + constructor(query: Query, public parameters: T) { super(query); if (!this.parameters) { this.parameters = {} as T; @@ -316,21 +312,6 @@ for (let i = 0; i < fieldNames.length; i++) { } } -export async function tryGetRepositoryEntity( - repositoryProvider: IRepositoryProvider, - repositoryId: number -): Promise { - try { - const repositoryEntity = await repositoryProvider.get(repositoryId); - return repositoryEntity; - } catch (error) { - if (ErrorHelper.IsNotFound(error)) { - return null; - } - throw error; - } -} - export const EntityImplementation = { Type: type, EnsureDefinitions: () => {}, diff --git a/business/entities/repositoryCache/index.ts b/entities/repositoryCache/index.ts similarity index 100% rename from business/entities/repositoryCache/index.ts rename to entities/repositoryCache/index.ts diff --git a/business/entities/repositoryCache/repositoryCache.ts b/entities/repositoryCache/repositoryCache.ts similarity index 91% rename from business/entities/repositoryCache/repositoryCache.ts rename to entities/repositoryCache/repositoryCache.ts index f88af3a4b..78da4fe3d 100644 --- a/business/entities/repositoryCache/repositoryCache.ts +++ b/entities/repositoryCache/repositoryCache.ts @@ -3,23 +3,23 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; +} from '../../lib/entityMetadataProvider/declarations'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; -import { stringOrNumberAsString } from '../../../lib/utils'; -import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; -import { Operations } from '../../operations'; -import { TableConfiguration } from '../../../lib/entityMetadataProvider'; +} from '../../lib/entityMetadataProvider/postgres'; +import { stringOrNumberAsString } from '../../utils'; +import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; +import { Operations } from '../../business/operations'; +import { TableConfiguration } from '../../lib/entityMetadataProvider'; const type = new EntityMetadataType('RepositoryCache'); diff --git a/business/entities/repositoryCache/repositoryCacheProvider.ts b/entities/repositoryCache/repositoryCacheProvider.ts similarity index 98% rename from business/entities/repositoryCache/repositoryCacheProvider.ts rename to entities/repositoryCache/repositoryCacheProvider.ts index 08b868c62..9109917d2 100644 --- a/business/entities/repositoryCache/repositoryCacheProvider.ts +++ b/entities/repositoryCache/repositoryCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { RepositoryCacheEntity, EntityImplementation, diff --git a/business/entities/repositoryCollaboratorCache/index.ts b/entities/repositoryCollaboratorCache/index.ts similarity index 100% rename from business/entities/repositoryCollaboratorCache/index.ts rename to entities/repositoryCollaboratorCache/index.ts diff --git a/business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts b/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts similarity index 94% rename from business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts rename to entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts index c701be627..72e3c7a53 100644 --- a/business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts +++ b/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts @@ -3,23 +3,23 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; -import { GitHubCollaboratorType, GitHubRepositoryPermission } from '../../../interfaces'; +} from '../../lib/entityMetadataProvider/declarations'; +import { GitHubCollaboratorType, GitHubRepositoryPermission } from '../../interfaces'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; -import { stringOrNumberAsString } from '../../../lib/utils'; -import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; -import { TableConfiguration } from '../../../lib/entityMetadataProvider'; +} from '../../lib/entityMetadataProvider/postgres'; +import { stringOrNumberAsString } from '../../utils'; +import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; +import { TableConfiguration } from '../../lib/entityMetadataProvider'; const type = new EntityMetadataType('RepositoryCollaboratorCache'); diff --git a/business/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts b/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts similarity index 99% rename from business/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts rename to entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts index 93dd18710..b7da8d4d3 100644 --- a/business/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts +++ b/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { RepositoryCollaboratorCacheEntity, EntityImplementation, diff --git a/business/entities/repositoryMetadata/index.ts b/entities/repositoryMetadata/index.ts similarity index 100% rename from business/entities/repositoryMetadata/index.ts rename to entities/repositoryMetadata/index.ts diff --git a/business/entities/repositoryMetadata/repositoryMetadata.ts b/entities/repositoryMetadata/repositoryMetadata.ts similarity index 95% rename from business/entities/repositoryMetadata/repositoryMetadata.ts rename to entities/repositoryMetadata/repositoryMetadata.ts index 015290fb0..c762557aa 100644 --- a/business/entities/repositoryMetadata/repositoryMetadata.ts +++ b/entities/repositoryMetadata/repositoryMetadata.ts @@ -3,28 +3,28 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import type { IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { type IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; +} from '../../lib/entityMetadataProvider/declarations'; import { Type } from './type'; import { PostgresGetAllEntities, PostgresGetByID, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; -import { TableSettings } from '../../../lib/entityMetadataProvider/table'; -import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +} from '../../lib/entityMetadataProvider/postgres'; +import { TableConfiguration, TableSettings } from '../../lib/entityMetadataProvider/table'; +import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; import { GitHubRepositoryVisibility, IInitialTeamPermission, RepositoryLockdownState, -} from '../../../interfaces/github/repos'; +} from '../../interfaces/github/repos'; const type = Type; diff --git a/business/entities/repositoryMetadata/repositoryMetadataProvider.ts b/entities/repositoryMetadata/repositoryMetadataProvider.ts similarity index 98% rename from business/entities/repositoryMetadata/repositoryMetadataProvider.ts rename to entities/repositoryMetadata/repositoryMetadataProvider.ts index 754486fb6..9cd0d39b2 100644 --- a/business/entities/repositoryMetadata/repositoryMetadataProvider.ts +++ b/entities/repositoryMetadata/repositoryMetadataProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { RepositoryMetadataEntity, RepositoryMetadataFixedQueryAll, diff --git a/business/entities/repositoryMetadata/type.ts b/entities/repositoryMetadata/type.ts similarity index 68% rename from business/entities/repositoryMetadata/type.ts rename to entities/repositoryMetadata/type.ts index 3c560ca42..d86789e50 100644 --- a/business/entities/repositoryMetadata/type.ts +++ b/entities/repositoryMetadata/type.ts @@ -3,6 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataType } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataType } from '../../lib/entityMetadataProvider/entityMetadata'; export const Type = new EntityMetadataType('Repository'); diff --git a/business/entities/repositoryTeamCache/index.ts b/entities/repositoryTeamCache/index.ts similarity index 100% rename from business/entities/repositoryTeamCache/index.ts rename to entities/repositoryTeamCache/index.ts diff --git a/business/entities/repositoryTeamCache/repositoryTeamCache.ts b/entities/repositoryTeamCache/repositoryTeamCache.ts similarity index 93% rename from business/entities/repositoryTeamCache/repositoryTeamCache.ts rename to entities/repositoryTeamCache/repositoryTeamCache.ts index c6a0cf66e..2d4147517 100644 --- a/business/entities/repositoryTeamCache/repositoryTeamCache.ts +++ b/entities/repositoryTeamCache/repositoryTeamCache.ts @@ -3,24 +3,24 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; +} from '../../lib/entityMetadataProvider/declarations'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresJsonEntityQueryMultiple, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; -import { stringOrNumberAsString } from '../../../lib/utils'; -import { GitHubRepositoryPermission } from '../../../interfaces/github/repos'; -import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; -import { TableConfiguration } from '../../../lib/entityMetadataProvider'; +} from '../../lib/entityMetadataProvider/postgres'; +import { stringOrNumberAsString } from '../../utils'; +import { GitHubRepositoryPermission } from '../../interfaces/github/repos'; +import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; +import { TableConfiguration } from '../../lib/entityMetadataProvider'; const type = new EntityMetadataType('RepositoryTeamCache'); diff --git a/business/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts b/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts similarity index 98% rename from business/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts rename to entities/repositoryTeamCache/repositoryTeamCacheProvider.ts index f22fd79d4..72fb0a38a 100644 --- a/business/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts +++ b/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { RepositoryTeamCacheEntity, EntityImplementation, diff --git a/business/entities/teamCache/index.ts b/entities/teamCache/index.ts similarity index 97% rename from business/entities/teamCache/index.ts rename to entities/teamCache/index.ts index aef008643..57d9f81a8 100644 --- a/business/entities/teamCache/index.ts +++ b/entities/teamCache/index.ts @@ -4,7 +4,7 @@ // import { ITeamCacheProvider, ITeamCacheCreateOptions, TeamCacheProvider } from './teamCacheProvider'; -import { FixedQueryType, IEntityMetadataFixedQuery } from '../../../lib/entityMetadataProvider/query'; +import { FixedQueryType, IEntityMetadataFixedQuery } from '../../lib/entityMetadataProvider/query'; export async function CreateTeamCacheProviderInstance( options?: ITeamCacheCreateOptions diff --git a/business/entities/teamCache/teamCache.ts b/entities/teamCache/teamCache.ts similarity index 89% rename from business/entities/teamCache/teamCache.ts rename to entities/teamCache/teamCache.ts index 99bb3592c..f5f3f3ffb 100644 --- a/business/entities/teamCache/teamCache.ts +++ b/entities/teamCache/teamCache.ts @@ -3,23 +3,23 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; +} from '../../lib/entityMetadataProvider/declarations'; import { PostgresJsonEntityQuery, PostgresGetAllEntities, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; +} from '../../lib/entityMetadataProvider/postgres'; import { TeamCacheFixedQueryByOrganizationId, TeamCacheDeleteByOrganizationId } from '.'; -import { stringOrNumberAsString } from '../../../lib/utils'; -import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; -import { TableConfiguration } from '../../../lib/entityMetadataProvider'; +import { stringOrNumberAsString } from '../../utils'; +import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; +import { TableConfiguration } from '../../lib/entityMetadataProvider'; const type = new EntityMetadataType('TeamCache'); diff --git a/business/entities/teamCache/teamCacheProvider.ts b/entities/teamCache/teamCacheProvider.ts similarity index 98% rename from business/entities/teamCache/teamCacheProvider.ts rename to entities/teamCache/teamCacheProvider.ts index 326aca957..dc29686b8 100644 --- a/business/entities/teamCache/teamCacheProvider.ts +++ b/entities/teamCache/teamCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { TeamCacheEntity } from './teamCache'; import { TeamCacheFixedQueryAll, diff --git a/business/entities/teamJoinApproval/approvalProvider.ts b/entities/teamJoinApproval/approvalProvider.ts similarity index 90% rename from business/entities/teamJoinApproval/approvalProvider.ts rename to entities/teamJoinApproval/approvalProvider.ts index 7e3988fc6..95a9acaad 100644 --- a/business/entities/teamJoinApproval/approvalProvider.ts +++ b/entities/teamJoinApproval/approvalProvider.ts @@ -4,7 +4,7 @@ // import { TeamJoinApprovalEntity } from './teamJoinApproval'; -import { IEntityMetadataProvider } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadataProvider } from '../../lib/entityMetadataProvider/entityMetadataProvider'; export interface IApprovalProvider { initialize(): Promise; diff --git a/business/entities/teamJoinApproval/index.ts b/entities/teamJoinApproval/index.ts similarity index 63% rename from business/entities/teamJoinApproval/index.ts rename to entities/teamJoinApproval/index.ts index ec378ba3c..a7936f8bd 100644 --- a/business/entities/teamJoinApproval/index.ts +++ b/entities/teamJoinApproval/index.ts @@ -3,8 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IApprovalProvider, IApprovalProviderCreateOptions } from './approvalProvider'; -import { TeamJoinApprovalProvider } from './teamJoinApprovalProvider'; +import { + IApprovalProvider, + IApprovalProviderCreateOptions, +} from '../../entities/teamJoinApproval/approvalProvider'; +import { TeamJoinApprovalProvider } from '../../entities/teamJoinApproval/teamJoinApprovalProvider'; export async function createAndInitializeApprovalProviderInstance( options: IApprovalProviderCreateOptions diff --git a/business/entities/teamJoinApproval/teamJoinApproval.ts b/entities/teamJoinApproval/teamJoinApproval.ts similarity index 96% rename from business/entities/teamJoinApproval/teamJoinApproval.ts rename to entities/teamJoinApproval/teamJoinApproval.ts index 443d39372..e9a049b2b 100644 --- a/business/entities/teamJoinApproval/teamJoinApproval.ts +++ b/entities/teamJoinApproval/teamJoinApproval.ts @@ -5,22 +5,22 @@ import { randomUUID } from 'crypto'; -import { IObjectWithDefinedKeys } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IObjectWithDefinedKeys } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; import { MetadataMappingDefinition, EntityMetadataMappings, -} from '../../../lib/entityMetadataProvider/declarations'; -import { FixedQueryType, IEntityMetadataFixedQuery } from '../../../lib/entityMetadataProvider/query'; -import { stringOrNumberAsString, stringOrNumberArrayAsStringArray } from '../../../lib/utils'; +} from '../../lib/entityMetadataProvider/declarations'; +import { FixedQueryType, IEntityMetadataFixedQuery } from '../../lib/entityMetadataProvider/query'; +import { stringOrNumberAsString, stringOrNumberArrayAsStringArray } from '../../utils'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; -import { TableSettings } from '../../../lib/entityMetadataProvider/table'; -import { MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +} from '../../lib/entityMetadataProvider/postgres'; +import { TableSettings } from '../../lib/entityMetadataProvider/table'; +import { MemorySettings } from '../../lib/entityMetadataProvider/memory'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; const type = new EntityMetadataType('TeamJoinRequest'); diff --git a/business/entities/teamJoinApproval/teamJoinApprovalProvider.ts b/entities/teamJoinApproval/teamJoinApprovalProvider.ts similarity index 98% rename from business/entities/teamJoinApproval/teamJoinApprovalProvider.ts rename to entities/teamJoinApproval/teamJoinApprovalProvider.ts index 1a5bb4691..2cf004b0f 100644 --- a/business/entities/teamJoinApproval/teamJoinApprovalProvider.ts +++ b/entities/teamJoinApproval/teamJoinApprovalProvider.ts @@ -7,7 +7,7 @@ import { IApprovalProvider } from './approvalProvider'; import { IEntityMetadataBaseOptions, EntityMetadataBase, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { TeamJoinApprovalEntity, TeamJoinRequestFixedQueryByTeam, diff --git a/business/entities/teamMemberCache/index.ts b/entities/teamMemberCache/index.ts similarity index 95% rename from business/entities/teamMemberCache/index.ts rename to entities/teamMemberCache/index.ts index d799cc026..652f1b78a 100644 --- a/business/entities/teamMemberCache/index.ts +++ b/entities/teamMemberCache/index.ts @@ -8,7 +8,7 @@ import { ITeamMemberCacheCreateOptions, TeamMemberCacheProvider, } from './teamMemberCacheProvider'; -import { FixedQueryType, IEntityMetadataFixedQuery } from '../../../lib/entityMetadataProvider/query'; +import { FixedQueryType, IEntityMetadataFixedQuery } from '../../lib/entityMetadataProvider/query'; export async function CreateTeamMemberCacheProviderInstance( options?: ITeamMemberCacheCreateOptions @@ -64,10 +64,7 @@ export class TeamMemberCacheFixedQueryByUserId implements IEntityMetadataFixedQu export class TeamMemberCacheFixedQueryByOrganizationIdAndUserId implements IEntityMetadataFixedQuery { public readonly fixedQueryType: FixedQueryType = FixedQueryType.TeamMemberCacheGetByOrganizationIdAndUserId; - constructor( - public organizationId: string, - public userId: string - ) { + constructor(public organizationId: string, public userId: string) { if (typeof this.userId !== 'string') { throw new Error(`userId ${userId} must be a string`); } diff --git a/business/entities/teamMemberCache/teamMemberCache.ts b/entities/teamMemberCache/teamMemberCache.ts similarity index 91% rename from business/entities/teamMemberCache/teamMemberCache.ts rename to entities/teamMemberCache/teamMemberCache.ts index 3a7c107a6..2cffaaa20 100644 --- a/business/entities/teamMemberCache/teamMemberCache.ts +++ b/entities/teamMemberCache/teamMemberCache.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../../lib/entityMetadataProvider/declarations'; +} from '../../lib/entityMetadataProvider/declarations'; import { TeamMemberCacheFixedQueryByOrganizationId, TeamMemberCacheFixedQueryByUserId, @@ -17,16 +17,16 @@ import { TeamMemberCacheFixedQueryByOrganizationIdAndUserId, TeamMemberCacheDeleteByOrganizationId, } from '.'; -import { GitHubTeamRole } from '../../../interfaces'; +import { GitHubTeamRole } from '../../interfaces'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../../lib/entityMetadataProvider/postgres'; -import { stringOrNumberAsString } from '../../../lib/utils'; -import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; -import { TableConfiguration } from '../../../lib/entityMetadataProvider'; +} from '../../lib/entityMetadataProvider/postgres'; +import { stringOrNumberAsString } from '../../utils'; +import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; +import { TableConfiguration } from '../../lib/entityMetadataProvider'; const type = new EntityMetadataType('TeamMemberCache'); diff --git a/business/entities/teamMemberCache/teamMemberCacheProvider.ts b/entities/teamMemberCache/teamMemberCacheProvider.ts similarity index 99% rename from business/entities/teamMemberCache/teamMemberCacheProvider.ts rename to entities/teamMemberCache/teamMemberCacheProvider.ts index dc109276a..c9083fe39 100644 --- a/business/entities/teamMemberCache/teamMemberCacheProvider.ts +++ b/entities/teamMemberCache/teamMemberCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../../lib/entityMetadataProvider/entityMetadata'; +} from '../../lib/entityMetadataProvider/entityMetadata'; import { TeamMemberCacheEntity, EntityImplementation } from './teamMemberCache'; import { TeamMemberCacheFixedQueryAll, diff --git a/business/entities/token/index.ts b/entities/token/index.ts similarity index 90% rename from business/entities/token/index.ts rename to entities/token/index.ts index 5d152e2b7..98f14a4b0 100644 --- a/business/entities/token/index.ts +++ b/entities/token/index.ts @@ -5,7 +5,7 @@ import { TokenProvider } from './tokenProvider'; import { PersonalAccessToken } from './token'; -import { IEntityMetadataBaseOptions } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataBaseOptions } from '../../lib/entityMetadataProvider/entityMetadata'; export interface ITokenProvider { initialize(): Promise; diff --git a/business/entities/token/token.ts b/entities/token/token.ts similarity index 92% rename from business/entities/token/token.ts rename to entities/token/token.ts index 518dbe6db..0c427cee0 100644 --- a/business/entities/token/token.ts +++ b/entities/token/token.ts @@ -5,28 +5,25 @@ import crypto from 'crypto'; -import { - EntityField, - IObjectWithDefinedKeys, -} from '../../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { EntityField, IObjectWithDefinedKeys } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; import { MetadataMappingDefinition, EntityMetadataMappings, -} from '../../../lib/entityMetadataProvider/declarations'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +} from '../../lib/entityMetadataProvider/declarations'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { TokenGenerator } from './tokenGenerator'; import { QueryTokensByCorporateID } from './tokenProvider'; import { Type } from './type'; -import { TableSettings } from '../../../lib/entityMetadataProvider/table'; -import { MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +import { TableSettings } from '../../lib/entityMetadataProvider/table'; +import { MemorySettings } from '../../lib/entityMetadataProvider/memory'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; import { PostgresConfiguration, PostgresJsonEntityQuery, PostgresSettings, -} from '../../../lib/entityMetadataProvider/postgres'; -import type { ApiClientGroupDisplay } from '../../../interfaces/api'; +} from '../../lib/entityMetadataProvider/postgres'; +import type { ApiClientGroupDisplay } from '../../interfaces/api'; const type = Type; @@ -170,19 +167,6 @@ export class PersonalAccessToken implements IObjectWithDefinedKeys, ITokenEntity return apis.includes(scope.toLowerCase()); } - hasAnyScope(scope: string[]) { - if (!this.scopes) { - return false; - } - const apis = this.scopes.toLowerCase().split(','); - for (let i = 0; i < scope.length; i++) { - if (apis.includes(scope[i].toLowerCase())) { - return true; - } - } - return false; - } - hasOrganizationScope(orgName: string) { if (!this.organizationScopes) { return false; diff --git a/business/entities/token/tokenGenerator.ts b/entities/token/tokenGenerator.ts similarity index 100% rename from business/entities/token/tokenGenerator.ts rename to entities/token/tokenGenerator.ts diff --git a/business/entities/token/tokenProvider.ts b/entities/token/tokenProvider.ts similarity index 95% rename from business/entities/token/tokenProvider.ts rename to entities/token/tokenProvider.ts index 6ad5b13bb..19f61926d 100644 --- a/business/entities/token/tokenProvider.ts +++ b/entities/token/tokenProvider.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataBase } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataBase } from '../../lib/entityMetadataProvider/entityMetadata'; import { PersonalAccessToken, EntityImplementation } from './token'; import { ITokenProvider, ITokenProviderCreateOptions } from '.'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; import { Type } from './type'; const thisProviderType = Type; diff --git a/business/entities/token/type.ts b/entities/token/type.ts similarity index 68% rename from business/entities/token/type.ts rename to entities/token/type.ts index a0ca4ea4e..8d70d2f71 100644 --- a/business/entities/token/type.ts +++ b/entities/token/type.ts @@ -3,6 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataType } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataType } from '../../lib/entityMetadataProvider/entityMetadata'; export const Type = new EntityMetadataType('Token'); diff --git a/business/entities/userSettings.ts b/entities/userSettings.ts similarity index 92% rename from business/entities/userSettings.ts rename to entities/userSettings.ts index a8756c1c8..10a12a7a0 100644 --- a/business/entities/userSettings.ts +++ b/entities/userSettings.ts @@ -8,13 +8,13 @@ import { IEntityMetadataBaseOptions, EntityMetadataBase, IEntityMetadata, -} from '../../lib/entityMetadataProvider/entityMetadata'; -import { QueryBase, IEntityMetadataFixedQuery } from '../../lib/entityMetadataProvider/query'; +} from '../lib/entityMetadataProvider/entityMetadata'; +import { QueryBase, IEntityMetadataFixedQuery } from '../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; -import { PostgresConfiguration, PostgresSettings } from '../../lib/entityMetadataProvider/postgres'; +} from '../lib/entityMetadataProvider/declarations'; +import { PostgresConfiguration, PostgresSettings } from '../lib/entityMetadataProvider/postgres'; const type = new EntityMetadataType('UserSettings'); const thisProviderType = type; @@ -33,10 +33,7 @@ class UserSettingsQueryBase extends QueryBase { } class UserSettingsQuery extends UserSettingsQueryBase { - constructor( - query: Query, - public parameters: T - ) { + constructor(query: Query, public parameters: T) { super(query); if (!this.parameters) { this.parameters = {} as T; diff --git a/features/graphTeamSync.ts b/features/graphTeamSync.ts new file mode 100644 index 000000000..e1c8c4777 --- /dev/null +++ b/features/graphTeamSync.ts @@ -0,0 +1,31 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { Team } from '../business'; +import { IProviders } from '../interfaces'; + +export class GraphTeamSync { + #team: Team; + #providers: IProviders; + + constructor(providers: IProviders, team: Team) { + this.#providers = providers; + this.#team = team; + } + + // On the GitHub side, they define: + // - The team must not have any sub-teams (must be a leaf node) + // - Can have up to 5 directory groups assigned to the team + // - Team Maintainers are not touched (TBD need to confirm) + // - If you suspend sync, it removes all the members + + // Unknowns: + // - What happens if the sole maint leaves... guess it just becomes an orphan team + // - How to handle removed directory groups + // - How much to store, log, show in the UI, or notify people about + + // Value-adds: + // - When a user links for the first time, kick off a job to evaluate the directory groups they're in +} diff --git a/business/features/index.ts b/features/index.ts similarity index 100% rename from business/features/index.ts rename to features/index.ts diff --git a/business/features/newRepositories/actions/createReadme.ts b/features/newRepositories/actions/createReadme.ts similarity index 93% rename from business/features/newRepositories/actions/createReadme.ts rename to features/newRepositories/actions/createReadme.ts index 1fb6fc636..738600562 100644 --- a/business/features/newRepositories/actions/createReadme.ts +++ b/features/newRepositories/actions/createReadme.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../..'; -import { ErrorHelper } from '../../../../lib/transitional'; +import { Repository } from '../../../business'; +import { ErrorHelper } from '../../../transitional'; import { setupRepositoryReadmeSubstring } from '../strings'; export async function tryCreateReadme(repository: Repository, log: string[]): Promise { diff --git a/business/features/newRepositories/actions/deleteFork.ts b/features/newRepositories/actions/deleteFork.ts similarity index 93% rename from business/features/newRepositories/actions/deleteFork.ts rename to features/newRepositories/actions/deleteFork.ts index a15ff479a..e68aa7cef 100644 --- a/business/features/newRepositories/actions/deleteFork.ts +++ b/features/newRepositories/actions/deleteFork.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../..'; +import { Repository } from '../../../business'; export async function immediatelyDeleteFork(log: string[], repository: Repository): Promise { const organization = repository.organization; diff --git a/business/features/newRepositories/actions/downgradeCollaborator.ts b/features/newRepositories/actions/downgradeCollaborator.ts similarity index 87% rename from business/features/newRepositories/actions/downgradeCollaborator.ts rename to features/newRepositories/actions/downgradeCollaborator.ts index ad1698e02..127826cf6 100644 --- a/business/features/newRepositories/actions/downgradeCollaborator.ts +++ b/features/newRepositories/actions/downgradeCollaborator.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../..'; -import { GitHubRepositoryPermission } from '../../../../interfaces'; +import { Repository } from '../../../business'; +import { GitHubRepositoryPermission } from '../../../interfaces'; export async function tryDowngradeCollaborator( repository: Repository, diff --git a/business/features/newRepositories/actions/dropCollaborator.ts b/features/newRepositories/actions/dropCollaborator.ts similarity index 93% rename from business/features/newRepositories/actions/dropCollaborator.ts rename to features/newRepositories/actions/dropCollaborator.ts index 508aef375..2382c1b3a 100644 --- a/business/features/newRepositories/actions/dropCollaborator.ts +++ b/features/newRepositories/actions/dropCollaborator.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../..'; +import { Repository } from '../../../business'; export async function tryDropCollaborator( repository: Repository, diff --git a/business/features/newRepositories/actions/dropTeam.ts b/features/newRepositories/actions/dropTeam.ts similarity index 93% rename from business/features/newRepositories/actions/dropTeam.ts rename to features/newRepositories/actions/dropTeam.ts index 62af1b5ef..186a73566 100644 --- a/business/features/newRepositories/actions/dropTeam.ts +++ b/features/newRepositories/actions/dropTeam.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository, Team } from '../../..'; +import { Repository, Team } from '../../../business'; export async function tryDropTeam(repository: Repository, team: Team, log: string[]): Promise { const organization = repository.organization; diff --git a/business/features/newRepositories/actions/index.ts b/features/newRepositories/actions/index.ts similarity index 100% rename from business/features/newRepositories/actions/index.ts rename to features/newRepositories/actions/index.ts diff --git a/business/features/newRepositories/actions/lockdown.ts b/features/newRepositories/actions/lockdown.ts similarity index 84% rename from business/features/newRepositories/actions/lockdown.ts rename to features/newRepositories/actions/lockdown.ts index de6d28b23..212537b83 100644 --- a/business/features/newRepositories/actions/lockdown.ts +++ b/features/newRepositories/actions/lockdown.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../..'; -import { GitHubCollaboratorAffiliationQuery } from '../../../../interfaces'; +import { Repository } from '../../../business'; +import { GitHubCollaboratorAffiliationQuery } from '../../../interfaces'; import { tryDowngradeCollaborator } from './downgradeCollaborator'; import { tryDropCollaborator } from './dropCollaborator'; import { tryDropTeam } from './dropTeam'; @@ -18,9 +18,9 @@ export async function lockdownRepository( const organization = repository.organization; try { const specialPermittedTeams = new Set([ - ...organization.specialSystemTeams.admin, - ...organization.specialSystemTeams.write, - ...organization.specialSystemTeams.read, + ...organization.specialRepositoryPermissionTeams.admin, + ...organization.specialRepositoryPermissionTeams.write, + ...organization.specialRepositoryPermissionTeams.read, ]); const teamPermissions = await repository.getTeamPermissions(); for (const tp of teamPermissions) { @@ -42,7 +42,7 @@ export async function lockdownRepository( if (collaborator.login.toLowerCase() !== creatorLogin.toLowerCase()) { await tryDropCollaborator(repository, collaborator.login, log); } else { - // Downgrade the creator to only having READ access + // Downgrade the creator to only having READ access (V2) if (collaborator.permissions.admin || collaborator.permissions.push) { await tryDowngradeCollaborator(repository, collaborator.login, log); } else { diff --git a/business/features/newRepositories/approve.ts b/features/newRepositories/approve.ts similarity index 97% rename from business/features/newRepositories/approve.ts rename to features/newRepositories/approve.ts index ec731b651..051711e10 100644 --- a/business/features/newRepositories/approve.ts +++ b/features/newRepositories/approve.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Repository } from '../..'; +import { Operations, Repository } from '../../business'; import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; -import { ICachedEmployeeInformation, RepositoryLockdownState } from '../../../interfaces'; -import { IMail } from '../../../lib/mailProvider'; +import { ICachedEmployeeInformation, RepositoryLockdownState } from '../../interfaces'; +import { IMail } from '../../lib/mailProvider'; import { IMailToRemoveAdministrativeLock } from './interfaces'; export async function administrativeApproval( diff --git a/business/features/newRepositories/initializeMetadata.ts b/features/newRepositories/initializeMetadata.ts similarity index 84% rename from business/features/newRepositories/initializeMetadata.ts rename to features/newRepositories/initializeMetadata.ts index fd53feef0..ef6217d42 100644 --- a/business/features/newRepositories/initializeMetadata.ts +++ b/features/newRepositories/initializeMetadata.ts @@ -4,8 +4,7 @@ // import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; -import { GitHubRepositoryVisibility, ICorporateLink } from '../../../interfaces'; -import { ErrorHelper } from '../../../lib/transitional'; +import { GitHubRepositoryVisibility, ICorporateLink } from '../../interfaces'; import { RepositoryLockdownCreateOptions } from './interfaces'; export async function initializeRepositoryMetadata(parameters: RepositoryLockdownCreateOptions) { @@ -20,7 +19,7 @@ export async function initializeRepositoryMetadata(parameters: RepositoryLockdow instances, } = parameters; const { repository } = instances; - const { insights, repositoryMetadataProvider } = providers; + const { repositoryMetadataProvider } = providers; const { organization } = repository; try { // Repository metadata is used to lock down the security of the repository setup system. Only @@ -29,20 +28,8 @@ export async function initializeRepositoryMetadata(parameters: RepositoryLockdow let repositoryMetadata: RepositoryMetadataEntity = null; try { repositoryMetadata = await repositoryMetadataProvider.getRepositoryMetadata(String(repository.id)); - } catch (error) { - if (!ErrorHelper.IsNotFound(error)) { - insights?.trackException({ - exception: error, - properties: { - content: 'RepositoryMetadataProviderGetRepositoryMetadataError', - message: error.message, - repositoryId: repository.id.toString(), - repositoryName: repository.name, - organizationName: organization.name, - organizationId: organization.id.toString(), - }, - }); - } + } catch (doesNotExist) { + // ignore: 404 is standard here } if (repositoryMetadata) { lockdownLog.push(`Repository metadata already exists for repository ID ${repository.id}`); diff --git a/business/features/newRepositories/interfaces.ts b/features/newRepositories/interfaces.ts similarity index 86% rename from business/features/newRepositories/interfaces.ts rename to features/newRepositories/interfaces.ts index d4c07f067..7d5a19cea 100644 --- a/business/features/newRepositories/interfaces.ts +++ b/features/newRepositories/interfaces.ts @@ -3,11 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { TelemetryClient } from 'applicationinsights'; - -import { Operations, Organization, Repository } from '../..'; +import { Operations, Organization, Repository } from '../../business'; import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; -import { ICorporateLink, RepositoryLockdownState } from '../../../interfaces'; +import { ICorporateLink, RepositoryLockdownState } from '../../interfaces'; export enum RepositoryLockdownCreateType { Created = 'created', @@ -15,7 +13,6 @@ export enum RepositoryLockdownCreateType { } export type RepositoryLockdownCreateProviders = { - insights: TelemetryClient; operations: Operations; repositoryMetadataProvider: IRepositoryMetadataProvider; }; @@ -76,10 +73,9 @@ export interface IMailToLockdownRepo { isForkDeleted: boolean; } -export type NewRepositoryLockdownSystemOptions = { - insights: TelemetryClient; +export interface INewRepositoryLockdownSystemOptions { operations: Operations; organization: Organization; repository: Repository; repositoryMetadataProvider: IRepositoryMetadataProvider; -}; +} diff --git a/business/features/newRepositories/lockdownMail.ts b/features/newRepositories/lockdownMail.ts similarity index 97% rename from business/features/newRepositories/lockdownMail.ts rename to features/newRepositories/lockdownMail.ts index ce4a9edbe..0fba395dc 100644 --- a/business/features/newRepositories/lockdownMail.ts +++ b/features/newRepositories/lockdownMail.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Repository } from '../..'; -import { ICachedEmployeeInformation, ICorporateLink, RepositoryLockdownState } from '../../../interfaces'; -import { IMail } from '../../../lib/mailProvider'; -import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; +import { Operations, Repository } from '../../business'; +import { ICachedEmployeeInformation, ICorporateLink, RepositoryLockdownState } from '../../interfaces'; +import { IMail } from '../../lib/mailProvider'; +import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; import { ILockdownResult, IMailToLockdownRepo, RepositoryLockdownCreateType } from './interfaces'; const defaultMailTemplate = 'newrepolockdown'; diff --git a/business/features/newRepositories/newRepositoryLockdown.ts b/features/newRepositories/newRepositoryLockdown.ts similarity index 85% rename from business/features/newRepositories/newRepositoryLockdown.ts rename to features/newRepositories/newRepositoryLockdown.ts index 4a5dfe90c..3ae9829de 100644 --- a/business/features/newRepositories/newRepositoryLockdown.ts +++ b/features/newRepositories/newRepositoryLockdown.ts @@ -3,20 +3,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Organization, Repository } from '../..'; +import { Operations, Organization, Repository } from '../../business'; import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; -import { botBracket } from '../../../lib/utils'; +import { botBracket } from '../../utils'; import { ICorporateLink, RepositoryLockdownState, NoCacheNoBackground, OrganizationMembershipState, OrganizationMembershipRole, -} from '../../../interfaces'; -import { CreateError } from '../../../lib/transitional'; +} from '../../interfaces'; +import { CreateError } from '../../transitional'; import { ILockdownResult, - NewRepositoryLockdownSystemOptions, + INewRepositoryLockdownSystemOptions, IRepoPatch, RepositoryLockdownCreateOptions, RepositoryLockdownCreateType, @@ -29,10 +29,8 @@ import { setupRepositorySubstring } from './strings'; import { immediatelyDeleteFork, tryCreateReadme } from './actions'; import { repositoryLockdownStatics } from './staticFunctions'; import { lockdownRepository } from './actions/lockdown'; -import { TelemetryClient } from 'applicationinsights'; export default class NewRepositoryLockdownSystem { - insights: TelemetryClient; organization: Organization; operations: Operations; repository: Repository; @@ -42,8 +40,7 @@ export default class NewRepositoryLockdownSystem { private readonly lockdownForks: boolean; private readonly lockdownTransfers: boolean; - constructor(options: NewRepositoryLockdownSystemOptions) { - this.insights = options.insights; + constructor(options: INewRepositoryLockdownSystemOptions) { this.organization = options.organization; this.operations = options.operations; this.repository = options.repository; @@ -111,7 +108,6 @@ export default class NewRepositoryLockdownSystem { repository: this.repository, }, providers: { - insights: this.insights, repositoryMetadataProvider: this.repositoryMetadataProvider, operations: this.operations, }, @@ -166,22 +162,20 @@ export default class NewRepositoryLockdownSystem { if (!this.organization.isNewRepositoryLockdownSystemEnabled()) { return { wasLocked: false, notifyOperations: false }; } - // informationalLog.push( - // `Confirmed that the ${this.organization.name} organization has opted into the new repository lockdown system` - // ); - // if (this.deleteForks) { - // informationalLog.push( - // 'Confirmed that the delete fork feature is enabled for this org. It will supersede fork lockdown capabilities.' - // ); - // } - // if (this.lockdownForks) { - // informationalLog.push('Confirmed that the additional fork lockdown feature is enabled for this org'); - // } - // if (this.lockdownTransfers) { - // informationalLog.push( - // 'Confirmed that the additional transfer lockdown feature is enabled for this org' - // ); - // } + lockdownLog.push( + `Confirmed that the ${this.organization.name} organization has opted into the new repository lockdown system` + ); + if (this.deleteForks) { + lockdownLog.push( + 'Confirmed that the delete fork feature is enabled for this org. It will supersede fork lockdown capabilities.' + ); + } + if (this.lockdownForks) { + lockdownLog.push('Confirmed that the additional fork lockdown feature is enabled for this org'); + } + if (this.lockdownTransfers) { + lockdownLog.push('Confirmed that the additional transfer lockdown feature is enabled for this org'); + } const setupUrl = `${this.organization.absoluteBaseUrl}wizard?existingreponame=${this.repository.name}&existingrepoid=${this.repository.id}`; const isTransfer = action === RepositoryLockdownCreateType.Transferred; if (isTransfer && !this.lockdownTransfers) { @@ -204,7 +198,7 @@ export default class NewRepositoryLockdownSystem { lockdownLog.push(`Created by a bot or GitHub App: ${username}`); return { wasLocked: false, log: lockdownLog, notifyOperations: false }; } - // informationalLog.push(`Confirmed that the repository was not ${action} by a bot`); + lockdownLog.push(`Confirmed that the repository was not ${action} by a bot`); // a repository created by one of the operations accounts in the allowed list is OK and will not be locked down const systemAccounts = new Set( this.operations.systemAccountsByUsername.map((username) => username.toLowerCase()) @@ -213,11 +207,11 @@ export default class NewRepositoryLockdownSystem { lockdownLog.push(`Created by a system account: ${username}`); return { wasLocked: false, log: lockdownLog, notifyOperations: true }; } - // informationalLog.push( - // `Confirmed that the repository was not ${action} by any of the system accounts: ${Array.from( - // systemAccounts.values() - // ).join(', ')}` - // ); + lockdownLog.push( + `Confirmed that the repository was not ${action} by any of the system accounts: ${Array.from( + systemAccounts.values() + ).join(', ')}` + ); const userMembership = await this.organization.getMembership(username, NoCacheNoBackground); let userIsOrganizationOwner = false; if ( @@ -267,13 +261,13 @@ export default class NewRepositoryLockdownSystem { const patchChanges: IRepoPatch = {}; if (!isFork && !isTransfer && !this.repository.private) { - // informationalLog.push('Preparing to hide the public repository pending setup'); + lockdownLog.push('Preparing to hide the public repository pending setup (V2)'); patchChanges.private = true; } if (!isFork) { - // informationalLog.push('Updating the description and web site to point at the setup wizard'); - // informationalLog.push(`Will direct the user to ${setupUrl}`); - patchChanges.description = setupRepositorySubstring; + lockdownLog.push('Updating the description and web site to point at the setup wizard (V2)'); + lockdownLog.push(`Will direct the user to ${setupUrl}`); + patchChanges.description = `${setupRepositorySubstring} ${setupUrl}`; patchChanges.homepage = setupUrl; } if (Object.getOwnPropertyNames(patchChanges).length > 0) { @@ -286,7 +280,7 @@ export default class NewRepositoryLockdownSystem { lockdownLog.push(`Updating repository with patch ${descriptiveUpdate}`); await this.repository.update(patchChanges); } catch (hideError) { - lockdownLog.push(`Error while trying to update the new repo: ${hideError}`); + lockdownLog.push(`Error while trying to update the new repo: ${hideError} (V2)`); } } } diff --git a/business/features/newRepositories/selfServiceDelete.ts b/features/newRepositories/selfServiceDelete.ts similarity index 97% rename from business/features/newRepositories/selfServiceDelete.ts rename to features/newRepositories/selfServiceDelete.ts index 9e5fbbdb2..9d4374c6d 100644 --- a/business/features/newRepositories/selfServiceDelete.ts +++ b/features/newRepositories/selfServiceDelete.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Repository } from '../..'; +import { Operations, Repository } from '../../business'; import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; -import { ICachedEmployeeInformation, RepositoryLockdownState } from '../../../interfaces'; -import { IMail } from '../../../lib/mailProvider'; +import { ICachedEmployeeInformation, RepositoryLockdownState } from '../../interfaces'; +import { IMail } from '../../lib/mailProvider'; export async function selfServiceDeleteLockedRepository( operations: Operations, diff --git a/business/features/newRepositories/staticFunctions.ts b/features/newRepositories/staticFunctions.ts similarity index 90% rename from business/features/newRepositories/staticFunctions.ts rename to features/newRepositories/staticFunctions.ts index d5e225f6b..2044ce2c3 100644 --- a/business/features/newRepositories/staticFunctions.ts +++ b/features/newRepositories/staticFunctions.ts @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../..'; +import { Repository } from '../../business'; import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; -import { IndividualContext } from '../../user'; +import { IndividualContext } from '../../business/user'; import { validateUserCanSelfDeleteRepository } from './validateSelfServiceDelete'; import { validateUserCanConfigureRepository } from './validateSelfServiceSetup'; diff --git a/business/features/newRepositories/strings.ts b/features/newRepositories/strings.ts similarity index 100% rename from business/features/newRepositories/strings.ts rename to features/newRepositories/strings.ts diff --git a/business/features/newRepositories/validateSelfServiceDelete.ts b/features/newRepositories/validateSelfServiceDelete.ts similarity index 90% rename from business/features/newRepositories/validateSelfServiceDelete.ts rename to features/newRepositories/validateSelfServiceDelete.ts index e1f3cc714..d16bf6be3 100644 --- a/business/features/newRepositories/validateSelfServiceDelete.ts +++ b/features/newRepositories/validateSelfServiceDelete.ts @@ -5,11 +5,11 @@ import { DateTime } from 'luxon'; -import { Repository } from '../..'; +import { Repository } from '../../business'; import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; -import { RepositoryLockdownState } from '../../../interfaces'; -import { IndividualContext } from '../../user'; -import { daysInMilliseconds } from '../../../lib/utils'; +import { RepositoryLockdownState } from '../../interfaces'; +import { IndividualContext } from '../../business/user'; +import { daysInMilliseconds } from '../../utils'; export async function validateUserCanSelfDeleteRepository( repository: Repository, diff --git a/business/features/newRepositories/validateSelfServiceSetup.ts b/features/newRepositories/validateSelfServiceSetup.ts similarity index 94% rename from business/features/newRepositories/validateSelfServiceSetup.ts rename to features/newRepositories/validateSelfServiceSetup.ts index edbd2cd04..dcb08455e 100644 --- a/business/features/newRepositories/validateSelfServiceSetup.ts +++ b/features/newRepositories/validateSelfServiceSetup.ts @@ -4,8 +4,8 @@ // import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; -import { RepositoryLockdownState } from '../../../interfaces'; -import { IndividualContext } from '../../user'; +import { RepositoryLockdownState } from '../../interfaces'; +import { IndividualContext } from '../../business/user'; export async function validateUserCanConfigureRepository( metadata: RepositoryMetadataEntity, diff --git a/business/features/publicReposFastFilter.ts b/features/publicReposFastFilter.ts similarity index 94% rename from business/features/publicReposFastFilter.ts rename to features/publicReposFastFilter.ts index e481faf57..b876c57f2 100644 --- a/business/features/publicReposFastFilter.ts +++ b/features/publicReposFastFilter.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IProviders } from '../../interfaces'; -import { Repository } from '..'; +import { IProviders } from '../interfaces'; +import { Repository } from '../business'; // TODO: refresh occasionally. diff --git a/business/features/sudo/index.ts b/features/sudo/index.ts similarity index 90% rename from business/features/sudo/index.ts rename to features/sudo/index.ts index f6eddcbcd..8d8791024 100644 --- a/business/features/sudo/index.ts +++ b/features/sudo/index.ts @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import type { Organization } from '../..'; -import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; -import { ICorporateLink, IProviders } from '../../../interfaces'; +import type { Organization } from '../../business'; +import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; +import { ICorporateLink, IProviders } from '../../interfaces'; export interface IOrganizationSudo { isSudoer(githubLogin: string, link?: ICorporateLink): Promise; @@ -16,10 +16,7 @@ export interface IPortalSudo { } export abstract class OrganizationSudo implements IOrganizationSudo { - constructor( - protected providers: IProviders, - protected organization: Organization - ) {} + constructor(protected providers: IProviders, protected organization: Organization) {} abstract isSudoer(githubLogin: string, link?: ICorporateLink): Promise; protected isSudoEnvironmentOff() { diff --git a/business/features/sudo/noop.ts b/features/sudo/noop.ts similarity index 65% rename from business/features/sudo/noop.ts rename to features/sudo/noop.ts index 8db9f7c00..88df28d77 100644 --- a/business/features/sudo/noop.ts +++ b/features/sudo/noop.ts @@ -4,14 +4,11 @@ // import { OrganizationSudo } from '.'; -import { Organization } from '../..'; -import { ICorporateLink, IProviders } from '../../../interfaces'; +import { Organization } from '../../business'; +import { ICorporateLink, IProviders } from '../../interfaces'; export class OrganizationSudoNoop extends OrganizationSudo { - constructor( - protected providers: IProviders, - protected organization: Organization - ) { + constructor(protected providers: IProviders, protected organization: Organization) { super(providers, organization); } diff --git a/business/features/sudo/portal.ts b/features/sudo/portal.ts similarity index 94% rename from business/features/sudo/portal.ts rename to features/sudo/portal.ts index dec705167..b87cd0635 100644 --- a/business/features/sudo/portal.ts +++ b/features/sudo/portal.ts @@ -4,10 +4,10 @@ // import { IPortalSudo } from '.'; -import { Organization } from '../..'; -import { IProviders, ICorporateLink } from '../../../interfaces'; -import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; -import { ErrorHelper } from '../../../lib/transitional'; +import { Organization } from '../../business'; +import { IProviders, ICorporateLink } from '../../interfaces'; +import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; +import { ErrorHelper } from '../../transitional'; abstract class PortalSudoBase { constructor(private providers: IProviders) {} diff --git a/business/features/sudo/securityGroup.ts b/features/sudo/securityGroup.ts similarity index 93% rename from business/features/sudo/securityGroup.ts rename to features/sudo/securityGroup.ts index 81b7fdc39..c650ed480 100644 --- a/business/features/sudo/securityGroup.ts +++ b/features/sudo/securityGroup.ts @@ -4,9 +4,9 @@ // import { OrganizationSudo } from '.'; -import { Organization } from '../..'; -import { IProviders, ICorporateLink } from '../../../interfaces'; -import { ErrorHelper } from '../../../lib/transitional'; +import { Organization } from '../../business'; +import { IProviders, ICorporateLink } from '../../interfaces'; +import { ErrorHelper } from '../../transitional'; export const OrganizationFeatureSecurityGroupProperty = 'orgsudosecuritygroup'; diff --git a/business/features/sudo/sudo.md b/features/sudo/sudo.md similarity index 90% rename from business/features/sudo/sudo.md rename to features/sudo/sudo.md index fca93b503..ff567cde5 100644 --- a/business/features/sudo/sudo.md +++ b/features/sudo/sudo.md @@ -33,6 +33,11 @@ Overrides are available to allow the company-specific system to provide the org sudo instance for an organization, if you wish to implement a different approach, or use a different company-internal system for these decisions. +### Debug flags + +There is an environmental off-switch enabled that can turn off sudo, allowing for testing +as a regular user in local environments. That env variable name is `DEBUG_GITHUB_ORG_SUDO_OFF`. + ## portal sudo Portal sudo applies sudo for all organizations configured within the application. @@ -41,7 +46,7 @@ Used by system administrators typically. The original design was to use the sudo configuration from the first/primary GitHub org that was configured in the environment. -## Feature flag: FEATURE_FLAG_ALLOW_PORTAL_SUDO +### Feature flag: FEATURE_FLAG_ALLOW_PORTAL_SUDO > This feature is not on by default. @@ -58,7 +63,7 @@ Can be: For the security group provider, configuration should set `SUDO_PORTAL_SECURITY_GROUP_ID` to the security group ID to use. -## Debug flags: portal sudo +### Debug flags Two environment variables designed for development work exist: diff --git a/business/features/sudo/teams.ts b/features/sudo/teams.ts similarity index 91% rename from business/features/sudo/teams.ts rename to features/sudo/teams.ts index ed4758cbb..f15a48536 100644 --- a/business/features/sudo/teams.ts +++ b/features/sudo/teams.ts @@ -4,9 +4,9 @@ // import { OrganizationSudo } from '.'; -import { Organization } from '../..'; -import { IProviders, ICorporateLink, GitHubTeamRole, ITeamMembershipRoleState } from '../../../interfaces'; -import { ErrorHelper } from '../../../lib/transitional'; +import { Organization } from '../../business'; +import { IProviders, ICorporateLink, GitHubTeamRole, ITeamMembershipRoleState } from '../../interfaces'; +import { ErrorHelper } from '../../transitional'; export class OrganizationSudoGitHubTeams extends OrganizationSudo { constructor(providers: IProviders, organization: Organization) { diff --git a/business/features/teamMemberToMaintainerUpgrade.ts b/features/teamMemberToMaintainerUpgrade.ts similarity index 96% rename from business/features/teamMemberToMaintainerUpgrade.ts rename to features/teamMemberToMaintainerUpgrade.ts index 5ed5daff4..f3f3f0d68 100644 --- a/business/features/teamMemberToMaintainerUpgrade.ts +++ b/features/teamMemberToMaintainerUpgrade.ts @@ -3,18 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Team } from '..'; -import { Operations } from '..'; -import { IndividualContext } from '../user'; -import { addArrayToSet } from '../../lib/utils'; -import { IMail } from '../../lib/mailProvider'; +import { Team } from '../business'; +import { Operations } from '../business'; +import { IndividualContext } from '../business/user'; +import { addArrayToSet } from '../utils'; +import { IMail } from '../lib/mailProvider'; import { NoCacheNoBackground, ITeamMembershipRoleState, OrganizationMembershipState, GitHubTeamRole, -} from '../../interfaces'; -import { ErrorHelper } from '../../lib/transitional'; +} from '../interfaces'; +import { ErrorHelper } from '../transitional'; interface ISelfServiceAllowedResult { currentMaintainerCount: number; diff --git a/index.ts b/index.ts deleted file mode 100644 index b90109b36..000000000 --- a/index.ts +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import express from 'express'; -import Debug from 'debug'; - -import type { ExecutionEnvironment, IReposApplication, SiteConfiguration } from './interfaces'; -import configResolver from './lib/config'; -import initialize from './middleware/initialize'; - -export * from './interfaces'; - -type InitializeCall = ( - executionEnvironment: ExecutionEnvironment, - config: SiteConfiguration, - configurationError: Error -) => Promise; - -export function createExpressApplication(): IReposApplication { - Debug.debug('startup')('starting web framework...'); - const app = express() as any as IReposApplication; - - app.initializeApplication = initializeApp.bind(undefined, app, express, __dirname); - app.startupApplication = commonStartup.bind( - undefined, - app.initializeApplication, - false /* not a job */, - true /* enable all apps */, - app - ); - - return app; -} - -function initializeApp( - app: IReposApplication, - express: any, - dirname: string, - executionEnvironment: ExecutionEnvironment, - config: SiteConfiguration, - configurationError: Error -) { - return initialize(executionEnvironment, app, express, dirname, config, configurationError); -} - -export async function commonStartup( - call: InitializeCall, - isJob: boolean, - enableAllGitHubApps: boolean, - app?: IReposApplication, - entrypointName?: string -) { - const executionEnvironment: ExecutionEnvironment = { - isJob, - enableAllGitHubApps, - entrypointName, - // - expressApplication: app, - // - providers: undefined, - skipModules: new Set(), - // - started: new Date(), - }; - - let painlessConfigResolver = null; - try { - painlessConfigResolver = configResolver(); - } catch (error) { - console.warn('Painless config resolver initialization error:'); - console.error(error); - throw error; - } - let config: any = null; - let configurationError: Error = null; - try { - config = await painlessConfigResolver.resolve(); - } catch (error) { - configurationError = error; - } - if (isJob) { - executionEnvironment.skipModules.add('web'); - } - try { - await call(executionEnvironment, config, configurationError); - } catch (startupError) { - console.error(`Startup error: ${startupError}`); - if (startupError.stack) { - console.error(startupError.stack); - } - process.exit(1); - } - - return executionEnvironment; -} diff --git a/interfaces/app.ts b/interfaces/app.ts index ba5d2f2d0..7520ed409 100644 --- a/interfaces/app.ts +++ b/interfaces/app.ts @@ -3,21 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Application, Response, NextFunction } from 'express'; +import { Application } from 'express'; +import { IProviders } from './providers'; -import type { IProviders } from './providers'; -import type { RuntimeConfiguration, SiteConfiguration } from './config'; -import type { ReposAppRequest } from './web'; +import type { RuntimeConfiguration } from './config'; -export type ApplicationProfile = { +export interface IApplicationProfile { applicationName: string; - customErrorHandlerRender?: ( - errorView: unknown, - err: Error, - req: ReposAppRequest, - res: Response, - next: NextFunction - ) => Promise; + customErrorHandlerRender?: (errorView: any, err: Error, req: any, res: any, next: any) => Promise; customRoutes?: () => Promise; logDependencies: boolean; serveClientAssets: boolean; @@ -26,7 +19,7 @@ export type ApplicationProfile = { startup?: (providers: IProviders) => Promise; sessions: boolean; webServer: boolean; -}; +} export interface IReposApplication extends Application { // Standard Express @@ -34,50 +27,29 @@ export interface IReposApplication extends Application { // Local things providers: IProviders; - config: SiteConfiguration; + config: any; isBackgroundJob: boolean; enableAllGitHubApps: boolean; runtimeConfiguration: RuntimeConfiguration; - executionEnvironment: ExecutionEnvironment; - startServer: () => Promise; - initializeApplication: ( - executionEnvironment: ExecutionEnvironment, - config: SiteConfiguration, - configurationError: Error - ) => Promise; - + initializeApplication: (config: any, configurationError: Error) => Promise; + initializeJob: (config: any, configurationError: Error) => Promise; startupApplication: () => Promise; + startupJob: () => Promise; runJob: ( job: (job: IReposJob) => Promise, options?: IReposJobOptions - ) => Promise; + ) => Promise; } -export type ExecutionEnvironment = { - isJob: boolean; - enableAllGitHubApps: boolean; - - expressApplication: IReposApplication | null; - - providers: IProviders; - skipModules: Set; - - entrypointName: string; - - started: Date; -}; - export interface IReposJob { app: IReposApplication; started: Date; providers: IProviders; parameters: any; args: string[]; - - executionEnvironment: ExecutionEnvironment; } export interface IReposJobResult { @@ -90,5 +62,4 @@ export interface IReposJobOptions { insightsPrefix?: string; parameters?: any; enableAllGitHubApps?: boolean; - name?: string; } diff --git a/interfaces/companySpecific/administration.ts b/interfaces/companySpecific/administration.ts index d404b5275..9d138e664 100644 --- a/interfaces/companySpecific/administration.ts +++ b/interfaces/companySpecific/administration.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import { IDictionary } from '../../interfaces'; diff --git a/interfaces/companySpecific/events/index.ts b/interfaces/companySpecific/events/index.ts deleted file mode 100644 index 016caa017..000000000 --- a/interfaces/companySpecific/events/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import type { ICompanySpecificEventsLinking } from './linking'; - -export * from './linking'; - -export interface ICompanySpecificEvents { - linking?: ICompanySpecificEventsLinking; -} diff --git a/interfaces/companySpecific/events/linking.ts b/interfaces/companySpecific/events/linking.ts deleted file mode 100644 index 6f6a55f99..000000000 --- a/interfaces/companySpecific/events/linking.ts +++ /dev/null @@ -1,11 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import type { ICorporateLink, IProviders } from '../..'; - -export interface ICompanySpecificEventsLinking { - onLink?: (providers: IProviders, link: ICorporateLink) => Promise; - onUnlink?: (providers: IProviders, corporateId: string) => Promise; -} diff --git a/interfaces/companySpecific/features/augmentApiMetadata.ts b/interfaces/companySpecific/features/augmentApiMetadata.ts index 9dc19e10c..9dab4d716 100644 --- a/interfaces/companySpecific/features/augmentApiMetadata.ts +++ b/interfaces/companySpecific/features/augmentApiMetadata.ts @@ -3,20 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Organization, Team } from '../../../business'; -import type { IProviders, TeamJsonFormat } from '../../../interfaces'; +import { Organization } from '../../../business'; +import { IProviders } from '../../../interfaces'; export interface ICompanySpecificAugmentApiMetadata { - augmentOrganizationClientJson?: ( + augmentOrganizationClientJson: ( providers: IProviders, organization: Organization, - standardJsonMetadata: object - ) => object; - - augmentTeamClientJson?: ( - providers: IProviders, - team: Team, - standardJsonMetadata: object, - jsonFormat: TeamJsonFormat - ) => Promise; + standardJsonMetadata: any + ) => any; } diff --git a/interfaces/companySpecific/features/firehose.ts b/interfaces/companySpecific/features/firehose.ts index 63656249c..90c3213f0 100644 --- a/interfaces/companySpecific/features/firehose.ts +++ b/interfaces/companySpecific/features/firehose.ts @@ -4,10 +4,9 @@ // import { IGitHubAppInstallation, IGitHubWebhookEnterprise, IProviders } from '../../../interfaces'; -import type { WebhookProcessor } from '../../../business/webhooks/organizationProcessor'; export interface ICompanySpecificFeatureFirehose { - processWebhook?: ( + processWebhook: ( providers: IProviders, body: any, eventType: string, @@ -15,6 +14,4 @@ export interface ICompanySpecificFeatureFirehose { installation: IGitHubAppInstallation, acknowledgeEvent: () => void ) => Promise; - - getAdditionalWebhookTasks?: (providers: IProviders) => Promise; } diff --git a/interfaces/companySpecific/features/index.ts b/interfaces/companySpecific/features/index.ts index 1a3ca4f66..2c821d92b 100644 --- a/interfaces/companySpecific/features/index.ts +++ b/interfaces/companySpecific/features/index.ts @@ -3,14 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import type { ICompanySpecificAugmentApiMetadata } from './augmentApiMetadata'; -import type { ICompanySpecificFeatureDemo } from './demo'; -import type { ICompanySpecificFeatureFirehose } from './firehose'; -import type { ICompanySpecificFeatureMailProvider } from './mailProvider'; -import type { ICompanySpecificFeatureOrganizationJoinAcl } from './organizationJoinAcl'; -import type { ICompanySpecificFeatureOrganizationSudo } from './organizationSudo'; -import type { ICompanySpecificFeaturePortalSudo } from './portalSudo'; -import type { ICompanySpecificFeatureRepositoryState } from './repositoryActions'; +import { ICompanySpecificAugmentApiMetadata } from './augmentApiMetadata'; +import { ICompanySpecificFeatureDemo } from './demo'; +import { ICompanySpecificFeatureFirehose } from './firehose'; +import { ICompanySpecificFeatureMailProvider } from './mailProvider'; +import { ICompanySpecificFeatureOrganizationJoinAcl } from './organizationJoinAcl'; +import { ICompanySpecificFeatureOrganizationSudo } from './organizationSudo'; +import { ICompanySpecificFeaturePortalSudo } from './portalSudo'; +import { ICompanySpecificFeatureRepositoryState } from './repositoryActions'; export * from './organizationSudo'; export * from './portalSudo'; @@ -22,7 +22,7 @@ export * from './organizationJoinAcl'; export * from './augmentApiMetadata'; export interface ICompanySpecificFeatures { - augmentApiMetadata?: ICompanySpecificAugmentApiMetadata; + augmentApiMetadata: ICompanySpecificAugmentApiMetadata; organizationSudo?: ICompanySpecificFeatureOrganizationSudo; organizationJoinAcl?: ICompanySpecificFeatureOrganizationJoinAcl; portalSudo?: ICompanySpecificFeaturePortalSudo; diff --git a/interfaces/companySpecific/features/organizationSudo.ts b/interfaces/companySpecific/features/organizationSudo.ts index 292df91e6..c7c25bc29 100644 --- a/interfaces/companySpecific/features/organizationSudo.ts +++ b/interfaces/companySpecific/features/organizationSudo.ts @@ -4,7 +4,7 @@ // import { Organization } from '../../../business'; -import { IOrganizationSudo } from '../../../business/features'; +import { IOrganizationSudo } from '../../../features'; import { IProviders } from '../../../interfaces'; export interface ICompanySpecificFeatureOrganizationSudo { diff --git a/interfaces/companySpecific/features/portalSudo.ts b/interfaces/companySpecific/features/portalSudo.ts index 07a704eb7..71f6c25ad 100644 --- a/interfaces/companySpecific/features/portalSudo.ts +++ b/interfaces/companySpecific/features/portalSudo.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IPortalSudo } from '../../../business/features'; +import { IPortalSudo } from '../../../features'; import { IProviders } from '../../../interfaces'; export interface ICompanySpecificFeaturePortalSudo { diff --git a/interfaces/companySpecific/index.ts b/interfaces/companySpecific/index.ts index fb311f15b..3bf21513e 100644 --- a/interfaces/companySpecific/index.ts +++ b/interfaces/companySpecific/index.ts @@ -11,4 +11,3 @@ export * from './administration'; export * from './passport'; export * from './views'; export * from './urls'; -export * from './events'; diff --git a/interfaces/companySpecific/middleware.ts b/interfaces/companySpecific/middleware.ts index f7c9e5e50..ceb754970 100644 --- a/interfaces/companySpecific/middleware.ts +++ b/interfaces/companySpecific/middleware.ts @@ -9,7 +9,6 @@ import { IProviders, ReposAppRequest } from '../../interfaces'; import { IndividualContext } from '../../business/user'; import { IRequestTeamPermissions } from '../../middleware/github/teamPermissions'; import type { ApiClientGroupDisplay } from '../api'; -import { ITeamJoinRequestSubmitOutcome } from '../../routes/org/team'; export interface ICompanySpecificRepoPermissionsMiddlewareCalls { afterPermissionsInitialized?: ( @@ -37,11 +36,6 @@ export interface ICompanySpecificTeamPermissionsMiddlewareCalls { activeContext: IndividualContext, team: Team ) => Promise; - beforeJoinRequest?: ( - providers: IProviders, - activeContext: IndividualContext, - team: Team - ) => Promise; } export interface ICompanySpecificAuthenticationCalls { @@ -52,8 +46,8 @@ export interface ICompanySpecificAuthenticationCalls { export interface IAadAuthenticationValidator { isAuthorizedTenant(tenantId: string): Promise; getAudienceIdentities(): Promise; - getAuthorizedClientIdToken(clientId: string): Promise; - getAuthorizedObjectIdToken(objectId: string): Promise; + getAuthorizedClientIdToken(clientId: string): Promise; + getAuthorizedObjectIdToken(objectId: string): Promise; getScopes(tokenRepresentation: any): Promise; getDisplayValues(tokenRepresentation: any): Promise; } diff --git a/interfaces/companySpecific/passport.ts b/interfaces/companySpecific/passport.ts index 478aa6c60..389e08065 100644 --- a/interfaces/companySpecific/passport.ts +++ b/interfaces/companySpecific/passport.ts @@ -4,7 +4,7 @@ // import { PassportStatic } from 'passport'; -import type { IAuthenticationHelperMethods } from '../../middleware/passport-routes'; +import { IAuthenticationHelperMethods } from '../../middleware/passport-routes'; export interface ICompanySpecificPassportMiddleware { configure?: (app: any, config: any, passport: PassportStatic) => void; diff --git a/interfaces/companySpecific/routes/api/index.ts b/interfaces/companySpecific/routes/api/index.ts index 0f5a5fae1..a8c324252 100644 --- a/interfaces/companySpecific/routes/api/index.ts +++ b/interfaces/companySpecific/routes/api/index.ts @@ -22,7 +22,6 @@ export interface IAttachCompanySpecificRoutesApiContextual { export interface IAttachCompanySpecificRoutesApiContextualOrganization { index?: ConnectRouter; repo?: ConnectRouter; - team?: ConnectRouter; } export interface IAttachCompanySpecificRoutesApiContextualAdministration { diff --git a/interfaces/companySpecific/routes/index.ts b/interfaces/companySpecific/routes/index.ts index ddb835ff4..9e4560744 100644 --- a/interfaces/companySpecific/routes/index.ts +++ b/interfaces/companySpecific/routes/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import { IAttachCompanySpecificRoutesApi } from './api'; export * from './api'; diff --git a/interfaces/github/account.ts b/interfaces/github/account.ts index f4bf943e3..c57efafa5 100644 --- a/interfaces/github/account.ts +++ b/interfaces/github/account.ts @@ -5,7 +5,6 @@ export enum AccountJsonFormat { GitHub = 'github', - GitHubExtended = 'github+extended', UplevelWithLink = 'github+link', GitHubDetailedWithLink = 'detailed+link', } diff --git a/interfaces/github/collaborators.ts b/interfaces/github/collaborators.ts index 5ab70be9c..7e9fcf2c7 100644 --- a/interfaces/github/collaborators.ts +++ b/interfaces/github/collaborators.ts @@ -5,8 +5,7 @@ export interface IGitHubCollaboratorPermissions { admin: boolean; - maintain: boolean; - push: boolean; - triage: boolean; pull: boolean; + push: boolean; + // triage and maintain do not appear today by the GitHub API (sigh), it's in V4 GraphQL but not in V3 REST } diff --git a/interfaces/github/operations.ts b/interfaces/github/operations.ts index 4ac9c3ee8..e2998f3c6 100644 --- a/interfaces/github/operations.ts +++ b/interfaces/github/operations.ts @@ -3,15 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { - CoreCapability, - ICacheDefaultTimes, - PurposefulGetAuthorizationHeader, - ICacheOptions, - GetAuthorizationHeader, -} from '.'; +import { CoreCapability, ICacheDefaultTimes, IPurposefulGetAuthorizationHeader, ICacheOptions } from '.'; import { IProviders, ICorporateLink, ICachedEmployeeInformation } from '..'; -import { IRepositoryMetadataProvider } from '../../business/entities/repositoryMetadata/repositoryMetadataProvider'; +import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; import { RestLibrary } from '../../lib/github'; import { Account } from '../../business'; @@ -32,34 +26,18 @@ export interface IOperationsProviders { providers: IProviders; } -export type LinkEvent = ICorporateLink & { - linkId: string; - correlationId: string; -}; - -export type UnlinkEvent = { - github: { - id: number; - login: string; - }; - aad: { - preferredName: string; - userPrincipalName: string; - id: string; - }; -}; - export interface IOperationsLinks { getLinks(options?: any): Promise; getLinkByThirdPartyId(thirdPartyId: string): Promise; getLinkByThirdPartyUsername(username: string): Promise; tryGetLink(login: string): Promise; - fireLinkEvent(value: LinkEvent): Promise; - fireUnlinkEvent(value: UnlinkEvent): Promise; + fireLinkEvent(value): Promise; + fireUnlinkEvent(value): Promise; } export interface IOperationsNotifications { getOperationsMailAddress(): string; + getInfrastructureNotificationsMail(): string; getLinksNotificationMailAddress(): string; getRepositoriesNotificationMailAddress(): string; } @@ -101,9 +79,8 @@ export interface IOperationsLockdownFeatureFlags { } export interface IOperationsCentralOperationsToken { + getCentralOperationsToken(): IPurposefulGetAuthorizationHeader; // IGetAuthorizationHeader ?; getAccountByUsername(username: string, options?: ICacheOptions): Promise; - getPublicReadOnlyStaticToken(): GetAuthorizationHeader; - getPublicAuthorizationToken(): GetAuthorizationHeader; } export function operationsIsCapable( diff --git a/interfaces/github/orgs.ts b/interfaces/github/orgs.ts index b815b973e..52092fda5 100644 --- a/interfaces/github/orgs.ts +++ b/interfaces/github/orgs.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import type { ICacheOptions, IPagedCacheOptions } from '.'; -import type { ICorporateLink } from '..'; +import { ICacheOptions, IPagedCacheOptions } from '.'; +import { ICorporateLink } from '..'; import { OrganizationMember } from '../../business'; import { Repository } from '../../business/repository'; @@ -97,24 +97,3 @@ export interface IOrganizationMembership { organization: any; user: any; } - -export type GitHubSimpleAccount = { - login: string; - avatar_url: string; - id: number; -}; - -export type GitHubOrganizationInvite = { - created_at: string; - email: string; - failed_at: string; - failed_reason: string; - id: number; - invitation_source: string; // 'member' - invitation_teams_url: string; - inviter: GitHubSimpleAccount; - login: string; - node_id: string; - role: string; // 'direct_member' - team_count: number; -}; diff --git a/interfaces/github/repos.ts b/interfaces/github/repos.ts index 828af3ba5..976f42b00 100644 --- a/interfaces/github/repos.ts +++ b/interfaces/github/repos.ts @@ -4,20 +4,18 @@ // import type { ICacheOptions, IPagedCacheOptions, IAccountBasics, IGitHubTeamBasics } from '.'; -import type { IGitHubWebhookEnterprise } from './apps'; import { IPersonalizedUserAggregateRepositoryPermission, TeamRepositoryPermission, GraphManager, } from '../../business'; -import type { IRepositoryMetadataProvider } from '../../business/entities/repositoryMetadata/repositoryMetadataProvider'; +import type { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; import { GitHubPullRequestState, GitHubPullRequestSort, GitHubSortDirection, } from '../../lib/github/collections'; import type { IRequestTeamPermissions } from '../../middleware/github/teamPermissions'; -import { CreateError } from '../../lib/transitional'; export enum GitHubRepositoryPermission { Pull = 'pull', @@ -176,49 +174,7 @@ export interface IGitHubBranchDetailed { }; } -export type RepositoryBranchAccessProtections = { - required_signatures: { - enabled: boolean; - }; - allow_fork_syncing: { - enabled: boolean; - }; - lock_branch: { - enabled: boolean; - }; - required_conversation_resolution: { - enabled: boolean; - }; - block_creations: { - enabled: boolean; - }; - required_pull_request_reviews: { - dismissal_restrictions: - | { - users: IAccountBasics[]; - teams: IGitHubTeamBasics[]; - apps: IGitHubWebhookEnterprise[]; - } - | Record; - dismiss_stale_reviews: boolean; - require_code_owner_reviews: boolean; - required_approving_review_count: number; - require_last_push_approval: boolean; - bypass_pull_request_allowances: { - users: IAccountBasics[]; - teams: IGitHubTeamBasics[]; - apps: IGitHubWebhookEnterprise[]; - }; - } | null; - required_status_checks: { - strict: boolean; - contexts: string[]; - checks: { - context: string; - app_id: number; - }[]; - } | null; - branch?: string; +export interface IRepositoryBranchAccessProtections { allow_deletions: { enabled: boolean; }; @@ -238,7 +194,7 @@ export type RepositoryBranchAccessProtections = { apps: unknown[]; }; url: string; -}; +} export interface ITemporaryCommandOutput { error?: Error; @@ -263,9 +219,7 @@ export interface IRepositorySearchOptions { export enum GitHubCollaboratorPermissionLevel { Admin = 'admin', - Maintain = 'maintain', Write = 'write', - Triage = 'triage', Read = 'read', None = 'none', } @@ -278,119 +232,13 @@ export function ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermis return null; case GitHubCollaboratorPermissionLevel.Admin: return GitHubRepositoryPermission.Admin; - case GitHubCollaboratorPermissionLevel.Maintain: - return GitHubRepositoryPermission.Maintain; case GitHubCollaboratorPermissionLevel.Write: return GitHubRepositoryPermission.Push; - case GitHubCollaboratorPermissionLevel.Triage: - return GitHubRepositoryPermission.Triage; case GitHubCollaboratorPermissionLevel.Read: return GitHubRepositoryPermission.Pull; default: - throw CreateError.InvalidParameters( - `Unrecognized GitHub permission value ${level}, current value cannot be translated (ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermission)` + throw new Error( + `ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermission unrecognized value ${level} cannot be translated` ); } } - -export enum GitHubAdvancedSecurityFeatureState { - Enabled = 'enabled', - Disabled = 'disabled', -} - -export type GitHubAdvancedSecurityFeatureStatusValue = { - status: GitHubAdvancedSecurityFeatureState; -}; - -export type GitHubSecurityAnalysisFeatures = { - advanced_security: GitHubAdvancedSecurityFeatureStatusValue; - secret_scanning: GitHubAdvancedSecurityFeatureStatusValue; - secret_scanning_push_protection: GitHubAdvancedSecurityFeatureStatusValue; - dependabot_security_updates: GitHubAdvancedSecurityFeatureStatusValue; - secret_scanning_validity_checks: GitHubAdvancedSecurityFeatureStatusValue; -}; - -export enum GitHubRepositoryOwnerType { - Organization = 'Organization', - User = 'User', -} - -export type GitHubRepositoryOwner = { - login: string; - id: number; - node_id: string; - avatar_url: string; - url: string; - type: GitHubRepositoryOwnerType; -}; - -export type GitHubRepositoryLicense = { - key: string; - name: string; - spdx_id: string; - url: string; - node_id: string; -}; - -export type GitHubRepositoryDetails = { - id: number; - node_id: string; - name: string; - full_name: string; - private: boolean; - owner: GitHubRepositoryOwner; - html_url: string; - description: string; - fork: boolean; - url: string; - created_at: string; - updated_at: string; - pushed_at: string; - git_url: string; - ssh_url: string; - clone_url: string; - homepage: string | null; - size: number; - stargazers_count: number; - watchers_count: number; - language: string; - has_issues: boolean; - has_projects: boolean; - has_downloads: boolean; - has_wiki: boolean; - has_pages: boolean; - has_discussions: boolean; - forks_count: number; - archived: boolean; - disabled: boolean; - open_issues_count: number; - license?: GitHubRepositoryLicense; - allow_forking: boolean; - is_template: boolean; - web_commit_signoff_required: boolean; - topics: string[]; - visibility?: GitHubRepositoryVisibility; - forks: number; - open_issues: number; - watchers: number; - default_branch: string; - // permissions: admin / maintain / push / triage / pull - // temp_clone_token: ... - allow_squash_merge: boolean; - allow_merge_commit: boolean; - allow_rebase_merge: boolean; - allow_auto_merge: boolean; - delete_branch_on_merge: boolean; - allow_update_branch: boolean; - use_squash_pr_title_as_default: boolean; - squash_merge_commit_message: string; - squash_merge_commit_title: string; - merge_commit_message: string; - merge_commit_title: string; - template_repository: GitHubRepositoryDetails; - organization?: GitHubRepositoryOwner; - security_and_analysis?: GitHubSecurityAnalysisFeatures; - network_count: number; - subscribers_count: number; - parent?: GitHubRepositoryDetails; -}; diff --git a/interfaces/github/rest.ts b/interfaces/github/rest.ts index 9d43fc236..c8ed62096 100644 --- a/interfaces/github/rest.ts +++ b/interfaces/github/rest.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurposeTypes } from '../../lib/github/appPurposes'; +import { AppPurposeTypes } from '../../business/githubApps'; export interface ICacheOptions { backgroundRefresh?: any | null | undefined; @@ -14,29 +14,25 @@ export interface ICacheOptionsWithPurpose extends ICacheOptions { purpose?: AppPurposeTypes; } -export type WithOptionalPurpose = { - purpose?: AppPurposeTypes; -}; - export interface IPagedCacheOptions extends ICacheOptions { pageRequestDelay?: number | null | undefined; // FUTURE: could be a function, too } -export type PagedCacheOptionsWithPurpose = IPagedCacheOptions & WithOptionalPurpose; - -export type PurposefulGetAuthorizationHeader = ( - purpose: AppPurposeTypes -) => Promise; +export interface IPurposefulGetAuthorizationHeader { + (purpose: AppPurposeTypes): Promise; +} -export type GetAuthorizationHeader = () => Promise; +export interface IGetAuthorizationHeader { + (): Promise; +} -export type AuthorizationHeaderValue = { +export interface IAuthorizationHeaderValue { value: string; purpose: AppPurposeTypes; source?: string; installationId?: number; organizationName?: string; -}; +} export interface ICacheDefaultTimes { orgReposStaleSeconds: number; @@ -62,7 +58,6 @@ export interface ICacheDefaultTimes { teamDetailStaleSeconds: number; orgRepoWebhooksStaleSeconds: number; teamRepositoryPermissionStaleSeconds: number; - defaultStaleSeconds: number; } // These "core capabilities" were created when the GitHub operations diff --git a/interfaces/github/teams.ts b/interfaces/github/teams.ts index e6d8a417a..110ddb0f7 100644 --- a/interfaces/github/teams.ts +++ b/interfaces/github/teams.ts @@ -22,29 +22,6 @@ export interface IGitHubTeamBasics { slug: string; } -export enum GitHubTeamNotificationSetting { - Enabled = 'notification_enabled', - Disabled = 'notification_disabled', -} - -export type GitHubTeamDetails = IGitHubTeamBasics & { - node_id: string; - description: string; - privacy: GitHubTeamPrivacy; - notification_setting: GitHubTeamNotificationSetting; - url: string; - html_url: string; - members_url: string; - repositories_url: string; - // permission: ... - created_at: string; - updated_at: string; - members_count: number; - repos_count: number; - // organization: ... - parent: IGitHubTeamBasics; -}; - export enum GitHubRepositoryType { Sources = 'sources', } diff --git a/interfaces/index.ts b/interfaces/index.ts index 4d0713adc..079d0b3d7 100644 --- a/interfaces/index.ts +++ b/interfaces/index.ts @@ -16,26 +16,22 @@ export * from './providers'; export * from './web'; export * from './config'; -import type { ExecutionEnvironment } from './app'; -import type { +import { IAttachCompanySpecificRoutes, IAttachCompanySpecificMiddleware, ICorporationAdministrationSection, IAttachCompanySpecificStrings, ICompanySpecificFeatures, - ICompanySpecificEvents, IAttachCompanySpecificViews, IAttachCompanySpecificUrls, } from './companySpecific'; -import type { ICompanySpecificPassportMiddleware } from './companySpecific/passport'; -import type { SiteConfiguration } from './config'; -import type { IProviders } from './providers'; +import { ICompanySpecificPassportMiddleware } from './companySpecific/passport'; +import { IProviders } from './providers'; // We're great at long variable names! export interface ICompanySpecificStartupProperties { isCompanySpecific: true; - events?: ICompanySpecificEvents; routes?: IAttachCompanySpecificRoutes; middleware?: IAttachCompanySpecificMiddleware; administrationSection?: ICorporationAdministrationSection; @@ -46,11 +42,6 @@ export interface ICompanySpecificStartupProperties { urls?: IAttachCompanySpecificUrls; } -export type ICompanySpecificStartupFunction = ( - executionEnvironment: ExecutionEnvironment, - config: SiteConfiguration, - p: IProviders, - rootdir: string -) => Promise; +export type ICompanySpecificStartupFunction = (config: any, p: IProviders, rootdir: string) => Promise; export type ICompanySpecificStartup = ICompanySpecificStartupFunction & ICompanySpecificStartupProperties; diff --git a/interfaces/middleware.ts b/interfaces/middleware.ts deleted file mode 100644 index 8b8b44b2f..000000000 --- a/interfaces/middleware.ts +++ /dev/null @@ -1,11 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { UserSettings } from '../business/entities/userSettings'; -import type { ReposAppRequest } from './web'; - -export type ReposAppRequestWithUserSettings = ReposAppRequest & { - userSettings?: UserSettings; -}; diff --git a/interfaces/providers.ts b/interfaces/providers.ts index d438fbb1e..fbe0ae2e5 100644 --- a/interfaces/providers.ts +++ b/interfaces/providers.ts @@ -9,25 +9,25 @@ import redis, { RedisClientType } from 'redis'; import { Pool as PostgresPool } from 'pg'; import { - ApplicationProfile, + IApplicationProfile, ICorporationAdministrationSection, IReposApplication, SiteConfiguration, } from '.'; import { Operations } from '../business'; import QueryCache from '../business/queryCache'; -import { IAuditLogRecordProvider } from '../business/entities/auditLogRecord/auditLogRecordProvider'; -import { ILocalExtensionKeyProvider } from '../business/entities/localExtensionKey'; -import { IOrganizationMemberCacheProvider } from '../business/entities/organizationMemberCache/organizationMemberCacheProvider'; -import { IOrganizationSettingProvider } from '../business/entities/organizationSettings/organizationSettingProvider'; -import { IRepositoryCacheProvider } from '../business/entities/repositoryCache/repositoryCacheProvider'; -import { IRepositoryCollaboratorCacheProvider } from '../business/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider'; -import { IRepositoryTeamCacheProvider } from '../business/entities/repositoryTeamCache/repositoryTeamCacheProvider'; -import { ITeamCacheProvider } from '../business/entities/teamCache/teamCacheProvider'; -import { IApprovalProvider } from '../business/entities/teamJoinApproval/approvalProvider'; -import { ITeamMemberCacheProvider } from '../business/entities/teamMemberCache/teamMemberCacheProvider'; -import { ITokenProvider } from '../business/entities/token'; -import { IUserSettingsProvider } from '../business/entities/userSettings'; +import { IAuditLogRecordProvider } from '../entities/auditLogRecord/auditLogRecordProvider'; +import { ILocalExtensionKeyProvider } from '../entities/localExtensionKey'; +import { IOrganizationMemberCacheProvider } from '../entities/organizationMemberCache/organizationMemberCacheProvider'; +import { IOrganizationSettingProvider } from '../entities/organizationSettings/organizationSettingProvider'; +import { IRepositoryCacheProvider } from '../entities/repositoryCache/repositoryCacheProvider'; +import { IRepositoryCollaboratorCacheProvider } from '../entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider'; +import { IRepositoryTeamCacheProvider } from '../entities/repositoryTeamCache/repositoryTeamCacheProvider'; +import { ITeamCacheProvider } from '../entities/teamCache/teamCacheProvider'; +import { IApprovalProvider } from '../entities/teamJoinApproval/approvalProvider'; +import { ITeamMemberCacheProvider } from '../entities/teamMemberCache/teamMemberCacheProvider'; +import { ITokenProvider } from '../entities/token'; +import { IUserSettingsProvider } from '../entities/userSettings'; import { ICacheHelper } from '../lib/caching'; import BlobCache from '../lib/caching/blob'; import { ICampaignHelper } from '../lib/campaigns'; @@ -37,18 +37,18 @@ import { ILinkProvider } from '../lib/linkProviders'; import { IMailAddressProvider } from '../lib/mailAddressProvider'; import { IMailProvider } from '../lib/mailProvider'; import { IQueueProcessor } from '../lib/queues'; -import { ICustomizedNewRepositoryLogic, ICustomizedTeamPermissionsWebhookLogic } from '../lib/transitional'; +import { ICustomizedNewRepositoryLogic, ICustomizedTeamPermissionsWebhookLogic } from '../transitional'; import { IEntityMetadataProvider } from '../lib/entityMetadataProvider'; -import { IRepositoryProvider } from '../business/entities/repository'; +import { IRepositoryProvider } from '../entities/repository'; import { IKeyVaultSecretResolver } from '../lib/keyVaultResolver'; -import { IOrganizationAnnotationMetadataProvider } from '../business/entities/organizationAnnotation'; +import { IOrganizationAnnotationMetadataProvider } from '../entities/organizationAnnotation'; import type { IImmutableStorageProvider } from '../lib/immutable'; type ProviderGenerator = (value: string) => IEntityMetadataProvider; export interface IProviders { app: IReposApplication; - applicationProfile: ApplicationProfile; + applicationProfile: IApplicationProfile; authorizationCodeClient?: AuthorizationCode; corporateAdministrationProfile?: ICorporationAdministrationSection; corporateViews?: any; diff --git a/interfaces/queryCache.ts b/interfaces/queryCache.ts index 9a8486eca..658775053 100644 --- a/interfaces/queryCache.ts +++ b/interfaces/queryCache.ts @@ -10,11 +10,11 @@ import { GitHubRepositoryPermission, } from '.'; import { Team, Repository, Organization } from '../business'; -import { RepositoryCacheEntity } from '../business/entities/repositoryCache/repositoryCache'; -import { RepositoryCollaboratorCacheEntity } from '../business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; -import { RepositoryTeamCacheEntity } from '../business/entities/repositoryTeamCache/repositoryTeamCache'; -import { TeamCacheEntity } from '../business/entities/teamCache/teamCache'; -import { TeamMemberCacheEntity } from '../business/entities/teamMemberCache/teamMemberCache'; +import { RepositoryCacheEntity } from '../entities/repositoryCache/repositoryCache'; +import { RepositoryCollaboratorCacheEntity } from '../entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; +import { RepositoryTeamCacheEntity } from '../entities/repositoryTeamCache/repositoryTeamCache'; +import { TeamCacheEntity } from '../entities/teamCache/teamCache'; +import { TeamMemberCacheEntity } from '../entities/teamMemberCache/teamMemberCache'; export enum QueryCacheOperation { New = 'new', diff --git a/interfaces/web.ts b/interfaces/web.ts index 4657f0082..18448f877 100644 --- a/interfaces/web.ts +++ b/interfaces/web.ts @@ -4,7 +4,7 @@ // import { Session } from 'express-session'; -import { NextFunction, Request, Response } from 'express'; +import { Request, Response } from 'express'; import { AccessToken } from 'simple-oauth2'; import type { TelemetryClient } from 'applicationinsights'; @@ -36,12 +36,8 @@ export enum LocalApiRepoAction { Delete = 'delete', Archive = 'archive', UnArchive = 'unarchive', - Privatize = 'privatize', } -export type VoidedExpressRoute = (req: ReposAppRequest, res: Response, next: NextFunction) => Promise; -// req: Request>, res: Response, number>, next: NextFunction) => void | Promise<...> - export interface ReposAppRequest extends Request { // passport isAuthenticated(): boolean; @@ -60,9 +56,9 @@ export interface ReposAppRequest extends Request { correlationId?: string; scrubbedUrl?: string; + // FUTURE: apiContext: IndividualContext; individualContext: IndividualContext; - watchdogContextOverride?: IndividualContext; oauthAccessToken: AccessToken; } diff --git a/test/jest.config.ts b/jest.config.ts similarity index 66% rename from test/jest.config.ts rename to jest.config.ts index ec96f57aa..d71b5f019 100644 --- a/test/jest.config.ts +++ b/jest.config.ts @@ -1,8 +1,3 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - // eslint-disable-next-line n/no-unpublished-import import type { Config } from 'jest'; diff --git a/job.ts b/job.ts deleted file mode 100644 index 24e77ef08..000000000 --- a/job.ts +++ /dev/null @@ -1,182 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { hostname } from 'os'; -import Debug from 'debug'; - -import type { - ExecutionEnvironment, - IProviders, - IReposJob, - IReposJobOptions, - IReposJobResult, - SiteConfiguration, -} from './interfaces'; -import { commonStartup } from '.'; -import { quitInTenSeconds } from './lib/utils'; -import initialize from './middleware/initialize'; - -export async function runJob( - job: (job: IReposJob) => Promise, - options?: IReposJobOptions -): Promise { - Debug.debug('startup')('starting job...'); - - options = options || {}; - // TODO: automatically track elapsed job time - const started = new Date(); - if (options.timeoutMinutes) { - setTimeout( - () => { - // TODO: insights metric and event, if a prefix exists - console.log(`Kill bit at ${options.timeoutMinutes}m`); - process.exit(1); - }, - 1000 * 60 * options.timeoutMinutes - ); - } - if (options.defaultDebugOutput && !process.env.DEBUG) { - process.env.DEBUG = options.defaultDebugOutput; - } - - let executionEnvironment: ExecutionEnvironment = null; - try { - executionEnvironment = await commonStartup( - initializeJob, - true /* job */, - options.enableAllGitHubApps, - null /* app */, - options.name - ); - } catch (startupError) { - console.error(`Job startup error before runJob: ${startupError}`); - quitInTenSeconds(false); - return; - } - const providers = executionEnvironment?.providers; - if (options.insightsPrefix && providers?.insights) { - try { - providers?.insights?.trackEvent({ - name: `${options.insightsPrefix}Started`, - properties: { - hostname: hostname(), - }, - }); - } catch (ignoreInsightsError) { - console.error(`insights error: ${ignoreInsightsError}`); - } - } - const jobObject = { - app: providers?.app, - executionEnvironment, - providers, - started, - parameters: options && options.parameters ? options.parameters : {}, - args: process.argv.length > 2 ? process.argv.slice(2) : [], - }; - let result: IReposJobResult = null; - try { - result = (await job.call(null, jobObject)) as IReposJobResult; - if (result?.successProperties && providers?.insights && options.insightsPrefix) { - try { - providers?.insights?.trackEvent({ - name: `${options.insightsPrefix}Success`, - properties: Object.assign( - { - hostname: hostname(), - }, - result.successProperties - ), - }); - } catch (ignoreInsightsError) { - console.error(`insights error: ${ignoreInsightsError}`); - } - } - } catch (jobError) { - console.error(`The job failed: ${jobError}`); - if (jobError.stack) { - console.error(jobError.stack); - } - // by default, let's not show the whole inner error - const simpleError = { ...jobError }; - simpleError?.cause && delete simpleError.cause; - console.dir(simpleError); - const config = providers?.config; - quitInTenSeconds(false, config); - if (options.insightsPrefix) { - try { - providers?.insights?.trackException({ - exception: jobError, - properties: { - name: `${options.insightsPrefix}Failure`, - }, - }); - } catch (ignoreInsightsError) { - console.error(`insights error: ${ignoreInsightsError}`); - } - } - trySilentInsightsFlush(providers); - return result; - } - // CONSIDER: insights metric for job time - trySilentInsightsFlush(providers); - console.log(); - console.log('The job was successful.'); - quitInTenSeconds(true); - return result; -} - -function trySilentInsightsFlush(providers: IProviders) { - try { - providers?.insights?.flush(); - } catch (ignored) { - console.warn(ignored); - } -} - -function initializeJob( - executionEnvironment: ExecutionEnvironment, - config: SiteConfiguration, - configurationError: Error -) { - if (!config || configurationError) { - console.warn(`Configuration did not resolve successfully`, configurationError); - } - return initialize( - executionEnvironment, - null /* app */, - null /* express */, - __dirname, - config, - configurationError - ); -} - -export const job = { - runBackgroundJob: async ( - script: (providers: IProviders, jobParameters?: IReposJob) => Promise, - options?: IReposJobOptions - ) => { - return runJob( - async function (jobParameters: IReposJob) { - return (await script(jobParameters.providers, jobParameters)) || {}; - }, - Object.assign({ enableAllGitHubApps: false }, options || {}) - ); - }, - run: async ( - script: (providers: IProviders, jobParameters?: IReposJob) => Promise, - options?: IReposJobOptions - ) => { - return runJob( - async function (jobParameters: IReposJob) { - return (await script(jobParameters.providers, jobParameters)) || {}; - }, - Object.assign({ enableAllGitHubApps: true }, options || {}) - ); - }, -}; - -export default job; diff --git a/middleware/types.ts b/jobs/cleanupBlobCache/index.ts similarity index 50% rename from middleware/types.ts rename to jobs/cleanupBlobCache/index.ts index 50b8e1de7..c359c26a1 100644 --- a/middleware/types.ts +++ b/jobs/cleanupBlobCache/index.ts @@ -3,8 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Express } from 'express'; +import Job from './task'; +import app from '../../app'; -export type ExpressWithStatic = Express & { - static: (path: string, options?: any) => Express; -}; +app.runJob(Job); diff --git a/jobs/cleanupBlobCache.ts b/jobs/cleanupBlobCache/task.ts similarity index 81% rename from jobs/cleanupBlobCache.ts rename to jobs/cleanupBlobCache/task.ts index 295326351..cccf1bd0d 100644 --- a/jobs/cleanupBlobCache.ts +++ b/jobs/cleanupBlobCache/task.ts @@ -3,15 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -// Job 17: Cleanup blob cache +import BlobCache from '../../lib/caching/blob'; +import { IReposJob } from '../../interfaces'; -import BlobCache from '../lib/caching/blob'; -import job from '../job'; -import { IProviders } from '../interfaces'; - -job.runBackgroundJob(cleanup); - -async function cleanup(providers: IProviders): Promise { +export default async function go({ providers }: IReposJob): Promise { for (const providerName in providers) { const provider = providers[providerName]; if (provider && provider['expiringBlobCache']) { diff --git a/jobs/cleanupInvites/index.ts b/jobs/cleanupInvites/index.ts new file mode 100644 index 000000000..7d2e3f56d --- /dev/null +++ b/jobs/cleanupInvites/index.ts @@ -0,0 +1,13 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import Job from './task'; +import app from '../../app'; + +app.runJob(Job, { + timeoutMinutes: 90, + defaultDebugOutput: 'restapi', + insightsPrefix: 'JobOrganizationInvitationsCleanup', +}); diff --git a/jobs/cleanupInvites.ts b/jobs/cleanupInvites/task.ts similarity index 71% rename from jobs/cleanupInvites.ts rename to jobs/cleanupInvites/task.ts index 8d538c7f2..6da64f9a4 100644 --- a/jobs/cleanupInvites.ts +++ b/jobs/cleanupInvites/task.ts @@ -3,50 +3,48 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -// Job 16: cleanup invites +import moment from 'moment'; + +import { IReposJob } from '../../interfaces'; // Organization invitations cleanup: remove any invitations that are older than a // set period of time from the organization. -import { GitHubOrganizationInvite, IProviders } from '../interfaces'; -import job from '../job'; -import { daysInMilliseconds } from '../lib/utils'; - const defaultMaximumInvitationAgeDays = 4; -job.runBackgroundJob(cleanup, { - timeoutMinutes: 90, - insightsPrefix: 'JobOrganizationInvitationsCleanup', -}); - -async function cleanup(providers: IProviders) { +export default async function cleanup({ providers }: IReposJob): Promise { const insights = providers.insights; let maximumInvitationAgeDays = defaultMaximumInvitationAgeDays; const { config, operations } = providers; - if (config?.github?.jobs?.cleanup?.maximumInvitationAgeDays) { + if ( + config.github && + config.github.jobs && + config.github.jobs.cleanup && + config.github.jobs.cleanup.maximumInvitationAgeDays + ) { maximumInvitationAgeDays = config.github.jobs.cleanup.maximumInvitationAgeDays; } - const maximumAgeDate = new Date(new Date().getTime() - daysInMilliseconds(maximumInvitationAgeDays)); + const maximumAgeMoment = moment().subtract(maximumInvitationAgeDays, 'days'); const organizations = operations.getOrganizations(); const removedInvitations = 0; for (const organization of organizations) { - let invitations: GitHubOrganizationInvite[]; + let invitations: any[]; try { invitations = await organization.getMembershipInvitations(); } catch (getInvitationsError) { - insights?.trackException({ exception: getInvitationsError }); + insights.trackException({ exception: getInvitationsError }); console.dir(getInvitationsError); continue; } if (!invitations || invitations.length === 0) { continue; } - const invitationsToRemove: string[] = []; + const invitationsToRemove = []; let emailInvitations = 0; for (let i = 0; i < invitations.length; i++) { const invite = invitations[i]; - const createdAt = new Date(invite.created_at); - if (createdAt < maximumAgeDate) { + const createdAt = moment(invite.created_at); + if (createdAt.isBefore(maximumAgeMoment)) { if (invite.login) { invitationsToRemove.push(invite.login); } else { @@ -54,7 +52,8 @@ async function cleanup(providers: IProviders) { console.warn(`An e-mail based invitation to ${invite.email} cannot be automatically canceled`); } const data = { - createdAt: createdAt.toISOString(), + createdAt: createdAt.format(), + invitedAgo: createdAt.fromNow(), login: invite.login, inviter: invite && invite.inviter && invite.inviter.login ? invite.inviter.login : undefined, role: invite.role, @@ -63,7 +62,7 @@ async function cleanup(providers: IProviders) { const eventName = invite.login ? 'JobOrganizationInviteCleanupInvitationNeeded' : 'JobOrganizationInviteCleanupInvitationNotUser'; - insights?.trackEvent({ + insights.trackEvent({ name: eventName, properties: data, }); @@ -81,8 +80,8 @@ async function cleanup(providers: IProviders) { try { await organization.removeMember(login); } catch (removeError) { - insights?.trackException({ exception: removeError }); - insights?.trackEvent({ + insights.trackException({ exception: removeError }); + insights.trackEvent({ name: 'JobOrganizationInvitationsCleanupInvitationFailed', properties: { login: login, @@ -93,5 +92,5 @@ async function cleanup(providers: IProviders) { } } console.log(`Job finishing. Removed ${removedInvitations} expired invitations.`); - insights?.trackMetric({ name: 'JobOrganizationInvitationsExpired', value: removedInvitations }); + insights.trackMetric({ name: 'JobOrganizationInvitationsExpired', value: removedInvitations }); } diff --git a/jobs/cleanupKeys/index.ts b/jobs/cleanupKeys/index.ts new file mode 100644 index 000000000..8380b468f --- /dev/null +++ b/jobs/cleanupKeys/index.ts @@ -0,0 +1,9 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import Job from './task'; +import app from '../../app'; + +app.runJob(Job, { timeoutMinutes: 90, defaultDebugOutput: 'restapi', insightsPrefix: 'JobCleanupKeys' }); diff --git a/jobs/cleanupKeys/task.ts b/jobs/cleanupKeys/task.ts new file mode 100644 index 000000000..4e1d3b019 --- /dev/null +++ b/jobs/cleanupKeys/task.ts @@ -0,0 +1,98 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import throat from 'throat'; + +import { IReposJob, IReposJobResult } from '../../interfaces'; +import { sleep } from '../../utils'; +import { IGraphProvider } from '../../lib/graphProvider'; +import { LocalExtensionKey } from '../../entities/localExtensionKey/localExtensionKey'; + +async function lookupCorporateId( + graphProvider: IGraphProvider, + knownUsers: Map, + corporateId: string +): Promise { + const entry = knownUsers.get(corporateId); + if (entry === false) { + return false; + } else if (entry) { + return true; + } + + try { + const userDetails = await graphProvider.getUserById(corporateId); + if (!userDetails || !userDetails.userPrincipalName) { + knownUsers.set(corporateId, false); + return false; + } + knownUsers.set(corporateId, userDetails); + return true; + } catch (otherUserError) { + console.dir(otherUserError); + throw otherUserError; + } +} + +export default async function cleanup({ providers }: IReposJob): Promise { + const graphProvider = providers.graphProvider; + const localExtensionKeyProvider = providers.localExtensionKeyProvider; + const insights = providers.insights; + + console.log('reading all keys'); + const allKeys = await localExtensionKeyProvider.getAllKeys(); + console.log(`read ${allKeys.length}`); + + insights.trackEvent({ name: 'JobCleanupTokensKeysTokens', properties: { tokens: String(allKeys.length) } }); + + let errors = 0; + + let deleted = 0; + let okUserTokens = 0; + + const parallelUsers = 2; + const secondsDelayAfterSuccess = 0.25; + + const knownUsers = new Map(); + + const throttle = throat(parallelUsers); + await Promise.all( + allKeys.map((key: LocalExtensionKey) => + throttle(async () => { + const corporateId = key.corporateId; + const userStatus = await lookupCorporateId(graphProvider, knownUsers, corporateId); + if (!userStatus) { + try { + ++deleted; + console.log(`${deleted}: Deleting key for ${corporateId} that could not be found`); + await localExtensionKeyProvider.delete(key); + } catch (tokenDeleteError) { + --deleted; + console.dir(tokenDeleteError); + ++errors; + insights.trackException({ exception: tokenDeleteError }); + } + } else { + ++okUserTokens; + console.log(`${okUserTokens}: valid`); + } + + await sleep(secondsDelayAfterSuccess * 1000); + }) + ) + ); + + console.log(`deleted: ${deleted}`); + console.log(`okUserTokens: ${okUserTokens}`); + console.log(); + + return { + successProperties: { + deleted, + okUserTokens, + errors, + }, + }; +} diff --git a/jobs/cleanupTeamRequests.ts b/jobs/cleanupTeamRequests.ts deleted file mode 100644 index 99bbc59db..000000000 --- a/jobs/cleanupTeamRequests.ts +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -// Job 18: cleanup team requests - -// Remove any team requests made by people who are no longer linked. - -import { IProviders } from '../interfaces'; -import job from '../job'; -import { TeamApprovalDecision } from '../routes/org/team/approval'; -import { CreateError } from '../lib/transitional'; - -job.runBackgroundJob(cleanup, { - timeoutMinutes: 5, - insightsPrefix: 'JobTeamRequestsCleanup', -}); - -async function cleanup(providers: IProviders) { - const { approvalProvider, insights, linkProvider } = providers; - if (!approvalProvider) { - throw CreateError.InvalidParameters('No approval provider instance available'); - } - - const linkedCorporateIds = await linkProvider.getAllCorporateIds(); - - let approvals = await approvalProvider.queryAllApprovals(); - approvals = approvals.filter((approval) => approval.active === true && approval.corporateId); - - const orphanApprovals = approvals.filter((approval) => !linkedCorporateIds.includes(approval.corporateId)); - - let removedRequests = 0; - let i = 0; - for (const approval of orphanApprovals) { - ++i; - try { - approval.active = false; - approval.decision = TeamApprovalDecision.Deny; - approval.decisionMessage = 'Requestor not linked'; - await approvalProvider.updateTeamApprovalEntity(approval); - insights?.trackEvent({ - name: 'JobTeamRequestsCleanupApprovalUpdate', - properties: { - approvalId: approval.approvalId, - }, - }); - console.log( - `Denied former linked user request ${approval.approvalId} (${i} of ${orphanApprovals.length})` - ); - ++removedRequests; - } catch (error) { - insights?.trackException({ - exception: error, - properties: { - eventName: 'JobTeamRequestsCleanupApprovalUpdateFailed', - approvalId: approval.approvalId, - }, - }); - console.warn(`Error ${error.message} updating approval ${approval.approvalId}`); - } - } - console.log(`Job finishing. Removed ${removedRequests} requests from former linked users.`); - insights?.trackMetric({ name: 'JobFormerRequestsDenied', value: removedRequests }); -} diff --git a/jobs/cleanupTokens/index.ts b/jobs/cleanupTokens/index.ts new file mode 100644 index 000000000..2b59c4a5d --- /dev/null +++ b/jobs/cleanupTokens/index.ts @@ -0,0 +1,9 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import Job from './task'; +import app from '../../app'; + +app.runJob(Job, { timeoutMinutes: 90, defaultDebugOutput: 'restapi', insightsPrefix: 'JobCleanupTokens' }); diff --git a/jobs/cleanupTokens/task.ts b/jobs/cleanupTokens/task.ts new file mode 100644 index 000000000..2bcd443e9 --- /dev/null +++ b/jobs/cleanupTokens/task.ts @@ -0,0 +1,142 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import throat from 'throat'; +import { IReposJob, IReposJobResult } from '../../interfaces'; + +// Revoke tokens of users that no longer resolve in the corporate graph and +// delete tokens that have been expired 30 days. + +const expiredTokenDeleteThresholdDays = 30; + +import { PersonalAccessToken } from '../../entities/token/token'; +import { sleep } from '../../utils'; +import { IGraphProvider } from '../../lib/graphProvider'; + +async function lookupCorporateId( + graphProvider: IGraphProvider, + knownUsers: Map, + corporateId: string +): Promise { + const entry = knownUsers.get(corporateId); + if (entry === false) { + return false; + } else if (entry) { + return true; + } + + try { + const userDetails = await graphProvider.getUserById(corporateId); + if (!userDetails || !userDetails.userPrincipalName) { + knownUsers.set(corporateId, false); + return false; + } + knownUsers.set(corporateId, userDetails); + return true; + } catch (otherUserError) { + console.dir(otherUserError); + throw otherUserError; + } +} + +export default async function cleanup({ providers }: IReposJob): Promise { + const insights = providers.insights; + const graphProvider = providers.graphProvider; + const tokenProvider = providers.tokenProvider; + + console.log('reading all tokens'); + const allTokens = await tokenProvider.getAllTokens(); + console.log(`read ${allTokens.length}`); + + insights.trackEvent({ + name: 'JobCleanupTokensReadTokens', + properties: { tokens: String(allTokens.length) }, + }); + + let errors = 0; + + let revokedUnresolved = 0; + let deleted = 0; + let serviceTokens = 0; + let okUserTokens = 0; + + const parallelUsers = 1; + const secondsDelayAfterSuccess = 0.25; + + const now = new Date(); + const monthAgo = new Date(now.getTime() - 1000 * 60 * 60 * 24 * expiredTokenDeleteThresholdDays); + + const knownUsers = new Map(); + + const throttle = throat(parallelUsers); + await Promise.all( + allTokens.map((pat: PersonalAccessToken) => + throttle(async () => { + const isGuidMeansADash = pat.corporateId && pat.corporateId.includes('-'); + let wasUser = false; + if (isGuidMeansADash) { + wasUser = true; + + const userStatus = await lookupCorporateId(graphProvider, knownUsers, pat.corporateId); + if (!userStatus && pat.active !== false) { + pat.active = false; + console.log( + `Revoking key for ${pat.getIdentifier()} - employee ${pat.corporateId} could not be found` + ); + try { + await tokenProvider.updateToken(pat); + ++revokedUnresolved; + } catch (tokenUpdateError) { + console.dir(tokenUpdateError); + ++errors; + insights.trackException({ exception: tokenUpdateError }); + } + } + } else { + ++serviceTokens; + } + + if (pat.isExpired()) { + const dateExpired = pat.expires; + if (dateExpired < monthAgo) { + console.log(`Deleting key for ${pat.getIdentifier()} that expired ${dateExpired}`); + try { + await tokenProvider.deleteToken(pat); + ++deleted; + } catch (tokenDeleteError) { + console.dir(tokenDeleteError); + ++errors; + insights.trackException({ exception: tokenDeleteError }); + } + } else { + console.log( + `Expired key, keeping around ${pat.getIdentifier()} that expired ${dateExpired} for user notification purposes` + ); + } + } else if (wasUser) { + ++okUserTokens; + } + + await sleep(secondsDelayAfterSuccess * 1000); + }) + ) + ); + + console.log(`deleted: ${deleted}`); + console.log(`revokedUnresolved: ${revokedUnresolved}`); + console.log(`okUserTokens: ${okUserTokens}`); + console.log(`serviceTokens: ${serviceTokens}`); + console.log(); + + return { + successProperties: { + deleted, + revokedUnresolved, + okUserTokens, + serviceTokens, + errors, + }, + }; +} diff --git a/jobs/firehose/index.ts b/jobs/firehose/index.ts new file mode 100644 index 000000000..9ac3820d6 --- /dev/null +++ b/jobs/firehose/index.ts @@ -0,0 +1,13 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import Job from './task'; +import app from '../../app'; + +app.runJob(Job, { + defaultDebugOutput: 'redis,restapi,querycache', + insightsPrefix: 'JobFirehose', + enableAllGitHubApps: true, +}); diff --git a/jobs/firehose.ts b/jobs/firehose/task.ts similarity index 89% rename from jobs/firehose.ts rename to jobs/firehose/task.ts index 6f4db5af7..e4acde7e4 100644 --- a/jobs/firehose.ts +++ b/jobs/firehose/task.ts @@ -7,31 +7,24 @@ import os from 'os'; import { DateTime } from 'luxon'; - -import ProcessOrganizationWebhook, { - IGitHubWebhookProperties, -} from '../business/webhooks/organizationProcessor'; +import App from '../../app'; +import ProcessOrganizationWebhook, { IGitHubWebhookProperties } from '../../webhooks/organizationProcessor'; import { IGitHubAppInstallation, IGitHubWebhookEnterprise, IProviders, IReposJob, IReposJobResult, -} from '../interfaces'; -import { sleep } from '../lib/utils'; -import { IQueueMessage } from '../lib/queues'; -import getCompanySpecificDeployment from '../middleware/companySpecificDeployment'; -import job from '../job'; +} from '../../interfaces'; +import { sleep } from '../../utils'; +import { IQueueMessage } from '../../lib/queues'; +import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; const runningAsOngoingDeployment = true; const hardAbortMs = 1000 * 60 * 5; // 5 minutes -job.run(firehose, { - insightsPrefix: 'JobFirehose', -}); - -async function firehose(providers: IProviders, { started }: IReposJob): Promise { +export default async function firehose({ providers, started }: IReposJob): Promise { const processedEventTypes = {}; const interestingEvents = 0; let processedEvents = 0; @@ -96,24 +89,28 @@ async function firehose(providers: IProviders, { started }: IReposJob): Promise< console.log( `Parallelism for this run will be ${parallelism} logical threads, offset by ${sliceDelayPerThread}s` ); - insights?.trackEvent({ - name: 'JobFirehoseStarted', - properties: { - hostname: os.hostname(), - // queue: serviceBusConfig.queue, - // subscription: serviceBusConfig.subscriptionName, - // messagesInQueue: messagesInQueue.toString(), - // deadLetters: deadLetters.toString(), - }, - }); - // insights.trackMetric({ name: 'FirehoseMessagesInQueue', value: messagesInQueue }); - // insights.trackMetric({ name: 'FirehoseDeadLetters', value: deadLetters }); + // const insights = app.settings.appInsightsClient; + if (insights) { + insights.trackEvent({ + name: 'JobFirehoseStarted', + properties: { + hostname: os.hostname(), + // queue: serviceBusConfig.queue, + // subscription: serviceBusConfig.subscriptionName, + // messagesInQueue: messagesInQueue.toString(), + // deadLetters: deadLetters.toString(), + }, + }); + // insights.trackMetric({ name: 'FirehoseMessagesInQueue', value: messagesInQueue }); + // insights.trackMetric({ name: 'FirehoseDeadLetters', value: deadLetters }); + } const threads: Promise[] = []; let delay = 0; for (let i = 0; i < parallelism; i++) { - threads.push(createThread(providers, i, delay)); + threads.push(createThread(App, providers, i, delay)); delay += sliceDelayPerThread; } + const ok = true; await Promise.all(threads); console.warn('Forever execution thread has completed.'); @@ -122,6 +119,7 @@ async function firehose(providers: IProviders, { started }: IReposJob): Promise< // -- end of job startup -- async function createThread( + app, providers: IProviders, threadNumber: number, startupDelay: number @@ -138,7 +136,7 @@ async function firehose(providers: IProviders, { started }: IReposJob): Promise< await iterate(providers, threadNumber); } } catch (error) { - const insights = providers.insights; + const insights = app.settings.appInsightsClient; insights.trackException({ exception: error }); insights.trackEvent({ name: 'JobFirehoseFatalError', diff --git a/jobs/permissions.ts b/jobs/permissions.ts deleted file mode 100644 index 93031a4fc..000000000 --- a/jobs/permissions.ts +++ /dev/null @@ -1,214 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -// Job 15: System Team Permissions - -import { shuffle } from 'lodash'; -import throat from 'throat'; - -import job from '../job'; -import { TeamPermission } from '../business/teamPermission'; -import { GitHubRepositoryPermission, IProviders, IReposJobResult } from '../interfaces'; -import AutomaticTeamsWebhookProcessor from '../business/webhooks/tasks/automaticTeams'; -import { sleep } from '../lib/utils'; -import { ErrorHelper } from '../lib/transitional'; -import { Organization } from '../business'; - -// Permissions processing: visit all repos and make sure that any designated read, write, admin -// teams for the organization are present on every repo. This job is designed to be run relatively -// regularly but is not looking to answer "the truth" - it will use the cache of repos and other -// assets to not abuse GitHub and its API exhaustively. Over time repos will converge to having -// the right permissions. -// -// If a repository is "compliance locked", the system teams are not enforced until the lock is removed. - -const maxParallelism = 3; -const delayBetweenSeconds = 1; - -let updatedPermissions = 0; -let updatedRepos = 0; - -const missingTeams = new Set(); - -job.runBackgroundJob(permissionsRun, { - insightsPrefix: 'JobPermissions', -}); - -async function permissionsRun(providers: IProviders): Promise { - const { config, insights, operations } = providers; - if (config?.jobs?.refreshWrites !== true) { - console.log('job is currently disabled to avoid metadata refresh/rewrites'); - return; - } - - const throttle = throat(maxParallelism); - - const organizations = shuffle(Array.from(operations.organizations.values())); - - await Promise.allSettled( - organizations.map((organization, index) => - throttle(async () => { - return reviewOrganizationSystemTeams(providers, organization, index, organizations.length); - }) - ) - ); - - console.log(`Updated ${updatedPermissions} permissions across ${organizations.length} organizations`); - insights?.trackMetric({ name: 'JobSystemTeamsUpdatedPermissions', value: updatedPermissions }); - - console.log(`Updated ${updatedRepos} repos across ${organizations.length} organizations`); - insights?.trackMetric({ name: 'JobSystemTeamsUpdatedRepos', value: updatedRepos }); - - return {}; -} - -async function reviewOrganizationSystemTeams( - providers: IProviders, - organization: Organization, - index: number, - count: number -) { - const { insights } = providers; - const prefix = `${index}/${count}: ${organization.name}: `; - - console.log(`${prefix} Reviewing permissions for all repos in ${organization.name}...`); - try { - const repos = await organization.getRepositories(); - console.log(`Repos in the ${organization.name} org: ${repos.length}`); - const automaticTeams = new AutomaticTeamsWebhookProcessor(); - for (const repo of repos) { - let thisRepoUpdated = false; - console.log(`${organization.name}/${repo.name}`); - sleep(1000 * delayBetweenSeconds); - const cacheOptions = { - maxAgeSeconds: 10 * 60 /* 10m */, - backgroundRefresh: false, - }; - const { specialTeamIds, specialTeamLevels } = automaticTeams.processOrgSpecialTeams(repo.organization); - let permissions: TeamPermission[] = null; - try { - permissions = await repo.getTeamPermissions(cacheOptions); - } catch (getError) { - if (ErrorHelper.IsNotFound(getError)) { - console.log(`Repo gone: ${repo.organization.name}/${repo.name}`); - } else { - console.log( - `There was a problem getting the permissions for the repo ${repo.name} from ${repo.organization.name}` - ); - console.dir(getError); - } - continue; - } - let shouldSkipEnforcement = false; - const { customizedTeamPermissionsWebhookLogic } = providers; - if (customizedTeamPermissionsWebhookLogic) { - shouldSkipEnforcement = await customizedTeamPermissionsWebhookLogic.shouldSkipEnforcement(repo); - } - const currentPermissions = new Map(); - permissions.forEach((entry) => { - currentPermissions.set(Number(entry.team.id), entry.getAsPermission()); - }); - const teamsToSet = new Set(); - specialTeamIds.forEach((specialTeamId) => { - if (!currentPermissions.has(specialTeamId)) { - teamsToSet.add(specialTeamId); - } else if ( - isAtLeastPermissionLevel( - currentPermissions.get(specialTeamId), - specialTeamLevels.get(specialTeamId) - ) - ) { - // The team permission is already acceptable - } else { - console.log( - `Permission level for ${specialTeamId} is not good enough, expected ${specialTeamLevels.get( - specialTeamId - )} but currently ${currentPermissions.get(specialTeamId)}` - ); - teamsToSet.add(specialTeamId); - } - }); - const setArray = Array.from(teamsToSet.values()); - for (const teamId of setArray) { - const newPermission = specialTeamLevels.get(teamId); - if ( - shouldSkipEnforcement && - (newPermission as GitHubRepositoryPermission) !== GitHubRepositoryPermission.Pull - ) { - console.log( - `should add ${teamId} team with permission ${newPermission} to the repo ${repo.name}, but compliance lock prevents non-read system teams` - ); - insights?.trackEvent({ - name: 'JobSystemTeamsSkipped', - properties: { - org: organization.name, - repo: repo.name, - teamId, - reason: 'compliance lock', - newPermission, - }, - }); - } else { - try { - if (!missingTeams.has(teamId)) { - await repo.setTeamPermission(teamId, newPermission as GitHubRepositoryPermission); - ++updatedPermissions; - thisRepoUpdated = true; - insights?.trackEvent({ - name: 'JobSystemTeamsUpdated', - properties: { - org: organization.name, - repo: repo.name, - teamId, - newPermission, - }, - }); - } - } catch (error) { - if (ErrorHelper.IsNotFound(error)) { - missingTeams.add(teamId); - console.log( - `the team ID ${teamId} could not be found when setting to repo ${repo.name} in org ${organization.name} and should likely be removed from config...` - ); - } else { - console.log(`${repo.name}`); - console.dir(error); - throw error; - } - } - } - } - if (thisRepoUpdated) { - ++updatedRepos; - } - } - console.log(`Finished with repos in ${organization.name} organization`); - } catch (processOrganizationError) { - console.dir(processOrganizationError); - console.log(`moving past ${organization.name} processing due to error...`); - } -} - -function isAtLeastPermissionLevel(value, expected) { - if (value !== 'admin' && value !== 'push' && value !== 'pull') { - throw new Error(`The permission type ${value} is not understood by isAtLeastPermissionLevel`); - } - if (value === expected) { - return true; - } - // Admin always wins - if (value === 'admin') { - return true; - } else if (expected === 'admin') { - return false; - } - if (expected === 'write' && value === expected) { - return true; - } - if (expected === 'read') { - return true; - } - return false; -} diff --git a/jobs/permissions/index.ts b/jobs/permissions/index.ts new file mode 100644 index 000000000..40b4097e0 --- /dev/null +++ b/jobs/permissions/index.ts @@ -0,0 +1,14 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +// Job: System Team Permissions + +import Job from './task'; +import app from '../../app'; + +app.runJob(Job, { + insightsPrefix: 'JobPermissions', + defaultDebugOutput: 'cache,restapi', +}); diff --git a/jobs/permissions/task.ts b/jobs/permissions/task.ts new file mode 100644 index 000000000..311e60711 --- /dev/null +++ b/jobs/permissions/task.ts @@ -0,0 +1,155 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +// Job: System Team Permissions + +import { shuffle } from 'lodash'; + +import { TeamPermission } from '../../business/teamPermission'; +import { GitHubRepositoryPermission, IReposJob, IReposJobResult } from '../../interfaces'; +import AutomaticTeamsWebhookProcessor from '../../webhooks/tasks/automaticTeams'; +import { sleep } from '../../utils'; +import { ErrorHelper } from '../../transitional'; + +// Permissions processing: visit all repos and make sure that any designated read, write, admin +// teams for the organization are present on every repo. This job is designed to be run relatively +// regularly but is not looking to answer "the truth" - it will use the cache of repos and other +// assets to not abuse GitHub and its API exhaustively. Over time repos will converge to having +// the right permissions. +// +// If a repository is "compliance locked", the system teams are not enforced until the lock is removed. + +const maxParallelism = 1; + +const delayBetweenSeconds = 1; + +export default async function permissionsRun({ providers }: IReposJob): Promise { + const { config, operations } = providers; + if (config?.jobs?.refreshWrites !== true) { + console.log('job is currently disabled to avoid metadata refresh/rewrites'); + return; + } + + for (const organization of shuffle(Array.from(operations.organizations.values()))) { + console.log(`Reviewing permissions for all repos in ${organization.name}...`); + try { + const repos = await organization.getRepositories(); + console.log(`Repos in the ${organization.name} org: ${repos.length}`); + let z = 0; + const automaticTeams = new AutomaticTeamsWebhookProcessor(); + for (const repo of repos) { + console.log(`${repo.organization.name}/${repo.name}`); + sleep(1000 * delayBetweenSeconds); + const cacheOptions = { + maxAgeSeconds: 10 * 60 /* 10m */, + backgroundRefresh: false, + }; + ++z; + if (z % 250 === 1) { + console.log('. ' + z); + } + const { specialTeamIds, specialTeamLevels } = automaticTeams.processOrgSpecialTeams( + repo.organization + ); + let permissions: TeamPermission[] = null; + try { + permissions = await repo.getTeamPermissions(cacheOptions); + } catch (getError) { + if (getError.status == /* loose */ 404) { + console.log(`Repo gone: ${repo.organization.name}/${repo.name}`); + } else { + console.log( + `There was a problem getting the permissions for the repo ${repo.name} from ${repo.organization.name}` + ); + console.dir(getError); + } + continue; + } + let shouldSkipEnforcement = false; + const { customizedTeamPermissionsWebhookLogic } = providers; + if (customizedTeamPermissionsWebhookLogic) { + shouldSkipEnforcement = await customizedTeamPermissionsWebhookLogic.shouldSkipEnforcement(repo); + } + const currentPermissions = new Map(); + permissions.forEach((entry) => { + currentPermissions.set(Number(entry.team.id), entry.permission); + }); + const teamsToSet = new Set(); + specialTeamIds.forEach((specialTeamId) => { + if (!currentPermissions.has(specialTeamId)) { + teamsToSet.add(specialTeamId); + } else if ( + isAtLeastPermissionLevel( + currentPermissions.get(specialTeamId), + specialTeamLevels.get(specialTeamId) + ) + ) { + // The team permission is already acceptable + } else { + console.log( + `Permission level for ${specialTeamId} is not good enough, expected ${specialTeamLevels.get( + specialTeamId + )} but currently ${currentPermissions.get(specialTeamId)}` + ); + teamsToSet.add(specialTeamId); + } + }); + const setArray = Array.from(teamsToSet.values()); + for (const teamId of setArray) { + const newPermission = specialTeamLevels.get(teamId); + if ( + shouldSkipEnforcement && + (newPermission as GitHubRepositoryPermission) !== GitHubRepositoryPermission.Pull + ) { + console.log( + `should add ${teamId} team with permission ${newPermission} to the repo ${repo.name}, but compliance lock prevents non-read system teams` + ); + } else { + try { + await repo.setTeamPermission(teamId, newPermission as GitHubRepositoryPermission); + } catch (error) { + if (ErrorHelper.IsNotFound(error)) { + console.log( + `the team ID ${teamId} could not be found when setting to repo ${repo.name} in org ${organization.name} and should likely be removed from config...` + ); + } else { + console.log(`${repo.name}`); + console.dir(error); + throw error; + } + } + } + } + } + console.log(`Finished with repos in ${organization.name} organization`); + } catch (processOrganizationError) { + console.dir(processOrganizationError); + console.log(`moving past ${organization.name} processing due to error...`); + } + } + return {}; +} + +function isAtLeastPermissionLevel(value, expected) { + if (value !== 'admin' && value !== 'push' && value !== 'pull') { + throw new Error(`The permission type ${value} is not understood by isAtLeastPermissionLevel`); + } + if (value === expected) { + return true; + } + // Admin always wins + if (value === 'admin') { + return true; + } else if (expected === 'admin') { + return false; + } + if (expected === 'write' && value === expected) { + return true; + } + if (expected === 'read') { + return true; + } + return false; +} diff --git a/jobs/deletedRepositoriesCache.ts b/jobs/refreshQueryCache/deletedRepositories.ts similarity index 91% rename from jobs/deletedRepositoriesCache.ts rename to jobs/refreshQueryCache/deletedRepositories.ts index d68573113..46eaac0ac 100644 --- a/jobs/deletedRepositoriesCache.ts +++ b/jobs/refreshQueryCache/deletedRepositories.ts @@ -1,21 +1,14 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -// Job: Consistency: Deleted repos (7) - -import job from '../job'; -import { Organization } from '../business/organization'; -import { RepositoryCollaboratorCacheEntity } from '../business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; -import { RepositoryTeamCacheEntity } from '../business/entities/repositoryTeamCache/repositoryTeamCache'; -import { IProviders, IReposJobResult } from '../interfaces'; -import { ErrorHelper } from '../lib/transitional'; -import { sleep } from '../lib/utils'; +import app from '../../app'; +import { Organization } from '../../business/organization'; +import { RepositoryCollaboratorCacheEntity } from '../../entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; +import { RepositoryTeamCacheEntity } from '../../entities/repositoryTeamCache/repositoryTeamCache'; +import { IProviders, IReposJob, IReposJobResult } from '../../interfaces'; +import { ErrorHelper } from '../../transitional'; +import { sleep } from '../../utils'; const killBitHours = 8; -job.runBackgroundJob(byUserJob, { +app.runJob(byUserJob, { defaultDebugOutput: 'qcuser', timeoutMinutes: 60 * killBitHours, insightsPrefix: 'JobRefreshUserQC', @@ -209,7 +202,7 @@ async function processDeletedRepositories(providers: IProviders): Promise console.log(`removed collaborator repos: ${removedCollaboratorRepositories}`); } -async function byUserJob(providers: IProviders): Promise { +export default async function byUserJob({ providers, args }: IReposJob): Promise { const { config } = providers; if (config?.jobs?.refreshWrites !== true) { console.log('job is currently disabled to avoid metadata refresh/rewrites'); diff --git a/jobs/refreshQueryCache/index.ts b/jobs/refreshQueryCache/index.ts new file mode 100644 index 000000000..714cb72d2 --- /dev/null +++ b/jobs/refreshQueryCache/index.ts @@ -0,0 +1,15 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import Job from './task'; +import app from '../../app'; + +const killBitHours = 48; + +app.runJob(Job, { + defaultDebugOutput: 'querycache', + timeoutMinutes: 60 * killBitHours, + insightsPrefix: 'JobRefreshQueryCache', +}); diff --git a/jobs/refreshQueryCache.ts b/jobs/refreshQueryCache/task.ts similarity index 97% rename from jobs/refreshQueryCache.ts rename to jobs/refreshQueryCache/task.ts index c4d589fda..18baa46e8 100644 --- a/jobs/refreshQueryCache.ts +++ b/jobs/refreshQueryCache/task.ts @@ -6,17 +6,7 @@ import throat from 'throat'; import { shuffle } from 'lodash'; -const killBitHours = 48; - -import job from '../job'; - -job.runBackgroundJob(refreshQueryCache, { - defaultDebugOutput: 'querycache', - timeoutMinutes: 60 * killBitHours, - insightsPrefix: 'JobRefreshQueryCache', -}); - -import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../lib/transitional'; +import { permissionsObjectToValue } from '../../transitional'; import { Collaborator, Operations, @@ -26,9 +16,9 @@ import { Team, TeamMember, TeamPermission, -} from '../business'; -import { sleep, addArrayToSet } from '../lib/utils'; -import QueryCache from '../business/queryCache'; +} from '../../business'; +import { sleep, addArrayToSet } from '../../utils'; +import QueryCache from '../../business/queryCache'; import { IPagedCacheOptions, ICacheOptions, @@ -47,8 +37,7 @@ import { QueryCacheOperation, IReposJob, IReposJobResult, - IProviders, -} from '../interfaces'; +} from '../../interfaces'; interface IConsistencyStats { new: number; @@ -258,6 +247,7 @@ async function refreshOrganization( const repositories = await organization.getRepositories(slowRequestCacheOptions); console.log(`${organizationIndex}: ${repositories.length} repositories in ${organization.name}`); const repoIds = new Set(repositories.map((repo) => repo.id.toString())); + for (let i = 0; i < repositories.length; i++) { try { const repository = repositories[i]; @@ -385,7 +375,7 @@ async function cacheRepositoryTeams( const repositoryId = repository.id.toString(); for (const teamPermission of repoTeamPermissions) { const teamId = teamPermission.team.id.toString(); - const permission = teamPermission.getAsPermission(); + const permission = teamPermission.permission; const isPrivate = repository.private as boolean; const repoName = repository.name as string; ops.push( @@ -620,9 +610,7 @@ async function cacheRepositoryCollaborators( const operations = []; const repositoryId = repository.id.toString(); for (const collaborator of repoCollaborators) { - const permission = projectCollaboratorPermissionsObjectToGitHubRepositoryPermission( - collaborator.permissions - ); + const permission = permissionsObjectToValue(collaborator.permissions); operations.push( await queryCache.addOrUpdateCollaborator( organizationId, @@ -640,7 +628,7 @@ async function cacheRepositoryCollaborators( return operations.filter((real) => real); } -async function refreshQueryCache(providers: IProviders, { args }: IReposJob): Promise { +export default async function refresh({ providers, args }: IReposJob): Promise { const { config } = providers; if (config?.jobs?.refreshWrites !== true) { console.log('job is currently disabled to avoid metadata refresh/rewrites'); diff --git a/jobs/refreshUsernames.ts b/jobs/refreshUsernames/index.ts similarity index 67% rename from jobs/refreshUsernames.ts rename to jobs/refreshUsernames/index.ts index 275edc1d8..c36d7da88 100644 --- a/jobs/refreshUsernames.ts +++ b/jobs/refreshUsernames/index.ts @@ -6,29 +6,28 @@ // Job: Backfill aliases (3) // Job: User attributes hygiene - alias backfills (4) -import job from '../job'; +import app from '../../app'; import throat from 'throat'; import { shuffle } from 'lodash'; -import { sleep } from '../lib/utils'; -import { IProviders, IReposJobResult, UnlinkPurpose } from '../interfaces'; -import { ErrorHelper } from '../lib/transitional'; +import { sleep } from '../../utils'; +import { IReposJob, IReposJobResult, UnlinkPurpose } from '../../interfaces'; -job.runBackgroundJob(refresh, { +const backfillAliasesOnly = process.env.BACKFILL_ALIASES === '1'; + +app.runJob(refresh, { + defaultDebugOutput: 'cache,restapi', insightsPrefix: 'JobRefreshUsernames', }); -async function refresh(providers: IProviders): Promise { +async function refresh({ providers }: IReposJob): Promise { const { config, operations, insights, linkProvider, graphProvider } = providers; if (config?.jobs?.refreshWrites !== true) { console.log('job is currently disabled to avoid metadata refresh/rewrites'); return; } - const backfillAliasesOnly = config.process.get('BACKFILL_ALIASES') === '1'; - const terminateLinksAndMemberships = config.process.get('REFRESH_USERNAMES_TERMINATE_ACCOUNTS') === '1'; - console.log('reading all links'); let allLinks = shuffle(await linkProvider.getAll()); console.log(`READ: ${allLinks.length} links`); @@ -68,9 +67,6 @@ async function refresh(providers: IProviders): Promise { allLinks.map((link) => throttle(async () => { ++i; - if (i % 100 === 0) { - console.log(`${i}/${allLinks.length}; total updates=${updates}, errors=${errors}`); - } // Refresh GitHub username for the ID const id = link.thirdPartyId; @@ -100,19 +96,7 @@ async function refresh(providers: IProviders): Promise { ++updatedAvatars; } } catch (githubError) { - if (ErrorHelper.IsNotFound(githubError)) { - console.warn( - `Deleted GitHub account, id=${id}, username_was=${link.thirdPartyUsername}; https://api.github.com/users/${link.thirdPartyUsername}` - ); - insights.trackMetric({ name: 'JobRefreshUsernamesMissingGitHubAccounts', value: 1 }); - insights.trackEvent({ - name: 'JobRefreshUsernamesGitHubAccountNotFound', - properties: { githubid: id, error: githubError.message }, - }); - } else { - console.dir(githubError); - } - throw githubError; + console.dir(githubError); } try { @@ -145,17 +129,7 @@ async function refresh(providers: IProviders): Promise { } } catch (graphLookupError) { // Ignore graph lookup issues, other jobs handle terminated employees - if (ErrorHelper.IsNotFound(graphLookupError)) { - console.warn(`Deleted AAD account, id=${id}, username_was=${link.corporateUsername}`); - insights.trackMetric({ name: 'JobRefreshUsernamesMissingCorporateAccounts', value: 1 }); - insights.trackEvent({ - name: 'JobRefreshUsernamesCorporateAccountNotFound', - properties: { githubid: id, error: graphLookupError.message }, - }); - } else { - console.dir(graphLookupError); - } - throw graphLookupError; + console.dir(graphLookupError); } if (changed) { @@ -164,31 +138,28 @@ async function refresh(providers: IProviders): Promise { ++updates; } } catch (getDetailsError) { - if (ErrorHelper.IsNotFound(getDetailsError)) { + if (getDetailsError.status == /* loose compare */ '404') { ++notFoundErrors; insights.trackEvent({ name: 'JobRefreshUsernamesNotFound', - properties: { githubid: id, aadId: link.corporateId, error: getDetailsError.message }, + properties: { githubid: id, error: getDetailsError.message }, }); - if (terminateLinksAndMemberships) { - try { - await operations.terminateLinkAndMemberships(id, { purpose: UnlinkPurpose.Deleted }); - insights.trackEvent({ - name: 'JobRefreshUsernamesUnlinkDelete', - properties: { githubid: id, error: getDetailsError.message }, - }); - } catch (unlinkDeletedAccountError) { - console.dir(unlinkDeletedAccountError); - insights.trackException({ - exception: unlinkDeletedAccountError, - properties: { githubid: id, event: 'JobRefreshUsernamesDeleteError' }, - }); - } + try { + await operations.terminateLinkAndMemberships(id, { purpose: UnlinkPurpose.Deleted }); + insights.trackEvent({ + name: 'JobRefreshUsernamesUnlinkDelete', + properties: { githubid: id, error: getDetailsError.message }, + }); + } catch (unlinkDeletedAccountError) { + console.dir(unlinkDeletedAccountError); + insights.trackException({ + exception: unlinkDeletedAccountError, + properties: { githubid: id, event: 'JobRefreshUsernamesDeleteError' }, + }); } } else { console.dir(getDetailsError); ++errors; - insights.trackMetric({ name: 'JobRefreshUsernamesErrors', value: 1 }); insights.trackException({ exception: getDetailsError, properties: { name: 'JobRefreshUsernamesError' }, @@ -217,8 +188,8 @@ async function refresh(providers: IProviders): Promise { console.log(`Updates: ${updates}`); console.log(`GitHub username changes: ${updatedUsernames}`); console.log(`GitHub avatar changes: ${updatedAvatars}`); - console.log(`Corporate name changes: ${updatedAadNames}`); - console.log(`Corporate username changes: ${updatedAadUpns}`); + console.log(`AAD name changes: ${updatedAadNames}`); + console.log(`AAD username changes: ${updatedAadUpns}`); console.log(`Updated corporate mails: ${updatedCorporateMails}`); return { diff --git a/jobs/repositories.ts b/jobs/repositories.ts index f8e86427e..6c2a306cc 100644 --- a/jobs/repositories.ts +++ b/jobs/repositories.ts @@ -3,27 +3,28 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -// Job 13: refresh repository data - +// JOB 13: refresh repository data // This is very similar to the query cache, but using proper Postgres type entities, and -// not being used by the app today at runtime. Possible optimizations include only -// targeting refreshes based on last-cached times. The act of refreshing these entities -// also helps keep the standard GitHub repository cache up to date. +// not being used by the app today. + +// Implementation is initial and not as robust (will refresh everything, even things not touched +// since the last update; limited telemetry.) import throat from 'throat'; -import job from '../job'; +import app from '../app'; import { Organization, sortByRepositoryDate } from '../business'; -import { RepositoryEntity, tryGetRepositoryEntity } from '../business/entities/repository'; -import { IProviders, IReposJobResult } from '../interfaces'; -import { sleep } from '../lib/utils'; +import { IRepositoryProvider, RepositoryEntity } from '../entities/repository'; +import { IProviders, IReposJob, IReposJobResult } from '../interfaces'; +import { ErrorHelper } from '../transitional'; +import { sleep } from '../utils'; -const sleepBetweenReposMs = 110; +const sleepBetweenReposMs = 125; const maxParallel = 6; const shouldUpdateCached = true; -async function refreshRepositories(providers: IProviders): Promise { +async function refreshRepositories({ providers }: IReposJob): Promise { const { config, operations } = providers; if (config?.jobs?.refreshWrites !== true) { console.log('job is currently disabled to avoid metadata refresh/rewrites'); @@ -31,7 +32,7 @@ async function refreshRepositories(providers: IProviders): Promise 0 ? ' continues' : ''})`); - } + const prefix = `org ${orgIndex}/${orgsLength}: repo ${i}/${repos.length}: `; try { let repositoryEntity = await tryGetRepositoryEntity(repositoryProvider, repo.id); if (await repo.isDeleted()) { @@ -76,33 +73,28 @@ async function processOrganization( continue; } const entity = repo.getEntity(); - let updatedFields: string[] = null; - let replace = false; + let update = false; if (!repositoryEntity) { repositoryEntity = new RepositoryEntity(); - setFields(repositoryEntity, entity, true); + setFields(repositoryProvider, repositoryEntity, entity); await repositoryProvider.insert(repositoryEntity); console.log(`${prefix}inserted ${organization.name}/${repositoryEntity.name}`); continue; } else { - updatedFields = setFields(repositoryEntity, entity, false /* not new */); - replace = updatedFields?.length > 0; + setFields(repositoryProvider, repositoryEntity, entity); + // not detecting changes now + update = true; } - if (updatedFields.length === 0 && shouldUpdateCached) { - replace = true; + if (!update && shouldUpdateCached) { + update = true; repositoryEntity.cached = new Date(); } - if (replace) { + if (update) { await repositoryProvider.replace(repositoryEntity); - updatedFields.length > 0 && - console.log( - `${prefix}Updated ${updatedFields.length} field${updatedFields.length === 1 ? '' : 's'} for ${ - organization.name - }/${repo.name} [${updatedFields.join(', ')}]` - ); + console.log(`${prefix}Updated all fields for ${organization.name}/${repo.name}`); } } catch (error) { - console.warn(`${prefix}repo error: ${repo.name} in organization ${organization.name}: ${error}`); + console.warn(`${prefix}repo error: ${repo.name} in organization ${organization.name}`); } await sleep(sleepBetweenReposMs); @@ -114,237 +106,70 @@ async function processOrganization( return {}; } -function setFields(repositoryEntity: RepositoryEntity, entity: any, isNew: boolean) { - const changed: string[] = []; - if ( - (repositoryEntity.repositoryId || entity.id) && - String(repositoryEntity.repositoryId) !== String(entity.id) - ) { - repositoryEntity.repositoryId = parseInt(entity.id, 10); - changed.push('id'); - } - if ((entity.archived || repositoryEntity.archived) && repositoryEntity.archived !== entity.archived) { - repositoryEntity.archived = entity.archived; - changed.push('archived'); - } +function setFields(repositoryProvider: IRepositoryProvider, repositoryEntity: RepositoryEntity, entity: any) { + repositoryEntity.repositoryId = entity.id; + repositoryEntity.archived = entity.archived; + repositoryEntity.cached = new Date(); if (entity.created_at) { - const createdAt = new Date(entity.created_at); - const currentCreatedAt = repositoryEntity.createdAt ? new Date(repositoryEntity.createdAt) : null; - if (currentCreatedAt && createdAt && currentCreatedAt.toISOString() !== createdAt.toISOString()) { - repositoryEntity.pushedAt = createdAt; - changed.push('created_at'); - } else if (!currentCreatedAt && createdAt) { - repositoryEntity.createdAt = createdAt; - changed.push('created_at'); - } - } - if ( - (entity.default_branch || repositoryEntity.defaultBranch) && - entity.default_branch !== repositoryEntity.defaultBranch - ) { - repositoryEntity.defaultBranch = entity.default_branch; - changed.push('default_branch'); - } - if ( - (entity.description || repositoryEntity.description) && - entity.description !== repositoryEntity.description - ) { - repositoryEntity.description = entity.description; - changed.push('description'); - } - if ((entity.disabled || repositoryEntity.disabled) && entity.disabled !== repositoryEntity.disabled) { - repositoryEntity.disabled = entity.disabled; - changed.push('disabled'); - } - if ((entity.fork || repositoryEntity.fork) && entity.fork !== repositoryEntity.fork) { - repositoryEntity.fork = entity.fork; - changed.push('fork'); - } - if ( - (entity.forks_count || repositoryEntity.forksCount) && - String(entity.forks_count) !== String(repositoryEntity.forksCount) - ) { - repositoryEntity.forksCount = parseInt(entity.forks_count, 10); - changed.push('forks_count'); - } - if ( - (entity.has_downloads || repositoryEntity.hasDownloads) && - entity.has_downloads !== repositoryEntity.hasDownloads - ) { - repositoryEntity.hasDownloads = entity.has_downloads; - changed.push('has_downloads'); - } - if ((entity.has_issues || repositoryEntity.hasIssues) && entity.has_issues !== repositoryEntity.hasIssues) { - repositoryEntity.hasIssues = entity.has_issues; - changed.push('has_issues'); - } - if ((entity.has_pages || repositoryEntity.hasPages) && entity.has_pages !== repositoryEntity.hasPages) { - repositoryEntity.hasPages = entity.has_pages; - changed.push('has_pages'); - } - if ( - (entity.has_projects || repositoryEntity.hasProjects) && - entity.has_projects !== repositoryEntity.hasProjects - ) { - repositoryEntity.hasProjects = entity.has_projects; - changed.push('has_projects'); - } - if ((entity.has_wiki || repositoryEntity.hasWiki) && entity.has_wiki !== repositoryEntity.hasWiki) { - repositoryEntity.hasWiki = entity.has_wiki; - changed.push('has_wiki'); - } - if ((entity.homepage || repositoryEntity.homepage) && entity.homepage !== repositoryEntity.homepage) { - repositoryEntity.homepage = entity.homepage; - changed.push('homepage'); - } - if ((entity.language || repositoryEntity.language) && entity.language !== repositoryEntity.language) { - repositoryEntity.language = entity.language; - changed.push('language'); - } - if (entity.license?.spdx_id !== repositoryEntity.license) { - repositoryEntity.license = entity.license?.spdx_id; - changed.push('license.spdx_id'); - } - if ((entity.full_name || repositoryEntity.fullName) && entity.full_name !== repositoryEntity.fullName) { - repositoryEntity.fullName = entity.full_name; - changed.push('full_name'); - } - if ( - (entity.organization?.id || repositoryEntity.organizationId) && - String(entity.organization?.id) !== String(repositoryEntity.organizationId) - ) { - repositoryEntity.organizationId = parseInt(entity.organization?.id, 10); - changed.push('organization.id'); - } - if (entity.organization?.login !== repositoryEntity.organizationLogin) { - repositoryEntity.organizationLogin = entity.organization?.login; - changed.push('organization.login'); - } - if ((entity.name || repositoryEntity.name) && entity.name !== repositoryEntity.name) { - repositoryEntity.name = entity.name; - changed.push('name'); - } - if ( - (entity.network_count || repositoryEntity.networkCount) && - String(entity.network_count) !== String(repositoryEntity.networkCount) - ) { - repositoryEntity.networkCount = parseInt(entity.network_count, 10); - changed.push('network_count'); - } - if ( - (entity.open_issues_count || repositoryEntity.openIssuesCount) && - String(entity.open_issues_count) !== String(repositoryEntity.openIssuesCount) - ) { - repositoryEntity.openIssuesCount = parseInt(entity.open_issues_count, 10); - changed.push('open_issues_count'); - } - if ( - (entity.parent?.id || repositoryEntity.parentId) && - String(entity.parent?.id) !== String(repositoryEntity.parentId) - ) { - repositoryEntity.parentId = parseInt(entity.parent?.id, 10); - changed.push('parent.id'); - } - if ( - (entity.parent?.login || repositoryEntity.parentName) && - entity.parent?.login !== repositoryEntity.parentName - ) { - repositoryEntity.parentName = entity.parent?.login; - changed.push('parent.login'); - } - if ( - (entity?.parent?.organization?.id || repositoryEntity.parentOrganizationId) && - String(entity?.parent?.organization?.id) !== String(repositoryEntity.parentOrganizationId) - ) { - repositoryEntity.parentOrganizationId = parseInt(entity.parent?.organization?.id, 10); - changed.push('parent.organization.id'); - } - if ( - (entity?.parent?.organization?.login || repositoryEntity.parentOrganizationName) && - entity?.parent?.organization?.login !== repositoryEntity.parentOrganizationName - ) { - repositoryEntity.parentOrganizationName = entity.parent?.organization?.login; - changed.push('parent.organization.login'); - } - if ((entity.private || repositoryEntity.private) && entity.private !== repositoryEntity.private) { - repositoryEntity.private = entity.private; - changed.push('private'); - } + repositoryEntity.createdAt = new Date(entity.created_at); + } + repositoryEntity.defaultBranch = entity.default_branch; + repositoryEntity.description = entity.description; + repositoryEntity.disabled = entity.disabled; + repositoryEntity.fork = entity.fork; + repositoryEntity.forksCount = entity.forks_count; + repositoryEntity.hasDownloads = entity.has_downloads; + repositoryEntity.hasIssues = entity.has_issues; + repositoryEntity.hasPages = entity.has_pages; + repositoryEntity.hasProjects = entity.has_projects; + repositoryEntity.hasWiki = entity.has_wiki; + repositoryEntity.homepage = entity.homepage; + repositoryEntity.language = entity.language; + repositoryEntity.license = entity.license?.spdx_id; + repositoryEntity.fullName = entity.full_name; + repositoryEntity.organizationId = entity.organization?.id; + repositoryEntity.organizationLogin = entity.organization?.login; + repositoryEntity.name = entity.name; + repositoryEntity.networkCount = entity.network_count; + repositoryEntity.openIssuesCount = entity.open_issues_count; + repositoryEntity.organizationId = entity.organization?.id; + repositoryEntity.parentId = entity.parent?.id; + repositoryEntity.parentName = entity.parent?.login; + repositoryEntity.parentOrganizationId = entity.parent?.organization?.id; + repositoryEntity.parentOrganizationName = entity.parent?.organization?.login; + repositoryEntity.private = entity.private; if (entity.pushed_at) { - const pushedAt = new Date(entity.pushed_at); - const currentPushedAt = repositoryEntity.pushedAt ? new Date(repositoryEntity.pushedAt) : null; - if (currentPushedAt && pushedAt && currentPushedAt.toISOString() !== pushedAt.toISOString()) { - repositoryEntity.pushedAt = pushedAt; - changed.push('pushed_at'); - } else if (!currentPushedAt && pushedAt) { - repositoryEntity.pushedAt = pushedAt; - changed.push('pushed_at'); - } - } - if ((entity.size || repositoryEntity.size) && String(entity.size) !== String(repositoryEntity.size)) { - repositoryEntity.size = parseInt(entity.size, 10); - changed.push('size'); - } - if ( - (entity.stargazers_count || repositoryEntity.stargazersCount) && - String(entity.stargazers_count) !== String(repositoryEntity.stargazersCount) - ) { - repositoryEntity.stargazersCount = parseInt(entity.stargazers_count, 10); - changed.push('stargazers_count'); - } - if ( - (entity.subscribers_count || repositoryEntity.subscribersCount) && - String(entity.subscribers_count) !== String(repositoryEntity.subscribersCount) - ) { - repositoryEntity.subscribersCount = parseInt(entity.subscribers_count, 10); - changed.push('subscribers_count'); - } - if (entity.topics && !repositoryEntity.topics) { - repositoryEntity.topics = entity.topics; - changed.push('topics'); - } else if (!entity.topics && repositoryEntity.topics) { - repositoryEntity.topics = null; - changed.push('topics'); - } else { - const storedTopics = [...(repositoryEntity.topics || [])].sort(); - const entityTopics = [...(entity.topics || [])].sort(); - if (storedTopics.join(',') !== entityTopics.join(',')) { - repositoryEntity.topics = entity.topics; - changed.push('topics'); - } + repositoryEntity.pushedAt = new Date(entity.pushed_at); } + repositoryEntity.size = entity.size; + repositoryEntity.stargazersCount = entity.stargazers_count; + repositoryEntity.subscribersCount = entity.subscribers_count; + repositoryEntity.topics = entity.topics; if (entity.updated_at) { - const updatedAt = new Date(entity.updated_at); - const currentUpdatedAt = repositoryEntity.updatedAt ? new Date(repositoryEntity.updatedAt) : null; - if (currentUpdatedAt && updatedAt && currentUpdatedAt.toISOString() !== updatedAt.toISOString()) { - repositoryEntity.updatedAt = updatedAt; - changed.push('updated_at'); - } else if (!currentUpdatedAt && updatedAt) { - repositoryEntity.updatedAt = updatedAt; - changed.push('updated_at'); - } - } - if ( - (entity.visibility || repositoryEntity.visibility) && - entity.visibility !== repositoryEntity.visibility - ) { - repositoryEntity.visibility = entity.visibility; - changed.push('visibility'); + repositoryEntity.updatedAt = new Date(entity.updated_at); } - if ( - (entity.watchers_count || repositoryEntity.watchersCount) && - String(entity.watchers_count) !== String(repositoryEntity.watchersCount) - ) { - repositoryEntity.watchersCount = parseInt(entity.watchers_count, 10); - changed.push('watchers_count'); - } - if (changed.length > 0 || isNew) { - repositoryEntity.cached = new Date(); + repositoryEntity.visibility = entity.visibility; + repositoryEntity.watchersCount = entity.watchers_count; + return repositoryEntity; +} + +async function tryGetRepositoryEntity( + repositoryProvider: IRepositoryProvider, + repositoryId: number +): Promise { + try { + const repositoryEntity = await repositoryProvider.get(repositoryId); + return repositoryEntity; + } catch (error) { + if (ErrorHelper.IsNotFound(error)) { + return null; + } + throw error; } - return changed; } -job.run(refreshRepositories, { - timeoutMinutes: 600, +app.runJob(refreshRepositories, { + timeoutMinutes: 320, + defaultDebugOutput: 'restapi', insightsPrefix: 'JobRefreshRepositories', }); diff --git a/lib/caching/blob.ts b/lib/caching/blob.ts index 7dfeada39..71c49a90b 100644 --- a/lib/caching/blob.ts +++ b/lib/caching/blob.ts @@ -14,7 +14,7 @@ import { } from '@azure/storage-blob'; import { ICacheHelper } from '.'; -import { gunzipBuffer, gzipString } from '../utils'; +import { gunzipBuffer, gzipString } from '../../utils'; import Debug from 'debug'; const debug = Debug.debug('cache'); diff --git a/lib/caching/cosmosdb.ts b/lib/caching/cosmosdb.ts index 4406daa51..9eb9eb0b9 100644 --- a/lib/caching/cosmosdb.ts +++ b/lib/caching/cosmosdb.ts @@ -6,8 +6,8 @@ import { ICacheHelper } from '.'; import { CosmosClient, Database, Container } from '@azure/cosmos'; import BlobCache, { IBlobCacheOptions } from './blob'; -import { sleep } from '../utils'; -import { ErrorHelper, getSafeCosmosResourceKey, sha256 } from '../transitional'; +import { sleep } from '../../utils'; +import { ErrorHelper, sha256 } from '../../transitional'; import Debug from 'debug'; const debug = Debug.debug('cache'); @@ -55,7 +55,7 @@ export default class CosmosCache implements ICacheHelper { } private safetyKey(str: string) { - return getSafeCosmosResourceKey(str); + return str.replace(/[%:\\/?#]/g, ''); } private key(key: string) { diff --git a/lib/caching/redis.ts b/lib/caching/redis.ts index 0b6b8035e..53ed8fa55 100644 --- a/lib/caching/redis.ts +++ b/lib/caching/redis.ts @@ -10,8 +10,8 @@ import Debug from 'debug'; const debug = Debug.debug('redis'); const debugCrossOrganization = Debug.debug('redis-cross-org'); -import type { ICacheHelper } from '.'; -import { gunzipBuffer, gzipString } from '../utils'; +import { ICacheHelper } from '.'; +import { gunzipBuffer, gzipString } from '../../utils'; export interface ISetCompressedOptions { minutesToExpire?: number; diff --git a/lib/campaigns.ts b/lib/campaigns.ts index 5835611cc..1d3418cf2 100644 --- a/lib/campaigns.ts +++ b/lib/campaigns.ts @@ -3,7 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { getSafeCosmosResourceKey } from './transitional'; import CosmosHelper from './cosmosHelper'; export interface ICampaignUserState { @@ -161,9 +160,9 @@ export class StatefulCampaignProvider implements ICampaignHelper { } private key(corporateId: string, campaignGroupId: string, campaignId?: string) { - return getSafeCosmosResourceKey( - campaignId ? `${campaignGroupId}-${campaignId}-${corporateId}` : `${campaignGroupId}-${corporateId}` - ); + return campaignId + ? `${campaignGroupId}-${campaignId}-${corporateId}` + : `${campaignGroupId}-${corporateId}`; } private baseObject(corporateId: string, campaignGroupId: string, campaignId?: string) { diff --git a/lib/config/painlessConfigAsCode.ts b/lib/config/painlessConfigAsCode.ts index 998ef8c67..de5aeb95b 100644 --- a/lib/config/painlessConfigAsCode.ts +++ b/lib/config/painlessConfigAsCode.ts @@ -10,7 +10,6 @@ import path from 'path'; import walkBack from 'walk-back'; import { InnerError, IPainlessConfigGet, IProviderOptions } from '.'; import { processEnvironmentProvider } from './environmentConfigurationResolver'; -import { CreateError } from '../transitional'; const debug = Debug.debug('config'); @@ -71,14 +70,10 @@ function configurePackageEnvironments( try { values = environmentPackage(environment); } catch (problemCalling) { - const asText = problemCalling.toString() as string; - let suggestion = ''; - if (asText.includes('Unable to require environment') && asText.includes('dist')) { - suggestion = 'Consider deleting and rebuilding the `dist` directory. '; - } - throw CreateError.ServerError( - `${suggestion}While calling the environment package "${npmName}" for the "${environment}" environment an error was thrown: ${asText}`, - problemCalling + const asText = problemCalling.toString(); + throw new Error( + `While calling the environment package "${npmName}" for the "${environment}" environment an error was thrown: ${asText}`, + { cause: problemCalling } ); } } else if (typeof environmentPackage === 'object') { diff --git a/lib/cosmosSession/index.ts b/lib/cosmosSession/index.ts index a457a8da3..d1eb0a313 100644 --- a/lib/cosmosSession/index.ts +++ b/lib/cosmosSession/index.ts @@ -7,7 +7,7 @@ import { CosmosClient, Database, Container } from '@azure/cosmos'; import { Store } from 'express-session'; import { IAppSession } from '../../interfaces'; -import { ErrorHelper } from '../transitional'; +import { ErrorHelper } from '../../transitional'; export interface ICosmosSessionProviderOptions { endpoint: string; diff --git a/lib/entityMetadataProvider/entityMetadataProvider.ts b/lib/entityMetadataProvider/entityMetadataProvider.ts index 6693c9ff0..190943c08 100644 --- a/lib/entityMetadataProvider/entityMetadataProvider.ts +++ b/lib/entityMetadataProvider/entityMetadataProvider.ts @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { type IEntityMetadata, EntityMetadataType } from './entityMetadata'; -import type { IEntityMetadataFixedQuery } from './query'; -import { swapMap } from '../utils'; +import { IEntityMetadata, EntityMetadataType } from './entityMetadata'; +import { IEntityMetadataFixedQuery } from './query'; +import { swapMap } from '../../utils'; export enum EntityField { Type = 'entityType', diff --git a/lib/entityMetadataProvider/postgres.ts b/lib/entityMetadataProvider/postgres.ts index 3a274c165..9928d9153 100644 --- a/lib/entityMetadataProvider/postgres.ts +++ b/lib/entityMetadataProvider/postgres.ts @@ -22,7 +22,7 @@ import { MetadataMappingDefinition, MetadataMappingDefinitionBase, } from './declarations'; -import { CreateError } from '../transitional'; +import { CreateError } from '../../transitional'; import { IDictionary } from '../../interfaces'; const MetadataColumnName = 'metadata'; @@ -34,12 +34,6 @@ const MapMetadataPropertiesToFields: any = { entityType: 'entitytype', }; -export enum PostgresColumnTranslations { - None = 'none', - Lowercase = 'lowercase', - LowercaseUnderscores = 'lowercase_underscores', -} - class PostgresMetadataDefinition extends MetadataMappingDefinitionBase { constructor(name: string) { super(name); @@ -200,23 +194,6 @@ class PostgresInternals { } } -function translateName(key: string, translations: PostgresColumnTranslations) { - switch (translations) { - case PostgresColumnTranslations.None: { - return key; - } - case PostgresColumnTranslations.Lowercase: { - return key.toLowerCase(); - } - case PostgresColumnTranslations.LowercaseUnderscores: { - return key.replace(/([A-Z])/g, '_$1').toLowerCase(); - } - default: { - throw CreateError.InvalidParameters(`Invalid column translation type: ${translations}`); - } - } -} - export class PostgresConfiguration { static IdentifyNativeFields(type: EntityMetadataType, fieldNames: string[]) { PostgresInternals.instance(type).nativeFieldNames = fieldNames; @@ -229,12 +206,11 @@ export class PostgresConfiguration { static MapFieldsToColumnNames( type: EntityMetadataType, map: Map, - columnTranslations: PostgresColumnTranslations = PostgresColumnTranslations.None + lowercaseColumnNamesAutomatically?: boolean ) { const dest = PostgresInternals.instance(type).mapFieldsToColumnNames; for (const [key, value] of map.entries()) { - const translatedValue = translateName(value, columnTranslations); - dest.set(key, translatedValue); + dest.set(key, lowercaseColumnNamesAutomatically ? value.toLowerCase() : value); } } @@ -254,19 +230,7 @@ export class PostgresConfiguration { return [fieldName, fieldName]; }) ), - PostgresColumnTranslations.Lowercase - ); - } - - static MapFieldsToColumnNamesFromListUnderscoreLowercased(type: EntityMetadataType, fieldNames: string[]) { - PostgresConfiguration.MapFieldsToColumnNames( - type, - new Map( - fieldNames.map((fieldName) => { - return [fieldName, fieldName]; - }) - ), - PostgresColumnTranslations.LowercaseUnderscores + true ); } @@ -688,18 +652,18 @@ export class PostgresEntityMetadataProvider implements IEntityMetadataProvider { } } - // private metadataToRowMetadata(metadata: IEntityMetadata): any { - // const shallowClone = Object.assign({}, metadata); - // delete shallowClone.entityCreated; - // delete shallowClone.entityFieldNames; - // delete shallowClone.entityId; - // delete shallowClone.entityType; - // return shallowClone; - // } + private metadataToRowMetadata(metadata: IEntityMetadata): any { + const shallowClone = Object.assign({}, metadata); + delete shallowClone.entityCreated; + delete shallowClone.entityFieldNames; + delete shallowClone.entityId; + delete shallowClone.entityType; + return shallowClone; + } - // private stripEntityIdentities(type: EntityMetadataType, entity: any) { - // return stripEntityIdentities(type, entity); - // } + private stripEntityIdentities(type: EntityMetadataType, entity: any) { + return stripEntityIdentities(type, entity); + } private rowToMetadataObject(type: EntityMetadataType, row: any): IEntityMetadata { return rowToMetadataObject(type, row); diff --git a/lib/entityMetadataProvider/query.ts b/lib/entityMetadataProvider/query.ts index 6c9af613a..c902218e6 100644 --- a/lib/entityMetadataProvider/query.ts +++ b/lib/entityMetadataProvider/query.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import type { IEntityMetadataProvider } from './entityMetadataProvider'; +import { IEntityMetadataProvider } from './entityMetadataProvider'; import { EntityMetadataType, EntityMetadataBase } from './entityMetadata'; // Newer "entity" implementations have fully decoupled and no longer use this single query type. diff --git a/lib/entityMetadataProvider/table.ts b/lib/entityMetadataProvider/table.ts index 5980472ec..4ec002995 100644 --- a/lib/entityMetadataProvider/table.ts +++ b/lib/entityMetadataProvider/table.ts @@ -50,7 +50,7 @@ import { MetadataMappingDefinitionBase, } from './declarations'; import { encryptTableEntity, decryptTableEntity, ITableEncryptionOperationOptions } from './tableEncryption'; -import { CreateError, ErrorHelper } from '../transitional'; +import { CreateError, ErrorHelper } from '../../transitional'; import { IKeyVaultSecretResolver } from '../keyVaultResolver'; export interface ITableEncryptionOptions { diff --git a/lib/github/appPurposes.ts b/lib/github/appPurposes.ts deleted file mode 100644 index 4373de395..000000000 --- a/lib/github/appPurposes.ts +++ /dev/null @@ -1,277 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { ExecutionEnvironment } from '../../interfaces'; -import { CreateError } from '../transitional'; - -import Debug from 'debug'; -import { GitHubTokenManager } from './tokenManager'; -import GitHubApplication from '../../business/application'; -import { Operations, OperationsCore } from '../../business'; - -const debug = Debug('github:tokens'); - -export enum AppPurpose { - Data = 'Data', - CustomerFacing = 'CustomerFacing', - Operations = 'Operations', - BackgroundJobs = 'BackgroundJobs', // "secondary" / "default" fallback - Updates = 'Updates', - Security = 'Security', - ActionsData = 'ActionsData', -} - -export interface ICustomAppPurpose { - isCustomAppPurpose: boolean; // basic type check - id: string; - name: string; - getForOrganizationName?(organizationName: string): IGitHubAppConfiguration; - getApplicationConfigurationForInitialization?(): IGitHubAppConfiguration; -} - -export type AppPurposeTypes = AppPurpose | ICustomAppPurpose; - -export type CustomAppPurposeWithGetApplications = ICustomAppPurpose & { - getGitHubAppInstances: () => GitHubApplication[]; -}; - -export abstract class CustomAppPurpose implements ICustomAppPurpose { - get isCustomAppPurpose() { - return true; - } - constructor( - public id: string, - public name: string - ) {} -} - -export class CustomAppPurposeOrganizationVariance extends CustomAppPurpose { - private _appsByAppId = new Map(); - - fallbackIfNotConfiguredOrganizationName = false; - - constructor( - private operations: Operations, - public id: string, - public name: string, - private configurations: IGitHubAppConfiguration[] - ) { - super(id, name); - } - - getForOrganizationName(organizationName: string) { - const configuration = this.configurations.find( - (c) => c.specificOrganizationName.toLowerCase() === organizationName.toLowerCase() - ); - if (!configuration && this.fallbackIfNotConfiguredOrganizationName === false) { - throw CreateError.NotFound(`No configuration found for organization ${organizationName}`); - } - return configuration || this.configurations[0]; - } - - getGitHubAppInstances() { - const uniqueAppIds = new Set(this.configurations.map((c) => c.appId).filter((id) => !!id)); - const appInstances: GitHubApplication[] = []; - for (const appId of uniqueAppIds) { - let instance = this._appsByAppId.get(appId); - if (!instance) { - instance = createGitHubAppInstance( - this.operations, - this.configurations.find((c) => c.appId === appId), - this - ); - this._appsByAppId.set(appId, instance); - } - appInstances.push(instance); - } - return appInstances; - } -} - -export class CustomAppPurposeSingleConfiguration extends CustomAppPurpose { - private _appInstance: GitHubApplication; - - constructor( - private operations: Operations, - public id: string, - public name: string, - private configuration: IGitHubAppConfiguration - ) { - super(id, name); - } - - getApplicationConfigurationForInitialization() { - return this.configuration; - } - - getGitHubAppInstances() { - if (!this._appInstance) { - this._appInstance = createGitHubAppInstance(this.operations, this.configuration, this); - } - return this._appInstance; - } -} - -function createGitHubAppInstance( - operations: Operations, - configuration: IGitHubAppConfiguration, - customPurpose: AppPurposeTypes -) { - const app = new GitHubApplication( - operations, - configuration.appId, - configuration.slug, - configuration.description || configuration.slug, - getAppAuthorizationHeader.bind(this, operations, configuration, customPurpose) - ); - return app; -} - -async function getAppAuthorizationHeader( - operations: Operations, - configuration: IGitHubAppConfiguration, - purpose: AppPurposeTypes -): Promise { - const appId = configuration.appId; - const tokenManager = GitHubTokenManager.TryGetTokenManagerForOperations(operations); - const appTokens = await tokenManager.ensureConfigurationAppInitialized(purpose, configuration); - if (!appTokens) { - CreateError.InvalidParameters(`No app tokens found configured for app ID ${appId} in tokens instance.`); - } - const jwt = await appTokens.getAppAuthenticationToken(); - const value = `bearer ${jwt}`; - return value; -} - -export const DefinedAppPurposes = [ - AppPurpose.Data, - AppPurpose.CustomerFacing, - AppPurpose.Operations, - AppPurpose.BackgroundJobs, - AppPurpose.Updates, - AppPurpose.Security, - AppPurpose.ActionsData, -]; - -// export const GitHubAppPurposesExemptFromAllRepositoriesSelection = [AppPurpose.Onboarding]; - -const appPurposeToConfigurationName = { - [AppPurpose.Data]: 'data', - [AppPurpose.CustomerFacing]: 'ui', - [AppPurpose.Operations]: 'operations', - [AppPurpose.BackgroundJobs]: 'jobs', - [AppPurpose.Updates]: 'updates', - [AppPurpose.Security]: 'security', - [AppPurpose.ActionsData]: 'actions', -}; - -export function getAppPurposeId(purpose: AppPurposeTypes) { - if (!purpose) { - return 'n/a'; - } - if ((purpose as ICustomAppPurpose).isCustomAppPurpose === true) { - return (purpose as ICustomAppPurpose).id; - } - const asPurpose = purpose as AppPurpose; - const id = appPurposeToConfigurationName[asPurpose]; - if (!id) { - throw new Error(`No configuration name for purpose ${asPurpose}`); - } - return id; -} - -export function tryGetAppPurposeAppConfiguration(purpose: AppPurposeTypes, organizationName: string) { - if ( - (purpose as ICustomAppPurpose).isCustomAppPurpose === true && - (purpose as ICustomAppPurpose).getForOrganizationName - ) { - return (purpose as ICustomAppPurpose).getForOrganizationName(organizationName); - } -} - -export function tryGetAppPurposeGitHubAppInstances(purpose: AppPurposeTypes) { - if ( - (purpose as ICustomAppPurpose).isCustomAppPurpose === true && - (purpose as CustomAppPurposeWithGetApplications).getGitHubAppInstances - ) { - return (purpose as CustomAppPurposeWithGetApplications).getGitHubAppInstances(); - } - const operations = GitHubAppPurposes.GetOperationsInstanceForBuiltInPurposes(); - const tokenManager = GitHubTokenManager.TryGetTokenManagerForOperations(operations); - const appTokens = tokenManager.getAppForPurpose(purpose); - if (!appTokens) { - throw CreateError.InvalidParameters(`No app tokens found configured for purpose ${purpose}`); - } - const appId = appTokens.appId; - if (!appId) { - throw CreateError.InvalidParameters(`No app ID found configured for purpose ${purpose}`); - } - return [operations.getApplicationById(appId)]; -} - -export class GitHubAppPurposes { - private _operations: Operations; - private static _instance: GitHubAppPurposes = new GitHubAppPurposes(); - - static get AllAvailableAppPurposes() { - debug(`Retrieving all available purposes (${this._instance._purposes.length})`); - return this._instance._purposes; - } - - static RegisterOperationsInstanceForBuiltInPurposes(operations: Operations) { - this._instance._operations = operations; - } - - static GetOperationsInstanceForBuiltInPurposes() { - return this._instance._operations; - } - - static RegisterCustomPurpose(purpose: ICustomAppPurpose) { - debug(`Registering custom purpose ${purpose.id} (${purpose.name})`); - if (purpose.isCustomAppPurpose !== true) { - throw new Error('Purpose must have `isCustomAppPurpose` set to true'); - } - if ( - (this._instance._purposes as ICustomAppPurpose[]) - .filter((p) => (p as ICustomAppPurpose)?.isCustomAppPurpose === true) - .find((p) => p.id === purpose.id) - ) { - throw new Error(`Purpose with ID ${purpose.id} already registered`); - } - this._instance._purposes.push(purpose); - } - - private _purposes: AppPurposeTypes[]; - - constructor() { - this._purposes = [...DefinedAppPurposes]; - } -} - -export enum GitHubAppAuthenticationType { - ForceSpecificInstallation = 'force', - BestAvailable = 'best', -} - -export interface IGitHubAppConfiguration { - clientId?: string; - clientSecret?: string; - appId?: number; - appKey?: string; - appKeyFile?: string; - webhookSecret?: string; - slug?: string; - description?: string; - baseUrl?: string; - - specificOrganizationName?: string; -} - -export interface IGitHubAppsOptions { - operations: OperationsCore; - // app: IReposApplication; - configurations: Map; - executionEnvironment: ExecutionEnvironment; -} diff --git a/lib/github/collections.ts b/lib/github/collections.ts index 228ac649c..cb18c7215 100644 --- a/lib/github/collections.ts +++ b/lib/github/collections.ts @@ -9,30 +9,20 @@ import Debug from 'debug'; const debug = Debug.debug('restapi'); import cost from './cost'; -import { RestResponse, flattenData } from './core'; +import { IRestResponse, flattenData } from './core'; import { CompositeApiContext, CompositeIntelligentEngine } from './composite'; import { Collaborator } from '../../business/collaborator'; import { Team } from '../../business/team'; -import { IPagedCacheOptions, GetAuthorizationHeader, IDictionary } from '../../interfaces'; +import { IPagedCacheOptions, IGetAuthorizationHeader, IDictionary } from '../../interfaces'; import { RestLibrary } from '.'; -import { sleep } from '../utils'; +import { sleep } from '../../utils'; import GitHubApplication from '../../business/application'; import { RepositoryPrimaryProperties } from '../../business/primaryProperties'; -import { RepositoryInvitation } from '../../business/repositoryInvitation'; export interface IGetAppInstallationsParameters { app_id: string; } -type WithPage = T & { page?: number }; - -type WithOctokitRequest = T & { octokitRequest?: string }; - -export type CollectionCopilotSeatsOptions = { - org: string; - per_page?: number; -}; - export enum GitHubPullRequestState { Open = 'open', Closed = 'closed', @@ -61,45 +51,23 @@ export interface IListPullsParameters { direction?: GitHubSortDirection; } -const mostBasicAccountProperties = ['id', 'login', 'avatar_url']; - const branchDetailsToCopy = ['name', 'commit', 'protected']; const repoDetailsToCopy = RepositoryPrimaryProperties; const teamDetailsToCopy = Team.PrimaryProperties; const memberDetailsToCopy = Collaborator.PrimaryProperties; const appInstallDetailsToCopy = GitHubApplication.PrimaryInstallationProperties; const contributorsDetailsToCopy = [...Collaborator.PrimaryProperties, 'contributions']; -const repoInviteDetailsToCopy = RepositoryInvitation.PrimaryProperties; - -type SubReducerProperties = Record; -type WithSubPropertyReducer = any[] & { subPropertiesToReduce?: SubReducerProperties }; - -const copilotSeatPropertiesToCopy: WithSubPropertyReducer = [ - 'created_at', - 'updated_at', - 'last_activity_at', - 'last_activity_editor', - 'assignee', // id, login; mostBasicAccountProperties -]; -copilotSeatPropertiesToCopy.subPropertiesToReduce = { - assignee: mostBasicAccountProperties, -}; - -const teamPermissionsToCopyForRepository = [ - 'name', +const teamPermissionsToCopy = [ 'id', + 'name', 'slug', 'description', - // 'members_count', - // 'repos_count', + 'members_count', + 'repos_count', 'privacy', - // 'notification_setting', - 'permission', // custom role name at times - 'permissions', // array of booleans for admin, maintain, push, triage, pull - 'parent', // large object for a parent team, if present + 'permission', ]; - const teamRepoPermissionsToCopy = [ 'id', 'name', @@ -108,9 +76,7 @@ const teamRepoPermissionsToCopy = [ 'private', 'fork', 'permissions', - 'role_name', ]; - const pullDetailsToCopy = [ 'id', 'number', @@ -157,56 +123,8 @@ export class RestCollections { this.githubCall = githubCall; } - collectAllPages( - token: string | GetAuthorizationHeader, - collectionCacheKey: string, - octokitApiName: string, - parameters: ParametersType, - cacheOptions: IPagedCacheOptions, - fieldNamesToKeep?: string[] | WithSubPropertyReducer, - arrayReducePropertyName?: string - ): Promise { - return this.generalizedCollectionWithFilter( - collectionCacheKey, - octokitApiName, - fieldNamesToKeep, - token, - parameters, - cacheOptions, - arrayReducePropertyName - ); - } - - collectAllPagesViaHttpGet( - token: string | GetAuthorizationHeader, - collectionCacheKey: string, - getRestUrl: string, - parameters: ParametersType, - cacheOptions: IPagedCacheOptions, - fieldNamesToKeep?: string[] | WithSubPropertyReducer, - arrayReducePropertyName?: string - ): Promise { - const expandedOptions: WithOctokitRequest = Object.assign( - { - octokitRequest: getRestUrl.startsWith('GET ') ? getRestUrl.substr(4) : getRestUrl, - }, - parameters - ); - return this.collectAllPages( - token, - collectionCacheKey, - 'request', - expandedOptions, - cacheOptions, - fieldNamesToKeep, - arrayReducePropertyName - ); - } - - // --- - getOrgRepos( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -221,7 +139,7 @@ export class RestCollections { } getOrgTeams( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -236,7 +154,7 @@ export class RestCollections { } getTeamChildTeams( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -251,7 +169,7 @@ export class RestCollections { } getUserActivity( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -266,7 +184,7 @@ export class RestCollections { } getOrgMembers( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -280,33 +198,8 @@ export class RestCollections { ); } - getOrganizationCopilotSeats( - token: string | GetAuthorizationHeader, - options: CollectionCopilotSeatsOptions, - cacheOptions: IPagedCacheOptions - ): Promise { - // technically type CopilotSeatData - const orgName = options.org; - delete options.org; - const params = Object.assign( - { - octokitRequest: `GET /orgs/${orgName}/copilot/billing/seats`, - }, - options - ); - return this.generalizedCollectionWithFilter( - 'orgCopilotSeats', - 'request', - copilotSeatPropertiesToCopy, - token, - params, - cacheOptions, - 'seats' - ); - } - getAppInstallations( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, parameters: IGetAppInstallationsParameters, cacheOptions: IPagedCacheOptions ): Promise { @@ -327,7 +220,7 @@ export class RestCollections { } getRepoIssues( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -342,7 +235,7 @@ export class RestCollections { } getRepoProjects( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -357,14 +250,14 @@ export class RestCollections { } getRepoTeams( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { return this.generalizedCollectionWithFilter( 'repoTeamPermissions', 'repos.listTeams', - teamPermissionsToCopyForRepository, + teamPermissionsToCopy, token, options, cacheOptions @@ -372,7 +265,7 @@ export class RestCollections { } getRepoContributors( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -387,7 +280,7 @@ export class RestCollections { } getRepoCollaborators( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -401,23 +294,8 @@ export class RestCollections { ); } - getRepoInvitations( - token: string | GetAuthorizationHeader, - options, - cacheOptions: IPagedCacheOptions - ): Promise { - return this.generalizedCollectionWithFilter( - 'repoInvitations', - 'repos.listInvitations', - repoInviteDetailsToCopy, - token, - options, - cacheOptions - ); - } - getRepoBranches( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -432,7 +310,7 @@ export class RestCollections { } getRepoPullRequests( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options: IListPullsParameters, cacheOptions: IPagedCacheOptions ): Promise { @@ -447,7 +325,7 @@ export class RestCollections { } getTeamMembers( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -462,7 +340,7 @@ export class RestCollections { } getTeamRepos( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -476,12 +354,11 @@ export class RestCollections { ); } - private async getGithubCollection( - token: string | GetAuthorizationHeader, - methodName: string, - options: OptionsType, - cacheOptions: IPagedCacheOptions, - arrayReducePropertyName?: string + private async getGithubCollection( + token: string | IGetAuthorizationHeader, + methodName, + options, + cacheOptions: IPagedCacheOptions ): Promise { const hasNextPage = this.libraryContext.hasNextPage; const githubCall = this.githubCall; @@ -491,14 +368,14 @@ export class RestCollections { const requests = []; let pages = 0; let currentPage = 0; - const pageLimit = (options as any)?.pageLimit || cacheOptions['pageLimit'] || Number.MAX_VALUE; + const pageLimit = options.pageLimit || cacheOptions['pageLimit'] || Number.MAX_VALUE; const pageRequestDelay = cacheOptions.pageRequestDelay || null; while (!done) { const method = githubCall; const args = []; const currentToken = typeof token === 'string' ? token : await token(); args.push(currentToken); - const clonedOptions: WithPage = Object.assign({}, options); + const clonedOptions = Object.assign({}, options); if (++currentPage > 1) { clonedOptions.page = currentPage; } @@ -507,19 +384,6 @@ export class RestCollections { let result = null; try { result = await (method as any).apply(null, args); - if ( - arrayReducePropertyName && - result[arrayReducePropertyName] && - Array.isArray(result[arrayReducePropertyName]) - ) { - const originalResultProperties = { - headers: result?.headers, - cost: result?.cost, - }; - result = result[arrayReducePropertyName]; - result.headers = originalResultProperties.headers; - result.cost = originalResultProperties.cost; - } recentResult = result; if (result) { ++pages; @@ -568,26 +432,17 @@ export class RestCollections { return { data, requests }; } - private async getFilteredGithubCollection( - token: string | GetAuthorizationHeader, - methodName: string, - options: OptionsType, + private async getFilteredGithubCollection( + token: string | IGetAuthorizationHeader, + methodName, + options, cacheOptions: IPagedCacheOptions, - propertiesToKeep: string[], - arrayReducePropertyName?: string + propertiesToKeep ): Promise { const keepAll = !propertiesToKeep; - const subReductionProperties = - propertiesToKeep && (propertiesToKeep as WithSubPropertyReducer).subPropertiesToReduce; try { // IRequestWithData - const getCollectionResponse = await this.getGithubCollection( - token, - methodName, - options, - cacheOptions, - arrayReducePropertyName - ); + const getCollectionResponse = await this.getGithubCollection(token, methodName, options, cacheOptions); if (!getCollectionResponse) { throw new Error('No response'); } @@ -607,14 +462,6 @@ export class RestCollections { const r = {}; _.forOwn(doNotModify, (value, key) => { if (keepAll || propertiesToKeep.indexOf(key) >= 0) { - if (subReductionProperties && subReductionProperties[key]) { - const validSubKeys = new Set(subReductionProperties[key]); - for (const subKey of Object.getOwnPropertyNames(value)) { - if (!validSubKeys.has(subKey)) { - delete value[subKey]; - } - } - } r[key] = value; } }); @@ -633,23 +480,21 @@ export class RestCollections { } } - private async getFilteredGithubCollectionWithMetadataAnalysis( - token: string | GetAuthorizationHeader, - methodName: string, - options: OptionsType, + private async getFilteredGithubCollectionWithMetadataAnalysis( + token: string | IGetAuthorizationHeader, + methodName, + options, cacheOptions: IPagedCacheOptions, - propertiesToKeep: string[], - arrayReducePropertyName?: string - ): Promise { - const collectionResults = await this.getFilteredGithubCollection( + propertiesToKeep + ): Promise { + const collectionResults = await this.getFilteredGithubCollection( token, methodName, options, cacheOptions, - propertiesToKeep, - arrayReducePropertyName + propertiesToKeep ); - const results = collectionResults.data as RestResponse; + const results = collectionResults.data as IRestResponse; const requests = collectionResults.requests; const pages = []; let dirty = false; @@ -686,12 +531,12 @@ export class RestCollections { } private generalizedCollectionMethod( - token: string | GetAuthorizationHeader, + token: string | IGetAuthorizationHeader, apiName: string, method, options, cacheOptions: IPagedCacheOptions - ): Promise { + ): Promise { const apiContext = new CompositeApiContext(apiName, method, options); apiContext.maxAgeSeconds = cacheOptions.maxAgeSeconds || 600; apiContext.overrideToken(token); @@ -703,47 +548,37 @@ export class RestCollections { return compositeEngine.execute(apiContext); } - private getCollectionAndFilter( - token: string | GetAuthorizationHeader, - options: OptionsType, + private getCollectionAndFilter( + token: string | IGetAuthorizationHeader, + options, cacheOptions: IPagedCacheOptions, - githubClientMethod: string, - propertiesToKeep: string[], - arrayReducePropertyName?: string + githubClientMethod, + propertiesToKeep ) { const capturedThis = this; - return function (token: string | GetAuthorizationHeader, options: OptionsType) { - return capturedThis.getFilteredGithubCollectionWithMetadataAnalysis( + return function (token, options) { + return capturedThis.getFilteredGithubCollectionWithMetadataAnalysis( token, githubClientMethod, options, cacheOptions, - propertiesToKeep, - arrayReducePropertyName + propertiesToKeep ); }; } - private async generalizedCollectionWithFilter( - name: string, - githubClientMethod: string, - propertiesToKeep: string[], - token: string | GetAuthorizationHeader, - options: OptionsType, - cacheOptions: IPagedCacheOptions, - arrayReducePropertyName?: string - ): Promise { + private async generalizedCollectionWithFilter( + name, + githubClientMethod, + propertiesToKeep, + token, + options, + cacheOptions: IPagedCacheOptions + ): Promise { const rows = await this.generalizedCollectionMethod( token, name, - this.getCollectionAndFilter( - token, - options, - cacheOptions, - githubClientMethod, - propertiesToKeep, - arrayReducePropertyName - ), + this.getCollectionAndFilter(token, options, cacheOptions, githubClientMethod, propertiesToKeep), options, cacheOptions ); diff --git a/lib/github/composite.ts b/lib/github/composite.ts index 21bfa9551..ab9ae1d6a 100644 --- a/lib/github/composite.ts +++ b/lib/github/composite.ts @@ -13,16 +13,16 @@ import Debug from 'debug'; const debug = Debug.debug('restapi'); import { - ShouldServeCache, + IShouldServeCache, ApiContext, IntelligentEngine, IApiContextRedisKeys, IApiContextCacheValues, ApiContextType, - RestMetadata, - RestResponse, + IRestMetadata, + IRestResponse, } from './core'; -import { GetAuthorizationHeader } from '../../interfaces'; +import { IGetAuthorizationHeader } from '../../interfaces'; import appPackage from '../../package.json'; @@ -34,7 +34,7 @@ const acceleratedExpirationMinutes = 60; // 1 hour export class CompositeApiContext extends ApiContext { private _apiMethod: any; private _apiTypePrefix: string; - private _token: string | GetAuthorizationHeader; + private _token: string | IGetAuthorizationHeader; private _cacheValues: IApiContextCacheValues; private _redisKeys: IApiContextRedisKeys; @@ -74,11 +74,11 @@ export class CompositeApiContext extends ApiContext { return this._cacheValues; } - get token(): string | GetAuthorizationHeader { + get token(): string | IGetAuthorizationHeader { return this._token; } - overrideToken(token: string | GetAuthorizationHeader) { + overrideToken(token: string | IGetAuthorizationHeader) { this._token = token; } @@ -98,12 +98,12 @@ export class CompositeApiContext extends ApiContext { export class CompositeIntelligentEngine extends IntelligentEngine { withMetadataShouldCacheBeServed( apiContext: ApiContext, - metadata: RestMetadata - ): boolean | ShouldServeCache { + metadata: IRestMetadata + ): boolean | IShouldServeCache { // result can be falsy OR an object; { cache: true, refresh: true } // cache: whether to use the cache, if available // refresh: whether to refresh in the background for a newer value - let shouldServeCache: ShouldServeCache | boolean = false; + let shouldServeCache: IShouldServeCache | boolean = false; const maxAgeSeconds = apiContext.maxAgeSeconds; const updatedIso = metadata ? metadata.updated : null; const refreshingIso = metadata ? metadata.refreshing : null; @@ -173,7 +173,7 @@ export class CompositeIntelligentEngine extends IntelligentEngine { return shouldServeCache; } - withResponseShouldCacheBeServed(apiContext: ApiContext, response: RestResponse) { + withResponseShouldCacheBeServed(apiContext: ApiContext, response: IRestResponse) { if (typeof response === 'function') { throw new Error('The response must not be a function'); } @@ -198,16 +198,16 @@ export class CompositeIntelligentEngine extends IntelligentEngine { return shouldUseCache; } - optionalStripResponse(apiContext: ApiContext, response: RestResponse): RestResponse { + optionalStripResponse(apiContext: ApiContext, response: IRestResponse): IRestResponse { // Composite does not strip any results further before caching return response; } - withResponseUpdateMetadata(apiContext: ApiContext, response: RestResponse) { + withResponseUpdateMetadata(apiContext: ApiContext, response: IRestResponse) { return response; } - reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: RestResponse) { + reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: IRestResponse) { // No reduction for object type metadata. // Store the app version in case it is needed for a future // schema update or cache invalidation @@ -217,7 +217,7 @@ export class CompositeIntelligentEngine extends IntelligentEngine { } } - async callApi(apiContext: CompositeApiContext): Promise { + async callApi(apiContext: CompositeApiContext): Promise { const args = []; const apiMethod = apiContext.apiMethod; if (apiContext.token) { @@ -232,10 +232,10 @@ export class CompositeIntelligentEngine extends IntelligentEngine { } catch (applyError) { throw applyError; } - return unknown as RestResponse; + return unknown as IRestResponse; } - getResponseMetadata(apiContext: CompositeApiContext, response: RestResponse): RestMetadata { + getResponseMetadata(apiContext: CompositeApiContext, response: IRestResponse): IRestMetadata { const headers = response.headers || {}; const calledTime = apiContext.calledTime ? apiContext.calledTime.toISOString() : new Date().toISOString(); headers.updated = calledTime; @@ -251,7 +251,7 @@ export class CompositeIntelligentEngine extends IntelligentEngine { return headers; } - processMetadataBeforeCall(apiContext: CompositeApiContext, metadata: RestMetadata) { + processMetadataBeforeCall(apiContext: CompositeApiContext, metadata: IRestMetadata) { if (metadata && !metadata.av) { // Old version of metadata, no package version, which is required for all composite metadata now metadata = undefined; diff --git a/lib/github/core.ts b/lib/github/core.ts index 2dbc8cd43..94acc778f 100644 --- a/lib/github/core.ts +++ b/lib/github/core.ts @@ -8,11 +8,11 @@ import { randomUUID } from 'crypto'; import moment from 'moment'; import { RestLibrary } from '.'; -import { AuthorizationHeaderValue } from '../../interfaces'; -import { sleep } from '../utils'; +import { IAuthorizationHeaderValue } from '../../interfaces'; +import { sleep } from '../../utils'; import cost from './cost'; -import { ErrorHelper } from '../transitional'; +import { ErrorHelper } from '../../transitional'; import Debug from 'debug'; const debug = Debug.debug('restapi'); @@ -43,7 +43,7 @@ const headerKeysWanted = [ 'x-ratelimit-used', ]; -export type GitHubRestInterestingHeaders = { +export interface IInterestingHeaders { etag?: string; ['last-modified']?: string; ['x-github-request-id']?: string; @@ -51,13 +51,9 @@ export type GitHubRestInterestingHeaders = { ['x-ratelimit-remaining']?: string; ['x-ratelimit-reset']?: string; ['x-ratelimit-used']?: string; -}; - -export type WithGitHubRestHeaders = T & { - headers?: GitHubRestInterestingHeaders; -}; +} -export type GitHubRestSpecializedCollectionHeaders = { +export interface ISpecializedCollectionHeaders { // really, these are the metadata fields, no headers at all... dirty?: boolean; pages?: string[]; @@ -67,34 +63,34 @@ export type GitHubRestSpecializedCollectionHeaders = { updated?: string; changed?: string; ['last-modified']?: string; -}; +} -export type RestMetadata = { +export interface IRestMetadata { etag?: string; av?: string; updated?: string; changed?: string; refreshing?: string; - headers?: GitHubRestSpecializedCollectionHeaders; // IDictionary; + headers?: ISpecializedCollectionHeaders; // IDictionary; status?: number; pages?: string[]; -}; +} -export type RestResponse = { - headers?: GitHubRestSpecializedCollectionHeaders; +export interface IRestResponse { + headers?: ISpecializedCollectionHeaders; status?: number; data: unknown; cost?: unknown; notModified?: boolean; -}; +} -export interface IIntelligentCacheResponseArray extends Array, RestResponse {} +export interface IIntelligentCacheResponseArray extends Array, IRestResponse {} -export type ShouldServeCache = { +export interface IShouldServeCache { cache?: boolean; remaining?: string; refresh?: boolean; -}; +} export abstract class ApiContext { private _log: string[]; @@ -103,7 +99,7 @@ export abstract class ApiContext { libraryContext: RestLibrary; etag?: string; - tokenSource: AuthorizationHeaderValue; + tokenSource: IAuthorizationHeaderValue; abstract get apiTypePrefix(): string; abstract get cacheValues(): IApiContextCacheValues; @@ -126,10 +122,7 @@ export abstract class ApiContext { return this._cost; } - constructor( - public api: any, - public options: any - ) { + constructor(public api: any, public options: any) { this._log = []; if (!this._calledTime) { this._calledTime = new Date(); @@ -142,7 +135,7 @@ export abstract class ApiContext { maxAgeSeconds?: number; backgroundRefresh?: boolean; - metadata?: RestMetadata; + metadata?: IRestMetadata; generatedRefreshId?: string; } @@ -171,23 +164,23 @@ export abstract class IntelligentEngine { } // was in api context: - abstract processMetadataBeforeCall(apiContext: ApiContext, metadata: RestMetadata): RestMetadata; - abstract callApi(apiContext: ApiContext, optionalMessage?: string): Promise; - abstract withResponseUpdateMetadata(apiContext: ApiContext, response: RestResponse): RestResponse; + abstract processMetadataBeforeCall(apiContext: ApiContext, metadata: IRestMetadata): IRestMetadata; + abstract callApi(apiContext: ApiContext, optionalMessage?: string): Promise; + abstract withResponseUpdateMetadata(apiContext: ApiContext, response: IRestResponse): IRestResponse; abstract withResponseShouldCacheBeServed( apiContext: ApiContext, - response: RestResponse - ): boolean | ShouldServeCache; + response: IRestResponse + ): boolean | IShouldServeCache; abstract withMetadataShouldCacheBeServed( apiContext: ApiContext, - metadata: RestMetadata - ): boolean | ShouldServeCache; - abstract reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: RestResponse): RestMetadata; - abstract getResponseMetadata(apiContext: ApiContext, response: RestResponse): RestMetadata; - abstract optionalStripResponse(apiContext: ApiContext, response: RestResponse): RestResponse; + metadata: IRestMetadata + ): boolean | IShouldServeCache; + abstract reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: IRestResponse): IRestMetadata; + abstract getResponseMetadata(apiContext: ApiContext, response: IRestResponse): IRestMetadata; + abstract optionalStripResponse(apiContext: ApiContext, response: IRestResponse): IRestResponse; - protected async cacheResponseAsync(apiContext: ApiContext, response: RestResponse) { + protected async cacheResponseAsync(apiContext: ApiContext, response: IRestResponse) { const backgroundAsyncWork = async () => { try { await this.storeResult(apiContext, response); @@ -204,7 +197,7 @@ export abstract class IntelligentEngine { return this.finalizeResult(apiContext, response); } - protected finalizeResult(apiContext: ApiContext, response: RestResponse): RestResponse { + protected finalizeResult(apiContext: ApiContext, response: IRestResponse): IRestResponse { if (!response || !response.data) { // This was a warning in the past, but to try and improve the underlying library, this should be an error if (response.headers.av) { @@ -225,9 +218,11 @@ export abstract class IntelligentEngine { return response; } - protected async tryGetCachedResult(apiContext: ApiContext): Promise { + protected async tryGetCachedResult(apiContext: ApiContext): Promise { const key = this.redisKeyBodyVersion(apiContext); - const response = (await apiContext.libraryContext.cacheProvider.getObjectCompressed(key)) as RestResponse; + const response = (await apiContext.libraryContext.cacheProvider.getObjectCompressed( + key + )) as IRestResponse; this.recordRedisCost(apiContext, 'get', response); return response; } @@ -235,8 +230,8 @@ export abstract class IntelligentEngine { protected async getCachedResult( apiContext: ApiContext, optionalCacheDecisions?, - notModifiedHeaders?: GitHubRestInterestingHeaders - ): Promise { + notModifiedHeaders?: IInterestingHeaders + ): Promise { const result = await this.tryGetCachedResult(apiContext); if (result && result.data) { // use the context metadata over any headers in the stored response, + any headers from 304 @@ -315,7 +310,7 @@ export abstract class IntelligentEngine { protected async reduceObjectExpirationWindow( apiContext: ApiContext, - response: RestResponse + response: IRestResponse ): Promise { if (!apiContext.etag || (apiContext.etag && apiContext.etag === response.headers.etag)) { return; @@ -350,7 +345,7 @@ export abstract class IntelligentEngine { this.recordRedisCost(apiContext, 'expire', cost); } - protected async storeMetadata(apiContext: ApiContext, response: RestResponse): Promise { + protected async storeMetadata(apiContext: ApiContext, response: IRestResponse): Promise { const reducedMetadata = this.reduceMetadataToCacheFromResponse(apiContext, response); const cost = await apiContext.libraryContext.cacheProvider.setObjectWithExpire( apiContext.redisKey.metadata, @@ -360,7 +355,7 @@ export abstract class IntelligentEngine { this.recordRedisCost(apiContext, 'set', cost); } - protected async storeResult(apiContext: ApiContext, response: RestResponse): Promise { + protected async storeResult(apiContext: ApiContext, response: IRestResponse): Promise { let key = null; try { key = this.redisKeyBodyVersion(apiContext, response.headers.etag); @@ -404,23 +399,23 @@ export abstract class IntelligentEngine { return object; } - public async execute(apiContext: ApiContext): Promise { + public async execute(apiContext: ApiContext): Promise { let metadata = await this.getCachedMetadata(apiContext); metadata = this.processMetadataBeforeCall(apiContext, metadata); - const shouldCacheBeServedImmediately: boolean | ShouldServeCache = this.withMetadataShouldCacheBeServed( + const shouldCacheBeServedImmediately: boolean | IShouldServeCache = this.withMetadataShouldCacheBeServed( apiContext, metadata ); const displayKey = apiContext.redisKey ? apiContext.redisKey.root + ' ' : ''; if ( shouldCacheBeServedImmediately === true || - (shouldCacheBeServedImmediately as ShouldServeCache).cache === true + (shouldCacheBeServedImmediately as IShouldServeCache).cache === true ) { debug('Cache should be served immediately.'); if (metadata) { const innerMessage = - shouldCacheBeServedImmediately && (shouldCacheBeServedImmediately as ShouldServeCache).remaining - ? (shouldCacheBeServedImmediately as ShouldServeCache).remaining + shouldCacheBeServedImmediately && (shouldCacheBeServedImmediately as IShouldServeCache).remaining + ? (shouldCacheBeServedImmediately as IShouldServeCache).remaining : ''; debug(`Cache ${displayKey}data: ${innerMessage}`); } @@ -434,9 +429,9 @@ export abstract class IntelligentEngine { await sleep(delayBeforeRefreshMilliseconds); } debug('Directly calling the function or REST API'); - let response: RestResponse = undefined; + let response: IRestResponse = undefined; try { - response = (await this.callApi(apiContext, `GET: ${displayKey}`)) as RestResponse; + response = (await this.callApi(apiContext, `GET: ${displayKey}`)) as IRestResponse; } catch (error) { if (error && error.status && error.status === 304) { const liveHeaders = error.response?.headers || {}; @@ -457,7 +452,7 @@ export abstract class IntelligentEngine { return response; } - private async processResponse(apiContext: ApiContext, response: RestResponse): Promise { + private async processResponse(apiContext: ApiContext, response: IRestResponse): Promise { this.withResponseUpdateMetadata(apiContext, response); const isCacheOk = this.withResponseShouldCacheBeServed(apiContext, response); if (isCacheOk === true) { @@ -479,7 +474,7 @@ export abstract class IntelligentEngine { } } - private async getCachedMetadata(apiContext: ApiContext): Promise { + private async getCachedMetadata(apiContext: ApiContext): Promise { if (apiContext.metadata || apiContext.etag) { debug('Shortcut: apiContext.metadata or apiContext.etag are set'); return; @@ -488,9 +483,9 @@ export abstract class IntelligentEngine { if (!redisKey) { throw new Error('No Redis key provided in apiContext.redisKey.metadata'); } - const cachedMetadata: RestMetadata = (await apiContext.libraryContext.cacheProvider.getObject( + const cachedMetadata: IRestMetadata = (await apiContext.libraryContext.cacheProvider.getObject( redisKey - )) as RestMetadata; + )) as IRestMetadata; // debug('Cached metadata retrieved'); this.recordRedisCost(apiContext, 'get', cachedMetadata); return cachedMetadata; diff --git a/lib/github/crossOrganization.ts b/lib/github/crossOrganization.ts index 4024d0d17..a1e72dde1 100644 --- a/lib/github/crossOrganization.ts +++ b/lib/github/crossOrganization.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { RestResponse, IIntelligentCacheResponseArray, flattenData } from './core'; +import { IRestResponse, IIntelligentCacheResponseArray, flattenData } from './core'; import { CompositeApiContext } from './composite'; import { RestLibrary } from '.'; import { RestCollections } from './collections'; @@ -11,16 +11,16 @@ import { ICacheOptions, IGetOrganizationMembersOptions, IPagedCrossOrganizationCacheOptions, - PurposefulGetAuthorizationHeader, + IPurposefulGetAuthorizationHeader, ITeamMembershipOptions, } from '../../interfaces'; -import { AppPurpose } from './appPurposes'; +import { AppPurpose } from '../../business/githubApps'; -interface IOrganizationsResponse extends RestResponse { +interface IOrganizationsResponse extends IRestResponse { orgs?: any; } -interface ICrossOrganizationDataResponse extends RestResponse { +interface ICrossOrganizationDataResponse extends IRestResponse { // data?: any; } @@ -42,7 +42,7 @@ export class CrossOrganizationCollator { } async orgMembers( - orgsAndTokens: Map, + orgsAndTokens: Map, options: IGetOrganizationMembersOptions, cacheOptions: ICacheOptions ): Promise { @@ -57,13 +57,13 @@ export class CrossOrganizationCollator { return flattenData(data); } - async teams(orgsAndTokens: Map, options, cacheOptions) { + async teams(orgsAndTokens: Map, options, cacheOptions) { const allTeams = await this.getAllTeams(orgsAndTokens, options, cacheOptions); return flattenData(allTeams); } async teamMembers( - orgsAndTokens: Map, + orgsAndTokens: Map, options: ITeamMembershipOptions, cacheOptions: ICacheOptions ): Promise { @@ -90,7 +90,7 @@ export class CrossOrganizationCollator { } async repos( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: ICacheOptions ): Promise { @@ -99,7 +99,7 @@ export class CrossOrganizationCollator { } async repoCollaborators( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: ICacheOptions ): Promise { @@ -126,7 +126,7 @@ export class CrossOrganizationCollator { } async repoTeams( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: ICacheOptions ): Promise { @@ -173,7 +173,7 @@ export class CrossOrganizationCollator { } private async getCrossOrganizationMethod( - orgsAndTokens: Map, + orgsAndTokens: Map, apiName: string, methodName: string, options, @@ -242,7 +242,7 @@ export class CrossOrganizationCollator { private crossOrganizationCollection( capturedThis: CrossOrganizationCollator, - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: IPagedCrossOrganizationCacheOptions, innerKeyType, @@ -303,7 +303,7 @@ export class CrossOrganizationCollator { const localOptions = Object.assign(localOptionsTarget, options); delete localOptions.maxAgeSeconds; delete localOptions.backgroundRefresh; - const token = orgsAndTokens.get(orgName.toLowerCase()) as PurposefulGetAuthorizationHeader; + const token = orgsAndTokens.get(orgName.toLowerCase()) as IPurposefulGetAuthorizationHeader; if (!token) { throw new Error(`No token available for the organization ${orgName}`); } @@ -348,7 +348,7 @@ export class CrossOrganizationCollator { } private async getAllTeams( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: IPagedCrossOrganizationCacheOptions ): Promise { @@ -364,7 +364,7 @@ export class CrossOrganizationCollator { } private async getAllRepos( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: IPagedCrossOrganizationCacheOptions ): Promise { diff --git a/lib/github/index.ts b/lib/github/index.ts index f9269ca6a..923b0fc81 100644 --- a/lib/github/index.ts +++ b/lib/github/index.ts @@ -13,26 +13,17 @@ import { CompositeIntelligentEngine } from './composite'; import { RestCollections } from './collections'; import { CrossOrganizationCollator } from './crossOrganization'; import { LinkMethods } from './links'; -import { GetAuthorizationHeader, AuthorizationHeaderValue } from '../../interfaces'; +import { IGetAuthorizationHeader, IAuthorizationHeaderValue } from '../../interfaces'; import { ICacheHelper } from '../caching'; -import { ICustomAppPurpose } from './appPurposes'; -import { CreateError } from '../transitional'; +import { ICustomAppPurpose } from '../../business/githubApps'; export enum CacheMode { ValidateCache = 'ValidateCache', BackgroundRefresh = 'BackgroundRefresh', } -export enum HttpMethod { - Get = 'GET', - Post = 'POST', - Put = 'PUT', - Patch = 'PATCH', - Delete = 'DELETE', -} - export interface IGitHubPostFunction { - (awaitToken: GetAuthorizationHeader, api: string, parameters: any): Promise; + (awaitToken: IGetAuthorizationHeader, api: string, parameters: any): Promise; } export type OctokitGraphqlOptions = { @@ -137,27 +128,25 @@ export class RestLibrary { hasNextPage?: (any) => boolean; private async resolveAuthorizationHeader( - authorizationHeader: GetAuthorizationHeader | AuthorizationHeaderValue | string - ): Promise { + authorizationHeader: IGetAuthorizationHeader | IAuthorizationHeaderValue | string + ): Promise { let authorizationValue = null; try { - if (!authorizationHeader) { - throw CreateError.InvalidParameters('No authorization header'); - } else if (typeof authorizationHeader === 'string') { + if (typeof authorizationHeader === 'string') { authorizationValue = authorizationHeader as string; } else if (typeof authorizationHeader === 'function') { - let asFunc = authorizationHeader as GetAuthorizationHeader; - let resolved = asFunc.call(null) as Promise; + let asFunc = authorizationHeader as IGetAuthorizationHeader; + let resolved = asFunc.call(null) as Promise; authorizationValue = await resolved; if (typeof resolved === 'function') { - asFunc = resolved as GetAuthorizationHeader; - resolved = asFunc.call(null) as Promise; + asFunc = resolved as IGetAuthorizationHeader; + resolved = asFunc.call(null) as Promise; authorizationValue = await resolved; } } else if (authorizationHeader && authorizationHeader['value']) { - authorizationValue = authorizationHeader as AuthorizationHeaderValue; + authorizationValue = authorizationHeader as IAuthorizationHeaderValue; } else { - throw CreateError.InvalidParameters('Unknown resolveAuthorizationHeader type'); + throw new Error('Invalid resolveAuthorizationHeader'); } } catch (getTokenError) { console.dir(getTokenError); @@ -167,7 +156,7 @@ export class RestLibrary { } async call( - awaitToken: GetAuthorizationHeader | AuthorizationHeaderValue | string, + awaitToken: IGetAuthorizationHeader | IAuthorizationHeaderValue | string, api: string, options, cacheOptions = null @@ -192,32 +181,20 @@ export class RestLibrary { return result; } - request(token: GetAuthorizationHeader | string, restEndpoint, parameters: any, cacheOptions): Promise { + request(token, restEndpoint, parameters: any, cacheOptions): Promise { parameters = parameters || {}; parameters['octokitRequest'] = restEndpoint; return this.call(token, 'request', parameters, cacheOptions); } - requestAsPost(token: GetAuthorizationHeader | string, restEndpoint, parameters: any): Promise { + requestAsPost(token, restEndpoint, parameters: any): Promise { parameters = parameters || {}; parameters['octokitRequest'] = restEndpoint; return this.post(token, 'request', parameters); } - restApi( - token: GetAuthorizationHeader | string, - httpMethod: HttpMethod, - restEndpoint: string, - parameters: any - ): Promise { - const requestUrlValue = `${httpMethod} ${restEndpoint}`; - return httpMethod === HttpMethod.Get - ? this.request(token, requestUrlValue, parameters, {}) - : this.requestAsPost(token, requestUrlValue, parameters); - } - graphql( - token: GetAuthorizationHeader | string, + token, query: string, parameters: any, graphqlOptions: OctokitGraphqlOptions = {} @@ -226,7 +203,7 @@ export class RestLibrary { } graphqlIteration( - token: GetAuthorizationHeader | string, + token, query: string, parameters: any, graphqlOptions: OctokitGraphqlOptions = {} @@ -251,7 +228,7 @@ export class RestLibrary { return this.post(token, api, parameters); } - async post(awaitToken: GetAuthorizationHeader | string, api: string, options: any): Promise { + async post(awaitToken: IGetAuthorizationHeader | string, api: string, options: any): Promise { const method = restApi.IntelligentGitHubEngine.findLibraryMethod(this.github, api); if (!options.headers) { options.headers = {}; @@ -262,14 +239,14 @@ export class RestLibrary { delete options.allowEmptyResponse; massageData = noDataMassage; } - let diagnosticHeaderInformation: AuthorizationHeaderValue = null; + let diagnosticHeaderInformation: IAuthorizationHeaderValue = null; if (!options.headers.authorization) { const value = await this.resolveAuthorizationHeader(awaitToken); - if ((value as AuthorizationHeaderValue)?.purpose) { - diagnosticHeaderInformation = value as AuthorizationHeaderValue; + if ((value as IAuthorizationHeaderValue)?.purpose) { + diagnosticHeaderInformation = value as IAuthorizationHeaderValue; } options.headers.authorization = - typeof value === 'string' ? (value as string) : (value as AuthorizationHeaderValue).value; + typeof value === 'string' ? (value as string) : (value as IAuthorizationHeaderValue).value; } const diagnostic: Record = {}; try { @@ -306,15 +283,8 @@ export class RestLibrary { return finalized; } catch (error) { console.log(`API ${api} POST error: ${error.message}`); - if (error?.message?.includes('Unexpected end of JSON input')) { - console.log('Usually a unicorn and bad GitHub 500'); - console.dir(error); - } - if ( - error?.message?.includes('Resource not accessible by integration') || - error?.message?.includes('Not Found') - ) { - console.error('\tOptions:'); + if (error?.message?.includes('Resource not accessible by integration')) { + console.error('Options:'); { const options = Object.getOwnPropertyNames(diagnostic.options).length > 0 ? diagnostic.options : null; @@ -327,17 +297,17 @@ export class RestLibrary { if (key === 'headers') { const headers = value as Record; const headersKeys = Object.getOwnPropertyNames(headers); - console.log('\t\tHeaders:'); + console.log('Headers:'); for (let j = 0; j < headersKeys.length; j++) { const headerKey = headersKeys[j]; const headerValue = headerKey.toLocaleLowerCase() === 'authorization' ? headers[headerKey].substring(0, 13) + '***' : headers[headerKey]; - console.log(`\t\t - ${headerKey}: ${headerValue}`); + console.log(` - ${headerKey}: ${headerValue}`); } } else { - console.log(`\t\tOption: ${key}: ${value}`); + console.log(`Option: ${key}: ${value}`); } } } @@ -346,39 +316,38 @@ export class RestLibrary { for (let i = 0; i < remainingKeys.length; i++) { const key = remainingKeys[i]; const value = diagnostic[key]; - console.log(`\t\t${key}: ${value}`); + console.log(`${key}: ${value}`); } } } if (diagnosticHeaderInformation) { - console.error('\tAuthorization selection information:'); + console.error('Authorization selection information:'); const { installationId, organizationName, purpose, source } = diagnosticHeaderInformation; - organizationName && console.error(`\t\tHeader resolved for organization: ${organizationName}`); + organizationName && console.error(`Header resolved for organization: ${organizationName}`); const customPurpose = purpose as ICustomAppPurpose; purpose && customPurpose?.isCustomAppPurpose === true && - console.error(`\t\tCustom purpose: ${customPurpose.id}`); - purpose && !customPurpose?.isCustomAppPurpose && console.error(`\t\tPurpose: ${purpose}`); - installationId && console.error(`\t\tInstallation ID: ${installationId}`); - source && console.error(`\t\tSource: ${source}`); + console.error(`Custom purpose: ${customPurpose.id}`); + purpose && !customPurpose?.isCustomAppPurpose && console.error(`Purpose: ${purpose}`); + installationId && console.error(`Installation ID: ${installationId}`); + source && console.error(`Source: ${source}`); } } if (error.status) { - console.log(`\tStatus: ${error.status}`); + console.log(`Status: ${error.status}`); } if (error?.response?.headers && error?.response?.headers['x-github-request-id']) { - console.log(`\tRequest ID: ${error.response.headers['x-github-request-id']}`); + console.log(`Request ID: ${error.response.headers['x-github-request-id']}`); } if (error?.response?.headers && error?.response?.headers['x-ratelimit-remaining']) { - console.log(`\tRate limit remaining: ${error.response.headers['x-ratelimit-remaining']}`); + console.log(`Rate limit remaining: ${error.response.headers['x-ratelimit-remaining']}`); } if (error?.response?.headers && error?.response?.headers['x-ratelimit-used']) { - console.log(`\tRate limit used: ${error.response.headers['x-ratelimit-used']}`); + console.log(`Rate limit used: ${error.response.headers['x-ratelimit-used']}`); } if (shouldErrorShowRequest && error?.request) { console.dir(error.request); } - console.log(); throw error; } } diff --git a/lib/github/restApi.ts b/lib/github/restApi.ts index 0c1e3f2e7..7687f2bed 100644 --- a/lib/github/restApi.ts +++ b/lib/github/restApi.ts @@ -14,26 +14,19 @@ const debugShowStandardBehavior = false; const debugOutputUnregisteredEntityApis = true; import { - ShouldServeCache, + IShouldServeCache, IntelligentEngine, ApiContext, IApiContextCacheValues, IApiContextRedisKeys, ApiContextType, - RestResponse, - RestMetadata, + IRestResponse, + IRestMetadata, } from './core'; import { getEntityDefinitions, GitHubResponseType, ResponseBodyType } from './endpointEntities'; import appPackage from '../../package.json'; -import { ErrorHelper } from '../transitional'; - -import type { GetAuthorizationHeader, AuthorizationHeaderValue } from '../../interfaces'; -import { - type IGitHubAppConfiguration, - getAppPurposeId, - tryGetAppPurposeAppConfiguration, -} from './appPurposes'; +import { IGetAuthorizationHeader, IAuthorizationHeaderValue } from '../../interfaces'; const appVersion = appPackage.version; @@ -77,7 +70,7 @@ export class IntelligentGitHubEngine extends IntelligentEngine { return method; } - async callApi(apiContext: GitHubApiContext, optionalMessage?: string): Promise { + async callApi(apiContext: GitHubApiContext, optionalMessage?: string): Promise { const token = apiContext.token; // CONSIDER: rename apiContext.token *to* something like apiContext.authorization if ( @@ -108,11 +101,10 @@ export class IntelligentGitHubEngine extends IntelligentEngine { } } } - const purpose = apiContext?.tokenSource?.purpose ? getAppPurposeId(apiContext.tokenSource.purpose) : null; if (optionalMessage) { let apiTypeSuffix = apiContext.tokenSource && apiContext.tokenSource.purpose - ? ' [' + (purpose || apiContext.tokenSource.purpose) + ']' + ? ' [' + apiContext.tokenSource.purpose + ']' : ''; if (!apiTypeSuffix && apiContext.tokenSource && apiContext.tokenSource.source) { apiTypeSuffix = ` [token source=${apiContext.tokenSource.source}]`; @@ -147,41 +139,11 @@ export class IntelligentGitHubEngine extends IntelligentEngine { args.push(argOptions); } const thisArgument = apiMethod.thisInstance || null; - try { - const response = await apiMethod.apply(thisArgument, args); - return response; - } catch (error) { - const asAny = error as any; - if ( - ErrorHelper.IsNotAuthorized(error) && - asAny?.message === 'Resource not accessible by integration' && - apiContext.tokenSource - ) { - let appConfig: IGitHubAppConfiguration = null; - if (apiContext?.tokenSource?.purpose && apiContext?.tokenSource?.organizationName) { - appConfig = tryGetAppPurposeAppConfiguration( - apiContext.tokenSource.purpose, - apiContext.tokenSource.organizationName - ); - } - asAny.source = apiContext.tokenSource.source; - const additional: string[] = []; - purpose && additional.push(`purpose=${purpose}`); - appConfig?.appId && additional.push(`appId=${appConfig.appId}`); - appConfig?.slug && additional.push(`slug=${appConfig.slug}`); - apiContext?.tokenSource?.installationId && - additional.push(`installationId=${apiContext.tokenSource.installationId}`); - apiContext?.tokenSource?.organizationName && - additional.push(`organization=${apiContext.tokenSource.organizationName}`); - const extra = ' ' + additional.join(', '); - debug(`Additional installation context added to message for 403: ${extra}`); - asAny.message += extra; - } - throw error; - } + const response = await apiMethod.apply(thisArgument, args); + return response; } - processMetadataBeforeCall(apiContext: ApiContext, metadata: RestMetadata) { + processMetadataBeforeCall(apiContext: ApiContext, metadata: IRestMetadata) { if ( metadata && metadata.av && @@ -203,11 +165,11 @@ export class IntelligentGitHubEngine extends IntelligentEngine { return metadata; } - withResponseUpdateMetadata(apiContext: ApiContext, response: RestResponse) { + withResponseUpdateMetadata(apiContext: ApiContext, response: IRestResponse) { return response; } - optionalStripResponse(apiContext: ApiContext, response: RestResponse): RestResponse { + optionalStripResponse(apiContext: ApiContext, response: IRestResponse): IRestResponse { const clonedResponse = Object.assign({}, response); if (response.headers) { const clonedHeaders = StripGitHubEntity( @@ -295,7 +257,7 @@ export class IntelligentGitHubEngine extends IntelligentEngine { return clonedResponse; } - reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: RestResponse): any { + reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: IRestResponse): any { const headers = response ? response.headers : null; if (headers?.etag) { const reduced: IReducedGitHubMetadata = { @@ -320,8 +282,8 @@ export class IntelligentGitHubEngine extends IntelligentEngine { withResponseShouldCacheBeServed( apiContext: ApiContext, - response: RestResponse - ): boolean | ShouldServeCache { + response: IRestResponse + ): boolean | IShouldServeCache { if (response === undefined) { throw new Error('The response was undefined and unable to process.'); } @@ -358,8 +320,8 @@ export class IntelligentGitHubEngine extends IntelligentEngine { return cacheOk; } - getResponseMetadata(apiContext: ApiContext, response: RestResponse): RestMetadata { - const md: RestMetadata = { + getResponseMetadata(apiContext: ApiContext, response: IRestResponse): IRestMetadata { + const md: IRestMetadata = { headers: response.headers, status: response.status, }; @@ -368,12 +330,12 @@ export class IntelligentGitHubEngine extends IntelligentEngine { withMetadataShouldCacheBeServed( apiContext: ApiContext, - metadata: RestMetadata - ): boolean | ShouldServeCache { + metadata: IRestMetadata + ): boolean | IShouldServeCache { // result can be falsy OR an object; { cache: true, refresh: true } // cache: whether to use the cache, if available // refresh: whether to refresh in the background for a newer value - let shouldServeCache: ShouldServeCache | boolean = false; + let shouldServeCache: IShouldServeCache | boolean = false; const maxAgeSeconds = apiContext.maxAgeSeconds; const updatedIso = metadata ? metadata.updated : null; const refreshingIso = metadata ? metadata.refreshing : null; @@ -446,7 +408,7 @@ export class GitHubApiContext extends ApiContext { private _apiMethod: any; private _redisKeys: IApiContextRedisKeys; private _cacheValues: IApiContextCacheValues; - private _token: string | GetAuthorizationHeader | AuthorizationHeaderValue; + private _token: string | IGetAuthorizationHeader | IAuthorizationHeaderValue; public fakeLink?: IGitHubLink; @@ -472,7 +434,7 @@ export class GitHubApiContext extends ApiContext { }; } - get token(): string | GetAuthorizationHeader | AuthorizationHeaderValue { + get token(): string | IGetAuthorizationHeader | IAuthorizationHeaderValue { return this._token; } @@ -511,9 +473,9 @@ export class GitHubApiContext extends ApiContext { this.libraryContext = libraryContext; } - overrideToken(token: string | GetAuthorizationHeader | AuthorizationHeaderValue) { + overrideToken(token: string | IGetAuthorizationHeader | IAuthorizationHeaderValue) { if (token && token['value']) { - const asPair = token as AuthorizationHeaderValue; + const asPair = token as IAuthorizationHeaderValue; this._token = asPair.value; this.tokenSource = asPair; } else if (typeof token === 'string') { diff --git a/lib/graphProvider/microsoftGraphProvider.ts b/lib/graphProvider/microsoftGraphProvider.ts index 0d5922e91..8cdb4f5e0 100644 --- a/lib/graphProvider/microsoftGraphProvider.ts +++ b/lib/graphProvider/microsoftGraphProvider.ts @@ -8,7 +8,6 @@ import cache from 'memory-cache'; import axios, { AxiosError } from 'axios'; import querystring from 'querystring'; -import validator from 'validator'; import { IGraphProvider, @@ -18,7 +17,7 @@ import { IGraphGroup, GraphUserType, } from '.'; -import { ErrorHelper, CreateError, splitSemiColonCommas } from '../transitional'; +import { ErrorHelper, CreateError, splitSemiColonCommas } from '../../transitional'; import { ICacheHelper } from '../caching'; const axios12BufferDecompressionBugHeaderAddition = true; @@ -33,68 +32,20 @@ export interface IMicrosoftGraphProviderOptions { skipManagerLookupForIds?: string; } -export type MicrosoftGraphGroupMembersOptions = { - getCount?: boolean; - maximumPages?: number; - throwOnMaximumPages?: boolean; - skipCache?: boolean; - additionalSelectValues?: string[]; - membership?: MicrosoftGraphGroupMembershipType; -}; - -export enum MicrosoftGraphGroupMembershipType { - Transitive = 'transitiveMembers', - Direct = 'members', -} - -export type MicrosoftGraphGroupMember = IGraphGroupMember & { - userType?: GraphUserType; -}; - -export function microsoftGraphUserTypeFromString(type: string): GraphUserType { - if (!type) { - return; - } - switch (type) { - case GraphUserType.Guest: - return GraphUserType.Guest; - case GraphUserType.Member: - return GraphUserType.Member; - default: - return GraphUserType.Unknown; - } -} - -type GraphCheckMembersRequest = { - ids: string[]; -}; - -type GraphCheckMembersResponse = { - value: string[]; -}; - const graphBaseUrl = 'https://graph.microsoft.com/v1.0/'; const odataNextLink = '@odata.nextLink'; -const defaultCachePeriodMinutes = 60 * 36; // 36 hours +const defaultCachePeriodMinutes = 60; const attemptCacheGet = true; -type MicrosoftGraphCallOptions = { +interface IGraphOptions { selectValues?: string; filterValues?: string; orderBy?: string; body?: any; count?: boolean; consistencyLevel?: 'eventual'; -}; - -type GraphCacheOptions = { - skipCache?: boolean; - maximumPages?: number; - throwOnMaximumPages?: boolean; -}; - -type GraphOptions = MicrosoftGraphCallOptions & GraphCacheOptions; +} export class MicrosoftGraphProvider implements IGraphProvider { #_tokenCacheMilliseconds: number; @@ -129,26 +80,9 @@ export class MicrosoftGraphProvider implements IGraphProvider { } async isUserInGroup(corporateId: string, securityGroupId: string): Promise { - // Formerly used a very inefficient approach: - // const members = await this.getGroupMembers(securityGroupId); - // return members.filter((m) => m.id === corporateId).length > 0; - return await this.checkMemberObjectsForUserId(corporateId, securityGroupId); - } - - private async checkMemberObjectsForUserId(corporateId: string, securityGroupId: string): Promise { - const requestBody: GraphCheckMembersRequest = { - ids: [securityGroupId], - }; - const url = `${graphBaseUrl}users/${corporateId}/checkMemberObjects`; - const response = await this.request( - url, - requestBody, - null, - true - ); /* no cache */ - const foundGroupIds = response.value; - const found = foundGroupIds.includes(securityGroupId); - return found; + // TODO: refactor for efficient use of Microsoft Graph's checkMemberObjects https://docs.microsoft.com/en-us/graph/api/group-checkmemberobjects?view=graph-rest-1.0&tabs=http + const members = await this.getGroupMembers(securityGroupId); + return members.filter((m) => m.id === corporateId).length > 0; } private async getTokenThenEntity(aadId: string, resource: string): Promise { @@ -228,18 +162,12 @@ export class MicrosoftGraphProvider implements IGraphProvider { } async getGroup(corporateGroupId: string): Promise { - const selectValues = 'description,displayName,id,mail,mailNickname'; - // if (additionalSelectValues) { - // selectValues = Array.from( - // new Set([...selectValues.split(','), ...additionalSelectValues]).values() - // ).join(','); - // } // prettier-ignore const response = await this.lookupInGraph([ 'groups', corporateGroupId, ], { - selectValues, + selectValues: 'description,displayName,id,mail,mailNickname', }); return response; } @@ -306,8 +234,8 @@ export class MicrosoftGraphProvider implements IGraphProvider { ], { filterValues: `mail eq '${mail}'`, // encodeURIComponent( selectValues: 'id', - // count: true, - // consistencyLevel: 'eventual', + count: true, + consistencyLevel: 'eventual', })) as any[]; if (!response || response.length === 0) { return null; @@ -429,50 +357,26 @@ export class MicrosoftGraphProvider implements IGraphProvider { }); } - async getGroupMembers( - corporateGroupId: string, - options?: MicrosoftGraphGroupMembersOptions - ): Promise { - const defaultSelectSet = ['id', 'userPrincipalName']; - const selectValuesSet = new Set([ - ...defaultSelectSet, - ...(options?.additionalSelectValues || []), - ]); - const graphOptions: GraphOptions = { - selectValues: Array.from(selectValuesSet.values()).join(','), - }; - if (options?.getCount !== undefined) { - graphOptions.count = true; - graphOptions.consistencyLevel = 'eventual'; - } - if (options?.maximumPages !== undefined) { - graphOptions.maximumPages = options.maximumPages; - } - if (options?.throwOnMaximumPages !== undefined) { - graphOptions.throwOnMaximumPages = options.throwOnMaximumPages; - } - const lookupType = options?.membership || MicrosoftGraphGroupMembershipType.Transitive; - const includesUserType = selectValuesSet.has('userType'); + async getGroupMembers(corporateGroupId: string): Promise { const response = (await this.lookupInGraph( - ['groups', corporateGroupId, lookupType], - graphOptions + [ + 'groups', + corporateGroupId, + 'transitiveMembers', // transitiveMembers or members + ], + { + selectValues: 'id,userPrincipalName', + } )) as any[]; + // may be a caching bug: if (Array.isArray(response)) { return response.map((entry) => { - return { - id: entry.id, - userPrincipalName: entry.userPrincipalName, - userType: includesUserType ? microsoftGraphUserTypeFromString(entry.userType) : undefined, - }; + return { id: entry.id, userPrincipalName: entry.userPrincipalName }; }); } const subResponse = (response as any).value ? (response as any).value : []; return subResponse.map((entry) => { - return { - id: entry.id, - userPrincipalName: entry.userPrincipalName, - userType: includesUserType ? microsoftGraphUserTypeFromString(entry.userType) : undefined, - }; + return { id: entry.id, userPrincipalName: entry.userPrincipalName }; }); } @@ -480,18 +384,12 @@ export class MicrosoftGraphProvider implements IGraphProvider { if (!minimum3Characters || minimum3Characters.length < 3) { throw new Error(`Minimum 3 characters required: ${minimum3Characters}`); } - - let filterValues = `securityEnabled eq true and (startswith(displayName, '${minimum3Characters}') or startswith(mailNickname, '${minimum3Characters}'))`; - if (validator.isUUID(minimum3Characters)) { - filterValues = `securityEnabled eq true and (id eq '${minimum3Characters}' or startswith(displayName, '${minimum3Characters}') or startswith(mailNickname, '${minimum3Characters}'))`; - } - // NOTE: this is currently explicitly looking for Security Groups only // prettier-ignore let response = (await this.lookupInGraph([ 'groups', ], { - filterValues, + filterValues: `securityEnabled eq true and (startswith(displayName, '${minimum3Characters}') or startswith(mailNickname, '${minimum3Characters}'))`, selectValues: 'id,displayName,mailNickname', })) as any[]; if (!response.filter && (response as any).value?.filter) { @@ -590,9 +488,8 @@ export class MicrosoftGraphProvider implements IGraphProvider { } } - private async lookupInGraph(entityPath: string[], options: GraphOptions): Promise { + private async lookupInGraph(entityPath: string[], options: IGraphOptions): Promise { // initial hacking on top of the API - const skipCache = options?.skipCache === true; const subUrl = entityPath.map((item) => encodeURIComponent(item)).join('/'); const queries = {}; if (options.filterValues) { @@ -604,15 +501,12 @@ export class MicrosoftGraphProvider implements IGraphProvider { if (options.orderBy) { queries['$orderby'] = options.orderBy; } - if (options.count === true) { - queries['$count'] = 'true'; - } let hasArray = false; let value = null; let url = `${graphBaseUrl}${subUrl}?${querystring.stringify(queries)}`; const originalUrl = url; try { - if (this.#_cache && attemptCacheGet && !skipCache) { + if (this.#_cache && attemptCacheGet) { value = await this.#_cache.getObject(url); if (value?.cache) { if (Array.isArray(value.cache) && value.cache.length === 0) { @@ -628,10 +522,9 @@ export class MicrosoftGraphProvider implements IGraphProvider { console.warn(error); } let pages = 0; - const maximumPages = options?.maximumPages; do { const consistencyLevel = options.consistencyLevel; - const body = await this.request(url, options.body, consistencyLevel, skipCache); + const body = await this.request(url, options.body, consistencyLevel); if (body.value && pages === 0) { hasArray = body && body.value && Array.isArray(body.value); if (hasArray) { @@ -646,25 +539,14 @@ export class MicrosoftGraphProvider implements IGraphProvider { } else { throw new Error(`Page ${pages} in response is not an array type but had a link: ${url}`); } - if (body && body['@odata.count'] !== undefined) { - const count = body['@odata.count']; - // NOTE: we don't store or cache or return this today - console.log(`Total objects in response: ${count}`); - } ++pages; url = body && body[odataNextLink] ? body[odataNextLink] : null; - } while (url && (maximumPages ? pages < maximumPages : true)); - if (pages >= maximumPages) { - if (options.throwOnMaximumPages) { - throw CreateError.InvalidParameters('Maximum pages exceeded for this resource'); - } - console.warn(`WARN: Maximum pages exceeded for this resource: ${originalUrl}`); - } + } while (url); if (this.#_cache) { try { this.#_cache .setObjectWithExpire(originalUrl, { cache: value }, defaultCachePeriodMinutes) - .then(() => {}) + .then((ok) => {}) .catch((err) => { console.warn(err); }); @@ -675,15 +557,10 @@ export class MicrosoftGraphProvider implements IGraphProvider { return value; } - private async request( - url: string, - body?: any, - eventualConsistency?: string, - skipCache?: boolean - ): Promise { + private async request(url: string, body?: any, eventualConsistency?: string): Promise { const token = await this.getToken(); const method = body ? 'post' : 'get'; - if (this.#_cache && attemptCacheGet && method === 'get' && !skipCache) { + if (this.#_cache && attemptCacheGet && method === 'get') { try { const value = await this.#_cache.getObject(url); if (value?.cache) { @@ -707,7 +584,7 @@ export class MicrosoftGraphProvider implements IGraphProvider { } if (eventualConsistency) { - headers['ConsistencyLevel'] = eventualConsistency; + // headers.ConsistencyLevel = eventualConsistency; } const response = await axios({ url, @@ -719,12 +596,13 @@ export class MicrosoftGraphProvider implements IGraphProvider { throw CreateError.ServerError('Empty response'); } if ((response.data as any).error?.message) { - throw CreateError.InvalidParameters((response.data as any).error.message); + // axios returns unknown now + throw CreateError.InvalidParameters((response.data as any).error.message); // axios returns unknown now } if (this.#_cache && method === 'get') { this.#_cache .setObjectWithExpire(url, { cache: response.data }, defaultCachePeriodMinutes) - .then(() => {}) + .then((ok) => {}) .catch((err) => {}); } return response.data; diff --git a/lib/linkProviders/table/tableLinkProvider.ts b/lib/linkProviders/table/tableLinkProvider.ts index 282a034c4..6e4d1c6dc 100644 --- a/lib/linkProviders/table/tableLinkProvider.ts +++ b/lib/linkProviders/table/tableLinkProvider.ts @@ -28,7 +28,7 @@ import { CorporateTableLink } from './tableLink'; import { ILinkProvider } from '..'; import tableEntity from '../../tableEntity'; -import { ErrorHelper } from '../../transitional'; +import { ErrorHelper } from '../../../transitional'; import { decryptEntityAsync, encryptEntityAsync, IEncryptionOptions } from '../../encryption'; import { IKeyVaultSecretResolver } from '../../keyVaultResolver'; diff --git a/lib/mailProvider/index.ts b/lib/mailProvider/index.ts index 6ddac4228..a334f0340 100644 --- a/lib/mailProvider/index.ts +++ b/lib/mailProvider/index.ts @@ -3,9 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { promises as fs } from 'fs'; -import { randomUUID } from 'crypto'; - import MockMailService from './mockMailService'; import SmtpMailService from './smtpMailService'; import AzureServiceBus from './azureServiceBus'; @@ -23,46 +20,6 @@ export interface IMail { correlationId?: string; senderProfile?: string; replyTo?: string; - attachments?: MailAttachment[]; - linkedResources?: MailAttachment[]; -} - -export type MailAttachment = { - name: string; - contentId: string; - contentType: string; - base64Value: string; -}; - -export async function createMailAttachment( - localPath: string, - name: string, - contentType: string, - contentId?: string -): Promise { - const realContentId = contentId || randomUUID(); - const content = await fs.readFile(localPath, 'base64'); - return { - name, - contentId: realContentId, - contentType, - base64Value: content, - }; -} - -export function createMailAttachmentFromBase64( - base64contents: string, - name: string, - contentType: string, - contentId?: string -): MailAttachment { - const realContentId = contentId || randomUUID(); - return { - name, - contentId: realContentId, - contentType, - base64Value: base64contents, - }; } export interface IMailProvider { diff --git a/lib/pugViewServices.ts b/lib/pugViewServices.ts index cf91bb7c9..2fcd7a98b 100644 --- a/lib/pugViewServices.ts +++ b/lib/pugViewServices.ts @@ -5,7 +5,7 @@ import _ from 'lodash'; import moment from 'moment'; -import octicons from '@primer/octicons'; +import octicons from 'octicons'; //const octicons = require('octicons'); import fileSize from 'file-size'; import languageMap from 'language-map'; import validator from 'validator'; diff --git a/middleware/alternateApps.ts b/middleware/alternateApps.ts index 76e783e49..9f6ec74ae 100644 --- a/middleware/alternateApps.ts +++ b/middleware/alternateApps.ts @@ -8,13 +8,13 @@ const debug = Debug.debug('startup'); import path from 'path'; -import type { ApplicationProfile, IReposApplication, SiteConfiguration } from '../interfaces'; +import { IApplicationProfile, IReposApplication } from '../interfaces'; export default async function initializeAlternateApps( - config: SiteConfiguration, + config, app: IReposApplication, appName: string -): Promise { +): Promise { const appPath = path.resolve(path.join(__dirname, '..', appName, '/')); debug(`Alternate app requested: name=${appName}, path=${appPath}`); try { diff --git a/middleware/apiAad.ts b/middleware/apiAad.ts index 6968e4e49..a44c24dc1 100644 --- a/middleware/apiAad.ts +++ b/middleware/apiAad.ts @@ -3,30 +3,28 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; import jwt from 'jsonwebtoken'; import jwksClient from 'jwks-rsa'; import { isJsonError, jsonError } from './jsonError'; import { IApiRequest, wrapErrorForImmediateUserError } from './apiReposAuth'; -import { PersonalAccessToken } from '../business/entities/token/token'; -import { CreateError, getProviders } from '../lib/transitional'; +import { PersonalAccessToken } from '../entities/token/token'; +import { CreateError, getProviders } from '../transitional'; import getCompanySpecificDeployment from './companySpecificDeployment'; // CONSIDER: Caching of signing keys -export function requireAadApiAuthorizedScope(scope: string | string[]) { - return (req: IApiRequest, res: Response, next: NextFunction) => { +export function requireAadApiAuthorizedScope(scope: string) { + return (req: IApiRequest, res, next) => { const { apiKeyToken } = req; - const scopes = typeof scope === 'string' ? [scope] : scope; - if (!apiKeyToken.hasAnyScope(scopes)) { + if (!apiKeyToken.hasScope(scope)) { return next(jsonError(`Not authorized for ${scope}`, 403)); } return next(); }; } -export default function aadApiMiddleware(req: IApiRequest, res: Response, next: NextFunction) { +export default function aadApiMiddleware(req: IApiRequest, res, next) { return validateAadAuthorization(req) .then((ok) => { return next(); @@ -35,7 +33,7 @@ export default function aadApiMiddleware(req: IApiRequest, res: Response, next: if ((err as any).immediate === true) { console.warn(`AAD API authorization failed: ${err}`); } - return isJsonError(err, req.url) ? next(err) : (jsonError(err, 500) as unknown); + return isJsonError(err) ? next(err) : jsonError(err, 500); }); } @@ -123,37 +121,20 @@ async function validateAadAuthorization(req: IApiRequest): Promise { } const { appid, oid } = payload as any; - const monikerSources = []; - const approvedAppMonikerClientId = await aadApiValidator.getAuthorizedClientIdToken(appid); - if (approvedAppMonikerClientId) { - monikerSources.push('client'); - } - const approvedAppMonikerObjectId = await aadApiValidator.getAuthorizedObjectIdToken(oid); - if (approvedAppMonikerObjectId) { - monikerSources.push('object'); + let approvedAppMonikerId = await aadApiValidator.getAuthorizedClientIdToken(appid); + if (!approvedAppMonikerId) { + approvedAppMonikerId = await aadApiValidator.getAuthorizedObjectIdToken(oid); } - const notAuthorized = !approvedAppMonikerClientId && !approvedAppMonikerObjectId; + const notAuthorized = !approvedAppMonikerId; if (notAuthorized) { throw wrapErrorForImmediateUserError( jsonError(`App ${appid} and object ID ${oid} is not authorized for this API endpoint`, 403) ); } - const scopesSet = new Set(); - if (approvedAppMonikerClientId) { - const clientIdScopes = await aadApiValidator.getScopes(approvedAppMonikerClientId); - clientIdScopes.forEach((s) => scopesSet.add(s)); - } - if (approvedAppMonikerObjectId) { - const objectIdScopes = await aadApiValidator.getScopes(approvedAppMonikerObjectId); - objectIdScopes.forEach((s) => scopesSet.add(s)); - } - const scopes = Array.from(scopesSet); - - const displayValues = await aadApiValidator.getDisplayValues( - approvedAppMonikerClientId || approvedAppMonikerObjectId - ); + const scopes = await aadApiValidator.getScopes(approvedAppMonikerId); + const displayValues = await aadApiValidator.getDisplayValues(approvedAppMonikerId); const apiToken = PersonalAccessToken.CreateFromAadAuthorization( { @@ -170,7 +151,6 @@ async function validateAadAuthorization(req: IApiRequest): Promise { name: 'ApiAadAppAuthorized', properties: Object.assign({}, decodedToken as any, { authorizedScopes: scopes.join(','), - monikerSources: monikerSources.join(','), }), }); } catch (error) { diff --git a/middleware/apiReposAuth.ts b/middleware/apiReposAuth.ts index ff26109de..f6c17f786 100644 --- a/middleware/apiReposAuth.ts +++ b/middleware/apiReposAuth.ts @@ -11,11 +11,10 @@ import basicAuth from 'basic-auth'; import crypto from 'crypto'; -import { NextFunction, Response } from 'express'; import { jsonError } from './jsonError'; -import { getProviders } from '../lib/transitional'; -import { PersonalAccessToken } from '../business/entities/token/token'; +import { getProviders } from '../transitional'; +import { PersonalAccessToken } from '../entities/token/token'; import { ReposAppRequest } from '../interfaces'; export const wrapErrorForImmediateUserError = (err: Error) => { @@ -31,7 +30,7 @@ export interface IApiRequest extends ReposAppRequest { userContextOverwriteRequest?: any; // refactor? } -export default function ReposApiAuthentication(req: IApiRequest, res: Response, next: NextFunction) { +export default function ReposApiAuthentication(req: IApiRequest, res, next) { const user = basicAuth(req); const key = user ? user.pass || user.name : null; if (!key) { diff --git a/middleware/apiVstsAuth.ts b/middleware/apiVstsAuth.ts index d34b6f67d..694e2af72 100644 --- a/middleware/apiVstsAuth.ts +++ b/middleware/apiVstsAuth.ts @@ -5,17 +5,16 @@ import axios from 'axios'; import asyncHandler from 'express-async-handler'; -import { NextFunction, Response } from 'express'; import { jsonError } from './jsonError'; import { IApiRequest } from './apiReposAuth'; -import { PersonalAccessToken } from '../business/entities/token/token'; -import { getProviders } from '../lib/transitional'; +import { PersonalAccessToken } from '../entities/token/token'; +import { getProviders } from '../transitional'; // TODO: consider better caching const localMemoryCacheVstsToAadId = new Map(); -const vstsAuth = asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { +const vstsAuth = asyncHandler(async (req: IApiRequest, res, next) => { const config = getProviders(req).config; if (!config) { return next(new Error('Missing configuration for the application')); diff --git a/middleware/appInsights.ts b/middleware/appInsights.ts index f3c4051c0..11c01d0e8 100644 --- a/middleware/appInsights.ts +++ b/middleware/appInsights.ts @@ -3,21 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import wrapOrCreateInsightsConsoleClient from '../lib/insights'; import Debug from 'debug'; const debug = Debug.debug('startup'); import { setup as appInsightsSetup, defaultClient } from 'applicationinsights'; -import type { - IReposApplication, - IProviders, - ReposAppRequest, - SiteConfiguration, - ExecutionEnvironment, -} from '../interfaces'; +import { IReposApplication, IProviders, ReposAppRequest } from '../interfaces'; function ignoreKubernetesProbes(envelope /* , context */) { if ('RequestData' === envelope.data.baseType) { @@ -50,22 +42,20 @@ function filterTelemetry(envelope, context): boolean { return true; } -export default function initializeAppInsights( - providers: IProviders, - executionEnvironment: ExecutionEnvironment, - app: IReposApplication, - config: SiteConfiguration -) { +export default function initializeAppInsights(app: IReposApplication, config) { let client = undefined; if (!config) { // Configuration failure happened ahead of this module return; } + const providers = app.settings.providers as IProviders; let cs: string = config?.telemetry?.applicationInsightsConnectionString || config?.telemetry?.applicationInsightsKey; // Override the key with a job-specific one if this is a job execution instead - const jobCs: string = config?.telemetry?.jobsApplicationInsightsConnectionString; - if (jobCs && executionEnvironment.isJob === true) { + const jobCs: string = + config?.telemetry?.jobsApplicationInsightsConnectionString || + config?.telemetry?.jobsApplicationInsightsKey; + if (jobCs && config.isJobInternal === true) { cs = jobCs; } if (cs) { @@ -88,7 +78,7 @@ export default function initializeAppInsights( debug('insights telemetry is not configured with a key or connection string'); } - app?.use((req: ReposAppRequest, res: Response, next: NextFunction) => { + app.use((req: ReposAppRequest, res, next) => { // Acknowledge synthetic tests immediately without spending time in more middleware if ( req.headers && diff --git a/middleware/business/administration.ts b/middleware/business/administration.ts index 7b192cd09..38e11a052 100644 --- a/middleware/business/administration.ts +++ b/middleware/business/administration.ts @@ -3,13 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; +const router: Router = Router(); import { ReposAppRequest } from '../../interfaces'; -import { wrapError } from '../../lib/utils'; +import { wrapError } from '../../utils'; -function denyRoute(next: NextFunction) { +function denyRoute(next) { next( wrapError( null, @@ -19,11 +20,7 @@ function denyRoute(next: NextFunction) { ); } -export function requirePortalAdministrationPermission( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export function requirePortalAdministrationPermission(req: ReposAppRequest, res, next) { req.individualContext .isPortalAdministrator() .then((isAdmin) => { diff --git a/middleware/business/allLinks.ts b/middleware/business/allLinks.ts index ece49af9a..c25f57df3 100644 --- a/middleware/business/allLinks.ts +++ b/middleware/business/allLinks.ts @@ -3,15 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; -import { wrapError } from '../../lib/utils'; +import { getProviders } from '../../transitional'; +import { wrapError } from '../../utils'; const cachedLinksRequestKeyName = 'cachedLinks'; -export async function ensureAllLinksInMemory(req: ReposAppRequest, res: Response, next: NextFunction) { +export async function ensureAllLinksInMemory(req: ReposAppRequest, res, next) { if (req[cachedLinksRequestKeyName]) { return next(); } diff --git a/middleware/business/authentication.ts b/middleware/business/authentication.ts index b0efa15a7..2c371c112 100644 --- a/middleware/business/authentication.ts +++ b/middleware/business/authentication.ts @@ -3,32 +3,30 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Response, NextFunction } from 'express'; - import { ReposAppRequest, IAppSession } from '../../interfaces'; import Debug from 'debug'; const debug = Debug.debug('user'); -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { ICorporateIdentity, IGitHubIdentity, IndividualContext, GitHubIdentitySource, } from '../../business/user'; -import { storeOriginalUrlAsReferrer } from '../../lib/utils'; +import { storeOriginalUrlAsReferrer } from '../../utils'; import getCompanySpecificDeployment from '../companySpecificDeployment'; export async function requireAuthenticatedUserOrSignInExcluding( exclusionPaths: string[], req: ReposAppRequest, - res: Response, - next: NextFunction + res, + next ) { - const url = req.url; + const baseUrl = req.baseUrl; for (let i = 0; i < exclusionPaths.length; i++) { - if (url.startsWith(exclusionPaths[i])) { + if (baseUrl.startsWith(exclusionPaths[i])) { console.log(`${req.method} ${req.baseUrl} excluded from auth by prefix: ${exclusionPaths[i]}`); return next(); } @@ -36,7 +34,7 @@ export async function requireAuthenticatedUserOrSignInExcluding( return await requireAuthenticatedUserOrSignIn(req, res, next); } -export async function requireAccessTokenClient(req: ReposAppRequest, res: Response, next: NextFunction) { +export async function requireAccessTokenClient(req: ReposAppRequest, res, next) { if (req.oauthAccessToken) { return next(); } @@ -65,7 +63,7 @@ export async function requireAccessTokenClient(req: ReposAppRequest, res: Respon return next(); } -function signoutThenSignIn(req: ReposAppRequest, res: Response) { +function signoutThenSignIn(req: ReposAppRequest, res) { const { insights } = getProviders(req); req.logout({ keepSessionInfo: false }, (err) => { if (err) { @@ -75,7 +73,7 @@ function signoutThenSignIn(req: ReposAppRequest, res: Response) { }); } -function redirectToSignIn(req: ReposAppRequest, res: Response) { +function redirectToSignIn(req, res) { const config = getProviders(req).config; storeOriginalUrlAsReferrer( req, @@ -85,11 +83,7 @@ function redirectToSignIn(req: ReposAppRequest, res: Response) { ); } -export async function requireAuthenticatedUserOrSignIn( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export async function requireAuthenticatedUserOrSignIn(req: ReposAppRequest, res, next) { const companySpecific = getCompanySpecificDeployment(); const providers = getProviders(req); const { config } = providers; @@ -117,7 +111,7 @@ export async function requireAuthenticatedUserOrSignIn( return shouldRedirectToSignIn ? redirectToSignIn(req, res) : next(); } -export function setIdentity(req: ReposAppRequest, res: Response, next: NextFunction) { +export function setIdentity(req: ReposAppRequest, res, next) { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext) { return next(new Error('No context available')); diff --git a/middleware/business/corporateAdministrators.ts b/middleware/business/corporateAdministrators.ts index 07e2f5795..b36e9b391 100644 --- a/middleware/business/corporateAdministrators.ts +++ b/middleware/business/corporateAdministrators.ts @@ -6,19 +6,17 @@ // This route does not use GitHub as a source of truth but instead falls back to // corporate assigned usernames or security group membership. -import { NextFunction, Response } from 'express'; - import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { IndividualContext } from '../../business/user'; -import { wrapError } from '../../lib/utils'; +import { wrapError } from '../../utils'; import { jsonError } from '../jsonError'; export interface IReposAppRequestWithSystemAdministration extends ReposAppRequest { isSystemAdministrator: boolean; } -function denyRoute(next: NextFunction, isApi: boolean) { +function denyRoute(next, isApi: boolean) { if (isApi) { return next(jsonError('This API is unavailable for you', 403)); } @@ -31,11 +29,7 @@ function denyRoute(next: NextFunction, isApi: boolean) { ); } -export async function AuthorizeOnlyCorporateAdministrators( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export async function AuthorizeOnlyCorporateAdministrators(req: ReposAppRequest, res, next) { const { operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const corporateId = activeContext.corporateIdentity?.id; @@ -48,8 +42,8 @@ export async function AuthorizeOnlyCorporateAdministrators( export async function checkIsCorporateAdministrator( req: IReposAppRequestWithSystemAdministration, - res: Response, - next: NextFunction + res, + next ) { await getIsCorporateAdministrator(req); return next(); diff --git a/middleware/business/corporateAlias.ts b/middleware/business/corporateAlias.ts index 78b451f82..7221975ff 100644 --- a/middleware/business/corporateAlias.ts +++ b/middleware/business/corporateAlias.ts @@ -5,7 +5,7 @@ import { jsonError } from '..'; import { IProviders, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { IndividualContext } from '../../business/user'; const cachedCorporateAliasRequestKey = '__corporateAlias'; diff --git a/middleware/business/corporateHierarchy.ts b/middleware/business/corporateHierarchy.ts index ed38c588d..77b0e40fc 100644 --- a/middleware/business/corporateHierarchy.ts +++ b/middleware/business/corporateHierarchy.ts @@ -6,7 +6,7 @@ import { jsonError } from '..'; import { IProviders, ReposAppRequest } from '../../interfaces'; import { IGraphEntry } from '../../lib/graphProvider'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { IndividualContext } from '../../business/user'; const cachedCorporateHierarchyRequestKey = '__corporateTree'; diff --git a/middleware/business/corporateMail.ts b/middleware/business/corporateMail.ts index 72b294801..fd6a2a5ab 100644 --- a/middleware/business/corporateMail.ts +++ b/middleware/business/corporateMail.ts @@ -5,7 +5,7 @@ import { jsonError } from '..'; import { IProviders, ReposAppRequest } from '../../interfaces'; -import { ErrorHelper, getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { IndividualContext } from '../../business/user'; const cachedCorporateMailRequestKey = '__corporateMail'; @@ -25,31 +25,18 @@ export async function getCorporateMailFromActiveContext( providers: IProviders, activeContext: IndividualContext ): Promise { + const { graphProvider } = providers; if (!activeContext.corporateIdentity || !activeContext.corporateIdentity.id) { throw jsonError('No corporate identity', 401); } let corporateMail = activeContext?.link?.corporateMailAddress; if (!corporateMail) { - const mail = await tryGetCorporateMailFromId(providers, activeContext.corporateIdentity.id); - if (!mail) { + const id = activeContext.corporateIdentity.id; + const entry = await graphProvider.getUserById(id); + if (!entry || !entry.mailNickname) { throw jsonError('Invalid corporate identity', 401); } - corporateMail = mail; + corporateMail = entry.mail; } return corporateMail; } - -export async function tryGetCorporateMailFromId(providers: IProviders, corporateId: string): Promise { - const { graphProvider } = providers; - try { - const info = await graphProvider.getUserById(corporateId); - if (info?.mail) { - return info.mail; - } - } catch (error) { - if (!ErrorHelper.IsNotFound(error)) { - throw error; - } - } - return null; -} diff --git a/middleware/business/employeesOnly.ts b/middleware/business/employeesOnly.ts index 3689147a4..ed6bb588f 100644 --- a/middleware/business/employeesOnly.ts +++ b/middleware/business/employeesOnly.ts @@ -5,15 +5,9 @@ // This is a Microsoft-specific piece of middleware. -import { NextFunction, Response } from 'express'; - import { ReposAppRequest } from '../../interfaces'; -export function AuthorizeOnlyFullTimeEmployeesAndInterns( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export function AuthorizeOnlyFullTimeEmployeesAndInterns(req: ReposAppRequest, res, next) { const individualContext = req.individualContext; if (!individualContext.corporateIdentity || !individualContext.corporateIdentity.username) { return next(new Error('This resource is only available to authenticated users.')); diff --git a/middleware/business/organization.ts b/middleware/business/organization.ts index b5872dc00..04ff3a199 100644 --- a/middleware/business/organization.ts +++ b/middleware/business/organization.ts @@ -3,12 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { ReposAppRequest } from '../../interfaces/web'; import { jsonError } from '../jsonError'; -import { CreateError, ErrorHelper, getProviders } from '../../lib/transitional'; -import { setOrganizationProfileForRequest } from '../github/ensureOrganizationProfile'; export enum OrganizationManagementType { Managed = 'managed', @@ -25,11 +21,7 @@ export function getOrganizationManagementType(req: IReposAppRequestWithOrganizat return req.organizationManagementType; } -export function blockIfUnmanagedOrganization( - req: IReposAppRequestWithOrganizationManagementType, - res: Response, - next: NextFunction -) { +export function blockIfUnmanagedOrganization(req: IReposAppRequestWithOrganizationManagementType, res, next) { const managementType = getOrganizationManagementType(req); switch (managementType) { case OrganizationManagementType.Unmanaged: @@ -40,38 +32,3 @@ export function blockIfUnmanagedOrganization( return next(jsonError('unknown organization management type', 500)); } } - -export async function apiMiddlewareOrganizationsToOrganization( - req: IReposAppRequestWithOrganizationManagementType, - res: Response, - next: NextFunction -) { - const { operations } = getProviders(req); - const { orgName } = req.params; - req.organizationName = orgName; - try { - const org = operations.getOrganization(orgName); - if (org) { - req.organizationManagementType = OrganizationManagementType.Managed; - req.organization = org; - return next(); - } - } catch (orgNotFoundError) { - if (!ErrorHelper.IsNotFound(orgNotFoundError)) { - return next(orgNotFoundError); - } - } - try { - const org = operations.getUncontrolledOrganization(orgName); - req.organizationManagementType = OrganizationManagementType.Unmanaged; - req.organization = org; - await setOrganizationProfileForRequest(req); - } catch (orgProfileError) { - if (ErrorHelper.IsNotFound(orgProfileError)) { - return next(CreateError.NotFound(`The organization ${orgName} does not exist`)); - } else { - return next(orgProfileError); - } - } - return next(); -} diff --git a/middleware/business/repository.ts b/middleware/business/repository.ts deleted file mode 100644 index d93618313..000000000 --- a/middleware/business/repository.ts +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { NextFunction, Response } from 'express'; - -import { Repository } from '../../business/repository'; -import type { ReposAppRequest } from '../../interfaces/web'; -import { CreateError } from '../../lib/transitional'; - -export type RequestWithRepo = ReposAppRequest & { - repository: Repository; -}; - -export async function apiMiddlewareRepositoriesToRepository( - req: RequestWithRepo, - res: Response, - next: NextFunction -) { - const { organization } = req; - if (!organization) { - return next(CreateError.InvalidParameters('No organization instance available')); - } - - const { repoName } = req.params; - if (!repoName) { - return next(CreateError.InvalidParameters('No repository name provided')); - } - - // does not confirm the name - req.repository = organization.repository(repoName); - return next(); -} diff --git a/middleware/business/setContext.ts b/middleware/business/setContext.ts index 37d8a34e2..9b2d90794 100644 --- a/middleware/business/setContext.ts +++ b/middleware/business/setContext.ts @@ -3,7 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; import { IndividualContext, IIndividualContextOptions, @@ -12,10 +11,9 @@ import { SessionUserProperties, WebApiContext, } from '../../business/user'; -import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; -export function webContextMiddleware(req: ReposAppRequest, res: Response, next: NextFunction) { +export function webContextMiddleware(req, res, next) { const { operations, insights } = getProviders(req); if (req.apiContext) { const msg = 'INVALID: API and web contexts should not be mixed'; @@ -48,7 +46,7 @@ export function webContextMiddleware(req: ReposAppRequest, res: Response, next: return next(); } -export function apiContextMiddleware(req, res: Response, next: NextFunction) { +export function apiContextMiddleware(req, res, next) { const { operations, insights } = getProviders(req); if (req.individualContext) { const msg = 'INVALID: API and web contexts should not be mixed'; diff --git a/middleware/business/userSettings.ts b/middleware/business/userSettings.ts deleted file mode 100644 index 8ab028405..000000000 --- a/middleware/business/userSettings.ts +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import type { NextFunction, Response } from 'express'; - -import type { ReposAppRequestWithUserSettings } from '../../interfaces/middleware'; - -import { UserSettings } from '../../business/entities/userSettings'; -import { ErrorHelper, getProviders } from '../../lib/transitional'; -import { IndividualContext } from '../../business/user'; - -export async function getUserSettings( - req: ReposAppRequestWithUserSettings, - res: Response, - next: NextFunction -) { - const activeContext = (req.individualContext || req.apiContext) as IndividualContext; - const corporateId = activeContext?.corporateIdentity?.id; - const { userSettingsProvider } = getProviders(req); - if (corporateId && !req.userSettings) { - let settings: UserSettings = null; - try { - settings = await userSettingsProvider.getUserSettings(corporateId); - } catch (notFoundError) { - if (ErrorHelper.IsNotFound(notFoundError)) { - // ignore - } else { - throw notFoundError; - } - } - if (!settings) { - settings = new UserSettings(); - settings.corporateId = corporateId; - await userSettingsProvider.insertUserSettings(settings); - } - req.userSettings = settings; - } - return next(); -} diff --git a/middleware/campaign.ts b/middleware/campaign.ts index 2d8fd77da..f1278f930 100644 --- a/middleware/campaign.ts +++ b/middleware/campaign.ts @@ -3,9 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; interface ICampaignData { uri?: any; @@ -25,7 +23,7 @@ export default function initializeCampaigns(app) { // come through the app. app.use('*', campaignMiddleware); - function campaignMiddleware(req, res: Response, next: NextFunction) { + function campaignMiddleware(req, res, next) { process.nextTick(processCampaignTelemetry.bind(null, req)); // Immediate return to keep middleware going diff --git a/middleware/codespaces.ts b/middleware/codespaces.ts index 4a38fc2c1..46e4e9c00 100644 --- a/middleware/codespaces.ts +++ b/middleware/codespaces.ts @@ -3,15 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { ReposAppRequest } from '../interfaces'; // Assistant for when using Visual Studio Code to connect to a Codespace // locally instead of the web. The default port forwarding experience is // to toast the user to browse to 127.0.0.1:3000, but since AAD does not // allow for IP-based callback URLs, the user must use localhost. -export function codespacesDevAssistant(req: ReposAppRequest, res: Response, next: NextFunction) { +export function codespacesDevAssistant(req: ReposAppRequest, res, next) { if (req.hostname === '127.0.0.1') { console.warn( `${req.method} ${req.url}: WARNING: You're trying to connect to ${req.hostname} from your codespace.` diff --git a/middleware/companySpecificDeployment.ts b/middleware/companySpecificDeployment.ts index 14d38df2a..d42009bff 100644 --- a/middleware/companySpecificDeployment.ts +++ b/middleware/companySpecificDeployment.ts @@ -18,13 +18,13 @@ function getCompanySpecificDeploymentName() { } function getCompanySpecificDeployment(): ICompanySpecificStartup { - if (instance) { - return instance; - } const name = getCompanySpecificDeploymentName(); if (!name) { return null; } + if (instance) { + return instance; + } try { const pn = path.join(__dirname, '..', name); const dynamicInclude = require(pn); diff --git a/middleware/corporateViews.ts b/middleware/corporateViews.ts index 24b53f8bb..4f16ef7f0 100644 --- a/middleware/corporateViews.ts +++ b/middleware/corporateViews.ts @@ -7,7 +7,7 @@ import { constants as fsConstants, promises as fs } from 'fs'; import path from 'path'; import { IProviders } from '../interfaces'; -import { stripDistFolderName } from '../lib/transitional'; +import { stripDistFolderName } from '../transitional'; // providers.corporateViews: // --- diff --git a/middleware/correlationId.ts b/middleware/correlationId.ts index 9f491d1a5..df5b433a7 100644 --- a/middleware/correlationId.ts +++ b/middleware/correlationId.ts @@ -3,15 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Request, Response } from 'express'; import { randomUUID } from 'crypto'; -export type WithCorrelationId = T & { - correlationId?: string; -}; - // Generate a correlation ID -export default function (req: WithCorrelationId, res: Response, next: NextFunction) { +export default function (req, res, next) { req.correlationId = randomUUID(); return next(); } diff --git a/middleware/errorRoutes.ts b/middleware/error-routes.ts similarity index 74% rename from middleware/errorRoutes.ts rename to middleware/error-routes.ts index f0b92c709..f5f621d02 100644 --- a/middleware/errorRoutes.ts +++ b/middleware/error-routes.ts @@ -3,15 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Request, Response } from 'express'; - import { IReposApplication, IReposError } from '../interfaces'; -import routeErrorHandler from './errorHandler'; +import RouteErrorHandler from './errorHandler'; export default async function configureErrorRoutes(app: IReposApplication, initializationError: Error) { - if (!app) { - return; - } if (initializationError) { console.warn('Initialization Error Present: All app requests will fail!'); @@ -19,7 +14,7 @@ export default async function configureErrorRoutes(app: IReposApplication, initi // for any request. Should evaluate whether to hide for // production scenarios or if there is a risk of the // error message leaking sensitive data. - app.use((req: Request, res: Response, next: NextFunction) => { + app.use((req, res, next) => { const error: IReposError = new Error('Application initialization error', { cause: initializationError, }); @@ -28,12 +23,12 @@ export default async function configureErrorRoutes(app: IReposApplication, initi }); } - app.use(function (req: Request, res: Response, next: NextFunction) { + app.use(function (req, res, next) { const err: IReposError = new Error('Not Found'); err.status = 404; err.skipLog = true; - return next(err); + next(err); }); - app.use(routeErrorHandler); + app.use(RouteErrorHandler); } diff --git a/middleware/errorHandler.ts b/middleware/errorHandler.ts index dcfd64194..7277cc666 100644 --- a/middleware/errorHandler.ts +++ b/middleware/errorHandler.ts @@ -6,11 +6,9 @@ import querystring from 'querystring'; import { AxiosError } from 'axios'; -import { wrapError } from '../lib/utils'; -import { getProviders } from '../lib/transitional'; +import { wrapError } from '../utils'; +import { getProviders } from '../transitional'; import { isJsonError } from '.'; -import { NextFunction, Response } from 'express'; -import { ReposAppRequest } from '../interfaces'; function redactRootPathsFromString(string, path) { if (typeof string === 'string' && string.includes && string.split) { @@ -51,16 +49,9 @@ const exceptionFieldsOfInterest = [ 'innerMessage', ]; -export default function SiteErrorHandler( - error: unknown, - req: ReposAppRequest, - res: Response, - next: NextFunction -) { - let err = error as any; - const isJson = isJsonError(err, req.url); +export default function SiteErrorHandler(err, req, res, next) { // CONSIDER: Let's eventually decouple all of our error message improvements to another area to keep the error handler intact. - const { applicationProfile, config, insights } = getProviders(req); + const { applicationProfile, config } = getProviders(req); const correlationId = req.correlationId; const errorStatus = err ? err.status || err.statusCode : undefined; // Per GitHub: https://developer.github.com/v3/oauth/#bad-verification-code @@ -72,8 +63,8 @@ export default function SiteErrorHandler( err.oauthError.message === 'The code passed is incorrect or expired.')) && req.scrubbedUrl.startsWith('/auth/github/') ) { - insights?.trackMetric({ name: 'GitHubInvalidExpiredCodeRedirect', value: 1 }); - insights?.trackEvent({ name: 'GitHubInvalidExpiredCodeRetry' }); + req.insights.trackMetric({ name: 'GitHubInvalidExpiredCodeRedirect', value: 1 }); + req.insights.trackEvent({ name: 'GitHubInvalidExpiredCodeRetry' }); return res.redirect( req.scrubbedUrl === '/auth/github/callback/increased-scope?code=*****' ? '/auth/github/increased-scope' @@ -83,7 +74,7 @@ export default function SiteErrorHandler( const isGitHubAbuseRateLimit = err && err.message && err.message.includes && err.message.includes('#abuse-rate-limits'); if (isGitHubAbuseRateLimit) { - insights?.trackMetric({ name: 'GitHubAbuseRateLimit', value: 1 }); + req.insights.trackMetric({ name: 'GitHubAbuseRateLimit', value: 1 }); } if ( err.message && @@ -91,8 +82,8 @@ export default function SiteErrorHandler( err.message.includes('ETIMEDOUT') && (err.message.includes('192.30.253.116') || err.message.includes('192.30.253.117')) ) { - insights?.trackMetric({ name: 'GitHubApiTimeout', value: 1 }); - insights?.trackEvent({ name: 'GitHubApiTimeout' }); + req.insights.trackMetric({ name: 'GitHubApiTimeout', value: 1 }); + req.insights.trackEvent({ name: 'GitHubApiTimeout' }); err = wrapError(err, 'The GitHub API is temporarily down. Please try again soon.', false); } let primaryUserInstance = req.user ? req.user.github : null; @@ -112,7 +103,7 @@ export default function SiteErrorHandler( stk: undefined, message: undefined, }; - if (insights?.trackException) { + if (req.insights && req.insights.trackException) { for (let i = 0; err && i < exceptionFieldsOfInterest.length; i++) { const key = exceptionFieldsOfInterest[i]; const value = err[key]; @@ -134,7 +125,7 @@ export default function SiteErrorHandler( } if (isGitHubAbuseRateLimit) { insightsProperties.message = err.message; - insights?.trackEvent({ + req.insights.trackEvent({ name: 'GitHubAbuseRateLimitError', properties: insightsProperties, }); @@ -142,7 +133,7 @@ export default function SiteErrorHandler( if (err && err['json']) { // not tracking jsonErrors for now, they pollute app insights } else { - insights?.trackException({ exception: err, properties: insightsProperties }); + req.insights.trackException({ exception: err, properties: insightsProperties }); } } } @@ -150,6 +141,7 @@ export default function SiteErrorHandler( } if (err !== undefined && err.skipLog !== true) { console.log('Error: ' + (err && err.message ? err.message : 'Error is undefined.')); + const isJson = isJsonError(err); if (err.stack && !isJson) { console.error(err.stack); } @@ -242,7 +234,7 @@ export default function SiteErrorHandler( // Support JSON-based error display for the API route, showing just a small // subset of typical view properties to share from the error instance. - if (isJson) { + if (err && err.json === true) { const safeError = { message: safeMessage, correlationId: correlationId, diff --git a/middleware/github/blockEnterpriseManagedUsers.ts b/middleware/github/blockEnterpriseManagedUsers.ts index b9d13c50f..740d11dad 100644 --- a/middleware/github/blockEnterpriseManagedUsers.ts +++ b/middleware/github/blockEnterpriseManagedUsers.ts @@ -3,16 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { ReposAppRequest, IReposError } from '../../interfaces'; -import { isEnterpriseManagedUserLogin } from '../../lib/utils'; +import { isEnterpriseManagedUserLogin } from '../../utils'; -export function blockEnterpriseManagedUsersAuthentication( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export function blockEnterpriseManagedUsersAuthentication(req: ReposAppRequest, res, next) { const context = req.individualContext; if (!context) { return next(new Error('Missing context')); diff --git a/middleware/github/ensureOrganizationProfile.ts b/middleware/github/ensureOrganizationProfile.ts deleted file mode 100644 index 7dbec0828..000000000 --- a/middleware/github/ensureOrganizationProfile.ts +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import asyncHandler from 'express-async-handler'; -import memoryCache from 'memory-cache'; -import { NextFunction, Response } from 'express'; - -import type { IReposAppRequestWithOrganizationManagementType } from '../business/organization'; -import { CreateError, getProviders } from '../../lib/transitional'; -import { - getOrganizationDetailsSanitized, - type GitHubOrganizationResponseSanitized, -} from '../../business/organization'; -import type { IProviders } from '../../interfaces'; - -export async function setOrganizationProfileForRequest(req: IReposAppRequestWithOrganizationManagementType) { - const providers = getProviders(req); - const org = req.organization; - if (!org) { - throw CreateError.InvalidParameters('No organization instance available in the request'); - } - if (!req.organizationProfile && org?.id) { - req.organizationProfile = await getOrganizationProfileViaMemoryCache(providers, String(org.id)); - } - if (!req.organizationProfile && org) { - req.organizationProfile = getOrganizationDetailsSanitized(await org.getDetails()); - } -} - -export async function getOrganizationProfileViaMemoryCache(providers: IProviders, organizationId: string) { - const { operations } = providers; - const cacheTimeMs = 1000 * 60 * 60 * 24; - - const key = `org:profile:${organizationId}`; - let profile = memoryCache.get(key) as GitHubOrganizationResponseSanitized; - if (!profile) { - const details = getOrganizationDetailsSanitized( - await operations.getOrganizationProfileById(Number(organizationId)) - ); - profile = details; - memoryCache.put(key, details, cacheTimeMs); - } - return profile; -} - -async function ensureOrganizationProfile( - req: IReposAppRequestWithOrganizationManagementType, - res: Response, - next: NextFunction -) { - await setOrganizationProfileForRequest(req); - return next(); -} - -export const ensureOrganizationProfileMiddleware = asyncHandler(ensureOrganizationProfile); diff --git a/middleware/github/orgPermissions.ts b/middleware/github/orgPermissions.ts index d3a4a63a0..9a0626211 100644 --- a/middleware/github/orgPermissions.ts +++ b/middleware/github/orgPermissions.ts @@ -3,10 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { OrganizationMembershipState, ReposAppRequest } from '../../interfaces'; -import { wrapError } from '../../lib/utils'; +import { wrapError } from '../../utils'; const orgPermissionsCacheKeyName = 'orgPermissions'; const orgOwnersCacheKeyName = 'orgOwners'; @@ -23,11 +21,7 @@ export function GetOrganizationPermissionsFromRequest(req: ReposAppRequest) { return req[orgPermissionsCacheKeyName]; } -export async function AddOrganizationPermissionsToRequest( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export async function AddOrganizationPermissionsToRequest(req: ReposAppRequest, res, next) { // Only compute once per request if (req[orgPermissionsCacheKeyName]) { return next(); diff --git a/middleware/github/repoPermissions.ts b/middleware/github/repoPermissions.ts index d6c06a63a..735f76bc1 100644 --- a/middleware/github/repoPermissions.ts +++ b/middleware/github/repoPermissions.ts @@ -3,9 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - -import { ErrorHelper, getProviders } from '../../lib/transitional'; +import { ErrorHelper, getProviders } from '../../transitional'; import { Repository } from '../../business/repository'; import { GitHubIdentitySource, IIndividualContextOptions, IndividualContext } from '../../business/user'; import getCompanySpecificDeployment from '../companySpecificDeployment'; @@ -109,33 +107,30 @@ export async function getComputedRepositoryPermissions( repoPermissions, activeContext ); + if (!activeContext.link) { + return repoPermissions; + } + repoPermissions.isLinked = true; + const login = activeContext.getGitHubIdentity().username; + const organization = repository.organization; + const isSudoer = await organization.isSudoer(login, activeContext.link); const isPortalSudoer = await activeContext.isPortalAdministrator(); - if (isPortalSudoer) { + if (isSudoer === true || isPortalSudoer === true) { repoPermissions.sudo = true; } - repoPermissions.isLinked = !!activeContext.link; - const hasGitHubIdentity = !!activeContext?.getGitHubIdentity()?.username; - if (hasGitHubIdentity) { - const login = activeContext.getGitHubIdentity().username; - const organization = repository.organization; - const isSudoer = await organization.isSudoer(login, activeContext.link); - if (isSudoer) { - repoPermissions.sudo = true; - } - try { - const collaborator = await repository.getCollaborator(login); - if (collaborator) { - if (collaborator.permission === GitHubCollaboratorPermissionLevel.Admin) { - repoPermissions.admin = repoPermissions.read = repoPermissions.write = true; - } else if (collaborator.permission === GitHubCollaboratorPermissionLevel.Write) { - repoPermissions.read = repoPermissions.write = true; - } else if (collaborator.permission === GitHubCollaboratorPermissionLevel.Read) { - repoPermissions.read = true; - } + try { + const collaborator = await repository.getCollaborator(login); + if (collaborator) { + if (collaborator.permission === GitHubCollaboratorPermissionLevel.Admin) { + repoPermissions.admin = repoPermissions.read = repoPermissions.write = true; + } else if (collaborator.permission === GitHubCollaboratorPermissionLevel.Write) { + repoPermissions.read = repoPermissions.write = true; + } else if (collaborator.permission === GitHubCollaboratorPermissionLevel.Read) { + repoPermissions.read = true; } - } catch (getCollaboratorPermissionError) { - console.dir(getCollaboratorPermissionError); } + } catch (getCollaboratorPermissionError) { + console.dir(getCollaboratorPermissionError); } if (repoPermissions.admin || repoPermissions.sudo) { repoPermissions.allowAdministration = true; @@ -150,11 +145,7 @@ export async function getComputedRepositoryPermissions( return repoPermissions; } -export async function AddRepositoryPermissionsToRequest( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export async function AddRepositoryPermissionsToRequest(req: ReposAppRequest, res, next) { if (req[repoPermissionsCacheKeyName]) { return next(); } diff --git a/middleware/github/requireActiveSession.ts b/middleware/github/requireActiveSession.ts index a0b46b553..f58ac23b6 100644 --- a/middleware/github/requireActiveSession.ts +++ b/middleware/github/requireActiveSession.ts @@ -3,12 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; -import { isCodespacesAuthenticating, storeOriginalUrlAsReferrer } from '../../lib/utils'; +import { getProviders } from '../../transitional'; +import { isCodespacesAuthenticating, storeOriginalUrlAsReferrer } from '../../utils'; -export default function RequireActiveGitHubSession(req: ReposAppRequest, res: Response, next: NextFunction) { +export default function RequireActiveGitHubSession(req: ReposAppRequest, res, next) { const { config } = getProviders(req); const identity = req.individualContext.getSessionBasedGitHubIdentity(); if (!identity) { diff --git a/middleware/github/systemWidePermissions.ts b/middleware/github/systemWidePermissions.ts index 8787fbdc1..16d6d95cf 100644 --- a/middleware/github/systemWidePermissions.ts +++ b/middleware/github/systemWidePermissions.ts @@ -3,17 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { ReposAppRequest } from '../../interfaces'; const requestCachedKeyName = 'systemWidePermissions'; -export default function addSystemWidePermissionsToRequest( - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +export default function addSystemWidePermissionsToRequest(req: ReposAppRequest, res, next) { // Only compute once per request if (req[requestCachedKeyName]) { return next(); diff --git a/middleware/github/teamPermissions.ts b/middleware/github/teamPermissions.ts index 0061260e5..16c7317f0 100644 --- a/middleware/github/teamPermissions.ts +++ b/middleware/github/teamPermissions.ts @@ -3,17 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { Team } from '../../business'; import { GitHubTeamRole, ITeamMembershipRoleState, - NoCacheNoBackground, OrganizationMembershipState, ReposAppRequest, } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { IndividualContext } from '../../business/user'; import getCompanySpecificDeployment from '../companySpecificDeployment'; @@ -43,11 +40,10 @@ export function getTeamMembershipFromRequest(req: ReposAppRequest) { return req[teamStatusCacheKeyName] as IRequestTeamMembershipStatus; } -export async function AddTeamMembershipToRequest(req: ReposAppRequest, res: Response, next: NextFunction) { +export async function AddTeamMembershipToRequest(req: ReposAppRequest, res, next) { if (req[teamStatusCacheKeyName]) { return next(); } - const skipCache = req.query.cache === '0'; const team2 = req['team2'] as Team; if (!team2) { return next(new Error('team2 required')); @@ -63,9 +59,7 @@ export async function AddTeamMembershipToRequest(req: ReposAppRequest, res: Resp } else { const login = activeContext.getGitHubIdentity().username; try { - const statusResult = skipCache - ? await team2.getMembership(login, NoCacheNoBackground) - : await team2.getMembershipEfficiently(login); + const statusResult = await team2.getMembershipEfficiently(login); const value: IRequestTeamMembershipStatus = { membershipStatus: statusResult && (statusResult as ITeamMembershipRoleState).role @@ -100,7 +94,7 @@ export function getTeamPermissionsFromRequest(req: ReposAppRequest) { return req[teamPermissionsCacheKeyName] as IRequestTeamPermissions; } -export async function AddTeamPermissionsToRequest(req: ReposAppRequest, res: Response, next: NextFunction) { +export async function AddTeamPermissionsToRequest(req: ReposAppRequest, res, next) { if (req[teamPermissionsCacheKeyName]) { return next(); } diff --git a/middleware/healthCheck.ts b/middleware/healthCheck.ts index 858057919..d8997c229 100644 --- a/middleware/healthCheck.ts +++ b/middleware/healthCheck.ts @@ -5,15 +5,13 @@ import Debug from 'debug'; import { IncomingHttpHeaders } from 'http'; -import { NextFunction, Response } from 'express'; - import type { ConfiguredHeaderProbe, ConfiguredGeneralProbe, ConfiguredProbeBase, } from '../config/webHealthProbes.types'; -import { IReposApplication, ReposAppRequest, SiteConfiguration } from '../interfaces'; -import { CreateError } from '../lib/transitional'; +import { ReposAppRequest, SiteConfiguration } from '../interfaces'; +import { CreateError } from '../transitional'; const dbg = Debug.debug('health'); @@ -31,7 +29,7 @@ enum ProbeType { } export default function initializeHealthCheck( - app: IReposApplication, + app, config: SiteConfiguration /* WebHealthProbeSubsetConfiguration */ ) { const { webHealthProbes: healthConfig } = config; @@ -86,8 +84,8 @@ export default function initializeHealthCheck( probeType: ProbeType, probeConfigs: ConfiguredHeaderProbe[], req: ReposAppRequest, - res: Response, - next: NextFunction + res, + next ) { for (const probeConfig of probeConfigs) { if (requestEligibleForCheck(checkType, probeType, probeConfig, req.headers)) { @@ -135,12 +133,7 @@ export default function initializeHealthCheck( return true; } - function returnExpressHealthCheck( - checkType: HealthProbeType, - req: ReposAppRequest, - res: Response, - next: NextFunction - ) { + function returnExpressHealthCheck(checkType: HealthProbeType, req: ReposAppRequest, res, next) { let result = null; try { result = checkHealth(checkType); @@ -156,7 +149,7 @@ export default function initializeHealthCheck( healthy: true, }; - if (enabledHeaderProbes.length > 0 && app) { + if (enabledHeaderProbes.length > 0) { dbg(`Configured header health probes: ${enabledHeaderProbes.length}`); app.get( '/health/readiness', @@ -167,7 +160,7 @@ export default function initializeHealthCheck( multipleHeaderHealthCheck.bind(null, HealthProbeType.Liveness, ProbeType.Header, enabledHeaderProbes) ); } - if (enabledGenericProbes.length > 0 && app) { + if (enabledGenericProbes.length > 0) { // General probes listen on their own type endpoint for (const genericProbeConfig of enabledGenericProbes) { const url = genericProbeConfig.endpoint || `/health/${genericProbeConfig.endpointSuffix}`; @@ -180,7 +173,7 @@ export default function initializeHealthCheck( ); } } - if (app && enabledGenericProbes.length + enabledGenericProbes.length > 0) { + if (enabledGenericProbes.length + enabledGenericProbes.length > 0) { dbg('Health probes listening'); // 404 on anything that was not handled by any active, allowed probe listeners app.use('/health/*', (req, res) => { diff --git a/middleware/index.ts b/middleware/index.ts index 32e2605c8..c45fdf0c3 100644 --- a/middleware/index.ts +++ b/middleware/index.ts @@ -6,23 +6,21 @@ import bodyParser from 'body-parser'; import compression from 'compression'; import path from 'path'; -import { Express } from 'express'; -import passport from 'passport'; import Debug from 'debug'; const debug = Debug.debug('startup'); export * from './react'; -export * from './business/links'; +export * from './links'; export * from './business'; export * from './jsonError'; -import { hasStaticReactClientApp, stripDistFolderName } from '../lib/transitional'; +import { hasStaticReactClientApp, stripDistFolderName } from '../transitional'; import { StaticClientApp } from './staticClientApp'; import { StaticReactClientApp } from './staticClientApp2'; import { StaticSiteFavIcon, StaticSiteAssets } from './staticSiteAssets'; import connectSession from './session'; -import passportConfig from './passportConfig'; +import passportConfig from './passport-config'; import onboard from './onboarding'; import viewServices from '../lib/pugViewServices'; @@ -37,14 +35,12 @@ import routePassport from './passport-routes'; import routeApi from '../api'; -import type { IProviders, IReposApplication, SiteConfiguration } from '../interfaces'; +import { IProviders, IReposApplication, SiteConfiguration } from '../interfaces'; import { codespacesDevAssistant } from './codespaces'; -import { ExpressWithStatic } from './types'; export default async function initMiddleware( app: IReposApplication, - express: Express, - providers: IProviders, + express, config: SiteConfiguration, dirname: string, hasCustomRoutes: boolean, @@ -55,6 +51,7 @@ export default async function initMiddleware( config && config.typescript && config.typescript.appDirectory ? config.typescript.appDirectory : stripDistFolderName(dirname); + const providers = app.get('providers') as IProviders; const applicationProfile = providers.applicationProfile; if (initializationError) { providers.healthCheck.healthy = false; @@ -81,15 +78,14 @@ export default async function initMiddleware( if (applicationProfile.serveStaticAssets) { StaticSiteAssets(app, express); } - const expressWithStatic = express as ExpressWithStatic; if (hasStaticReactClientApp()) { - StaticReactClientApp(app, expressWithStatic, config); + StaticReactClientApp(app, express, config); } if (applicationProfile.serveClientAssets) { - StaticClientApp(app, expressWithStatic); + StaticClientApp(app, express); } providers.campaign = campaign(app); - let passport: passport.PassportStatic; + let passport; if (!initializationError) { if (config.containers && config.containers.deployment) { app.enable('trust proxy'); diff --git a/middleware/initialize.ts b/middleware/initialize.ts index 4422f6271..b249d29bd 100644 --- a/middleware/initialize.ts +++ b/middleware/initialize.ts @@ -3,7 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Express, NextFunction, Response } from 'express'; import path from 'path'; import CosmosSessionStore from '../lib/cosmosSession'; @@ -15,11 +14,11 @@ import { createAndInitializeEntityMetadataProviderInstance, IEntityMetadataProvidersOptions, } from '../lib/entityMetadataProvider'; -import { createAndInitializeRepositoryMetadataProviderInstance } from '../business/entities/repositoryMetadata'; -import createAndInitializeOrganizationAnnotationProviderInstance from '../business/entities/organizationAnnotation'; +import { createAndInitializeRepositoryMetadataProviderInstance } from '../entities/repositoryMetadata'; +import createAndInitializeOrganizationAnnotationProviderInstance from '../entities/organizationAnnotation'; import { createMailAddressProviderInstance, IMailAddressProvider } from '../lib/mailAddressProvider'; -import ErrorRoutes from './errorRoutes'; +import ErrorRoutes from './error-routes'; import { createClient, RedisClientType } from 'redis'; import { Pool as PostgresPool } from 'pg'; @@ -27,7 +26,6 @@ import { Pool as PostgresPool } from 'pg'; import Debug from 'debug'; const debug = Debug.debug('startup'); const pgDebug = Debug.debug('pgpool'); -const nowDebug = Debug.debug('now'); import appInsights from './appInsights'; import keyVault from './keyVault'; @@ -38,9 +36,9 @@ import expressRoutes from '../routes/'; import alternateRoutes from './alternateApps'; import RedisHelper from '../lib/caching/redis'; -import { createTokenProvider } from '../business/entities/token'; -import { createAndInitializeApprovalProviderInstance } from '../business/entities/teamJoinApproval'; -import { CreateLocalExtensionKeyProvider } from '../business/entities/localExtensionKey'; +import { createTokenProvider } from '../entities/token'; +import { createAndInitializeApprovalProviderInstance } from '../entities/teamJoinApproval'; +import { CreateLocalExtensionKeyProvider } from '../entities/localExtensionKey'; import { CreateGraphProviderInstance, IGraphProvider } from '../lib/graphProvider/'; import initializeCorporateViews from './corporateViews'; @@ -48,16 +46,16 @@ import keyVaultResolver, { IKeyVaultSecretResolver } from '../lib/keyVaultResolv import { createMailProviderInstance } from '../lib/mailProvider/'; import { RestLibrary } from '../lib/github'; -import { CreateRepositoryCacheProviderInstance } from '../business/entities/repositoryCache'; -import { CreateRepositoryCollaboratorCacheProviderInstance } from '../business/entities/repositoryCollaboratorCache'; -import { CreateTeamCacheProviderInstance } from '../business/entities/teamCache'; -import { CreateTeamMemberCacheProviderInstance } from '../business/entities/teamMemberCache'; -import { CreateRepositoryTeamCacheProviderInstance } from '../business/entities/repositoryTeamCache'; -import { CreateOrganizationMemberCacheProviderInstance } from '../business/entities/organizationMemberCache'; +import { CreateRepositoryCacheProviderInstance } from '../entities/repositoryCache'; +import { CreateRepositoryCollaboratorCacheProviderInstance } from '../entities/repositoryCollaboratorCache'; +import { CreateTeamCacheProviderInstance } from '../entities/teamCache'; +import { CreateTeamMemberCacheProviderInstance } from '../entities/teamMemberCache'; +import { CreateRepositoryTeamCacheProviderInstance } from '../entities/repositoryTeamCache'; +import { CreateOrganizationMemberCacheProviderInstance } from '../entities/organizationMemberCache'; import QueryCache from '../business/queryCache'; -import { createAndInitializeOrganizationSettingProviderInstance } from '../business/entities/organizationSettings'; +import { createAndInitializeOrganizationSettingProviderInstance } from '../entities/organizationSettings'; import { IEntityMetadataProvider } from '../lib/entityMetadataProvider/entityMetadataProvider'; -import { createAndInitializeAuditLogRecordProviderInstance } from '../business/entities/auditLogRecord'; +import { createAndInitializeAuditLogRecordProviderInstance } from '../entities/auditLogRecord'; import CosmosCache from '../lib/caching/cosmosdb'; import BlobCache from '../lib/caching/blob'; import { StatefulCampaignProvider } from '../lib/campaigns'; @@ -65,7 +63,7 @@ import CosmosHelper from '../lib/cosmosHelper'; import { IQueueProcessor } from '../lib/queues'; import ServiceBusQueueProcessor from '../lib/queues/servicebus'; import AzureQueuesProcessor from '../lib/queues/azurequeue'; -import { UserSettingsProvider } from '../business/entities/userSettings'; +import { UserSettingsProvider } from '../entities/userSettings'; import getCompanySpecificDeployment from './companySpecificDeployment'; import routeCorrelationId from './correlationId'; @@ -73,20 +71,13 @@ import routeHsts from './hsts'; import routeSslify from './sslify'; import middlewareIndex from '.'; -import type { ICacheHelper } from '../lib/caching'; -import type { - ExecutionEnvironment, - ApplicationProfile, - IProviders, - IReposApplication, - SiteConfiguration, -} from '../interfaces'; -import initializeRepositoryProvider from '../business/entities/repository'; +import { ICacheHelper } from '../lib/caching'; +import { IApplicationProfile, IProviders, IReposApplication, SiteConfiguration } from '../interfaces'; +import initializeRepositoryProvider from '../entities/repository'; import { tryGetImmutableStorageProvider } from '../lib/immutable'; -import { GitHubAppPurposes } from '../lib/github/appPurposes'; -const DefaultApplicationProfile: ApplicationProfile = { - applicationName: 'Open Source Management Portal', +const DefaultApplicationProfile: IApplicationProfile = { + applicationName: 'GitHub Management Portal', serveStaticAssets: true, serveClientAssets: true, logDependencies: true, @@ -101,13 +92,12 @@ type CompanyStartupEntrypoint = ( ) => Promise; async function initializeAsync( - executionEnvironment: ExecutionEnvironment, - providers: IProviders, - // app: IReposApplication, - // express, + app: IReposApplication, + express, rootdir: string, config: SiteConfiguration ): Promise { + const providers = app.get('providers') as IProviders; providers.postgresPool = await ConnectPostgresPool(config.data.postgres); providers.linkProvider = await createAndInitializeLinkProviderInstance(providers, config); if (config.github.cache.provider === 'cosmosdb') { @@ -121,6 +111,7 @@ async function initializeAsync( } else if (config.github.cache.provider === 'redis') { const redisClient = await connectRedis(config, config.redis, 'cache'); const redisHelper = new RedisHelper({ redisClient, prefix: config.redis.prefix }); + // providers.redisClient = redisClient; providers.cacheProvider = redisHelper; } else { throw new Error('No cache provider available'); @@ -133,7 +124,10 @@ async function initializeAsync( } providers.graphProvider = await createGraphProvider(providers, config); + app.set('graphProvider', providers.graphProvider); + providers.mailAddressProvider = await createMailAddressProvider(config, providers); + app.set('mailAddressProvider', providers.mailAddressProvider); const mailProvider = createMailProviderInstance(config); if (mailProvider) { @@ -145,6 +139,7 @@ async function initializeAsync( } providers.github = configureGitHubLibrary(providers.cacheProvider, config); + app.set('github', providers.github); // always check if config exists to prevent crashing because of trying to access an undefined object const emOptions: IEntityMetadataProvidersOptions = { @@ -273,7 +268,7 @@ async function initializeAsync( providers.corporateAdministrationProfile = getCompanySpecificDeployment()?.administrationSection; providers.corporateViews = await initializeCorporateViews(providers, rootdir); - await dynamicStartup(executionEnvironment, config, providers, rootdir); + await dynamicStartup(config, providers, rootdir); const webhooksConfig = config.github.webhooks; if (webhooksConfig && webhooksConfig.provider) { @@ -295,21 +290,16 @@ async function initializeAsync( const repositoryMetadataProvider = await createAndInitializeRepositoryMetadataProviderInstance({ entityMetadataProvider: providerNameToInstance(config.entityProviders.repositorymetadata), }); - const operations = new Operations({ - executionEnvironment, - providers, - repositoryMetadataProvider, - github: providers.github, - }); + const operations = new Operations({ providers, repositoryMetadataProvider, github: providers.github }); await operations.initialize(); + app.set('operations', operations); providers.operations = operations; - GitHubAppPurposes.RegisterOperationsInstanceForBuiltInPurposes(operations); } catch (ignoredError2) { console.dir(ignoredError2); throw ignoredError2; } - await dynamicStartup(executionEnvironment, config, providers, rootdir, 'secondary'); + await dynamicStartup(config, providers, rootdir, 'secondary'); if (providers.applicationProfile.startup) { debug('Application provider-specific startup...'); @@ -317,7 +307,17 @@ async function initializeAsync( } } -function configureGitHubLibrary(cacheProvider: ICacheHelper, config: SiteConfiguration): RestLibrary { +function configureGitHubLibrary(cacheProvider: ICacheHelper, config): RestLibrary { + if ( + config && + config.github && + config.github.operations && + !config.github.operations.centralOperationsToken + ) { + debug( + 'WARNING: no central GitHub operations token is defined, some library operations may not succeed. ref: config.github.operations.centralOperationsToken var: GITHUB_CENTRAL_OPERATIONS_TOKEN' + ); + } const libraryContext = new RestLibrary({ config, cacheProvider, @@ -327,44 +327,33 @@ function configureGitHubLibrary(cacheProvider: ICacheHelper, config: SiteConfigu // Asynchronous initialization for the Express app, configuration and data stores. export default async function initialize( - executionEnvironment: ExecutionEnvironment, app: IReposApplication, - express: Express, + express, rootdir: string, - config: SiteConfiguration, + config: any, exception: Error -): Promise { +): Promise { if (exception) { console.warn(`Startup exception: ${exception}`, exception?.stack); } if (!config || Object.getOwnPropertyNames(config).length === 0) { throw new Error('Empty configuration object'); } - if (app && !app.runtimeConfiguration) { + if (!app.runtimeConfiguration) { app.runtimeConfiguration = {}; } const applicationProfile = config?.web?.app && config.web.app !== 'repos' ? await alternateRoutes(config, app, config.web.app) : DefaultApplicationProfile; - const web = false === executionEnvironment.skipModules.has('web'); + const web = !(config?.skipModules && config.skipModules.has('web')); if (applicationProfile.webServer && !web) { applicationProfile.webServer = false; } - const containerPurpose = executionEnvironment.isJob - ? 'job' - : applicationProfile.webServer - ? 'web application' - : 'application'; - if (executionEnvironment.entrypointName) { - debug(`${containerPurpose} name: ${executionEnvironment.entrypointName}`); - } - debug(`${containerPurpose} profile: ${applicationProfile.applicationName}`); + const containerPurpose = + config && config.isJobInternal ? 'job' : applicationProfile.webServer ? 'web application' : 'application'; + debug(`${containerPurpose} name: ${applicationProfile.applicationName}`); debug(`environment: ${config?.debug?.environmentName || 'Unknown'}`); - if (config?.continuousDeployment) { - const values = Object.values(config.continuousDeployment).filter((x) => x); - values.length > 0 && debug(`build: ${values.join(', ')}`); - } const codespacesConfig = (config as SiteConfiguration)?.github?.codespaces; if (codespacesConfig?.connected === true && codespacesConfig.block === true) { @@ -388,69 +377,54 @@ export default async function initialize( exception = error; } } - if (app) { - app.set('started', executionEnvironment.started); - app.config = config; - } + app.set('started', new Date()); + app.config = config; if (exception) { // Once app insights is available, will try to log this exception; display for now. console.dir(exception); } - if (app) { - app.set('basedir', rootdir); - } + app.set('basedir', rootdir); const providers: IProviders = { app, basedir: rootdir, applicationProfile, }; - executionEnvironment.providers = providers; - if (app) { - app.set('providers', providers); - app.providers = providers; - app.set('runtimeConfig', config); - } + app.set('providers', providers); + app.providers = providers; + app.set('runtimeConfig', config); providers.healthCheck = healthCheck(app, config); if (applicationProfile.webServer) { - if (!app) { - throw new Error('app (Express) is required for web applications'); - } else if (!app.startServer) { + if (!app.startServer) { throw new Error(`app.startServer is required for web applications`); } await app.startServer(); } - if (app) { - app.use(routeCorrelationId); - } - const insights = appInsights(providers, executionEnvironment, app, config); - providers.insights = insights; + app.use(routeCorrelationId); + providers.insights = appInsights(app, config); + app.set('appInsightsClient', providers.insights); if (!exception && (!config || !config.activeDirectory)) { exception = new Error( `config.activeDirectory.clientId and config.activeDirectory.clientSecret are required to initialize KeyVault` ); } - if (app) { - app.use('*', (req, res: Response, next: NextFunction) => { - if (providers.healthCheck.ready) { - return next(); - } - return res.send('Service not ready.'); - }); - } - // See docs/configuration.md for all this - if (app) { - if (config?.containers?.deployment) { - debug('Container deployment: HTTP: listening, HSTS: on'); - app.use(routeHsts); - } else if (config?.containers?.docker) { - debug('Docker image: HTTP: listening, HSTS: off'); - } else if (config.webServer.allowHttp) { - debug('development mode: HTTP: listening, HSTS: off'); - } else { - debug('non-container production mode: HTTP: redirect to HTTPS, HSTS: on'); - const sslifyRouter = routeSslify(config.webServer); - sslifyRouter && app.use(sslifyRouter); + app.use('*', (req, res, next) => { + if (providers.healthCheck.ready) { + return next(); } + return res.send('Service not ready.'); + }); + // See docs/configuration.md for all this + if (config?.containers?.deployment) { + debug('Container deployment: HTTP: listening, HSTS: on'); + app.use(routeHsts); + } else if (config?.containers?.docker) { + debug('Docker image: HTTP: listening, HSTS: off'); + } else if (config.webServer.allowHttp) { + debug('development mode: HTTP: listening, HSTS: off'); + } else { + debug('non-container production mode: HTTP: redirect to HTTPS, HSTS: on'); + const sslifyRouter = routeSslify(config.webServer); + sslifyRouter && app.use(sslifyRouter); } if (!exception) { const kvConfig = { @@ -463,7 +437,7 @@ export default async function initialize( try { const keyVaultClient = keyVault(kvConfig); keyEncryptionKeyResolver = keyVaultResolver(keyVaultClient); - app && app.set('keyEncryptionKeyResolver', keyEncryptionKeyResolver); + app.set('keyEncryptionKeyResolver', keyEncryptionKeyResolver); providers.keyEncryptionKeyResolver = keyEncryptionKeyResolver; debug('configuration secrets resolved'); } catch (noKeyVault) { @@ -475,7 +449,7 @@ export default async function initialize( } } try { - await initializeAsync(executionEnvironment, providers, rootdir, config); + await initializeAsync(app, express, rootdir, config); } catch (initializeError) { console.dir(initializeError); debug(`Initialization failure: ${initializeError}`); @@ -484,9 +458,7 @@ export default async function initialize( } const hasCustomRoutes = !!applicationProfile.customRoutes; try { - if (app) { - await middlewareIndex(app, express, providers, config, rootdir, hasCustomRoutes, exception); - } + await middlewareIndex(app, express, config, rootdir, hasCustomRoutes, exception); } catch (middlewareError) { exception = middlewareError; } @@ -494,12 +466,13 @@ export default async function initialize( if (!exception) { if (hasCustomRoutes) { await applicationProfile.customRoutes(); - } else if (app) { + } else { app.use('/', expressRoutes); } } else { console.error(exception); - const crash = (error: Error) => { + const appInsightsClient = providers.insights; + const crash = (error) => { return () => { debug('App crashed because of an initialization error.'); console.log(error.message); @@ -509,15 +482,15 @@ export default async function initialize( process.exit(1); }; }; - if (insights) { - insights.trackException({ + if (appInsightsClient) { + appInsightsClient.trackException({ exception, properties: { info: 'App crashed while initializing', }, }); try { - insights.flush({ isAppCrashing: true, callback: crash(exception) }); + appInsightsClient.flush({ isAppCrashing: true, callback: crash(exception) }); } catch (sendError) { console.dir(sendError); crash(exception)(); @@ -527,24 +500,10 @@ export default async function initialize( } } await ErrorRoutes(app, exception); - if (config?.debug?.breakConsoleEveryMinute === true) { - const isNowDebugging = Debug.enabled('now'); - const everyMinute = () => { - const display = new Date().toISOString().substring(0, 19).replace('T', ' '); - if (isNowDebugging) { - nowDebug(display); - } else { - console.log(); - console.log(display); - } - }; - everyMinute(); - setInterval(everyMinute, 60000); - } - return executionEnvironment; + return app; } -function createGraphProvider(providers: IProviders, config: SiteConfiguration): Promise { +function createGraphProvider(providers: IProviders, config: any): Promise { return new Promise((resolve, reject) => { // The graph provider is optional. A graph provider can connect to a // corporate directory to validate or lookup employees and other @@ -642,10 +601,7 @@ async function connectRedis( return redisClient; } -async function createMailAddressProvider( - config: SiteConfiguration, - providers: IProviders -): Promise { +async function createMailAddressProvider(config: any, providers: IProviders): Promise { const options = { config: config, providers: providers, @@ -653,13 +609,7 @@ async function createMailAddressProvider( return createMailAddressProviderInstance(options); } -async function dynamicStartup( - executionEnvironment: ExecutionEnvironment, - config: SiteConfiguration, - providers: IProviders, - rootdir: string, - stage?: string -) { +async function dynamicStartup(config: any, providers: IProviders, rootdir: string, stage?: string) { const p = config?.startup?.path; if (p) { try { @@ -675,7 +625,6 @@ async function dynamicStartup( } const promise = (entrypoint as CompanyStartupEntrypoint).call( null, - executionEnvironment, config, providers, rootdir @@ -683,9 +632,6 @@ async function dynamicStartup( await promise; debug(`company-specific ${stage || 'startup'} complete (${p})`); } catch (dynamicLoadError) { - if (dynamicLoadError.stack) { - console.error(dynamicLoadError.stack); - } throw new Error(`config.startup.path=${p} could not successfully load: ${dynamicLoadError}`); } } diff --git a/middleware/jsonError.ts b/middleware/jsonError.ts index a8f40058d..48cdd1bc9 100644 --- a/middleware/jsonError.ts +++ b/middleware/jsonError.ts @@ -3,22 +3,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - -import { ReposAppRequest } from '../interfaces'; - interface IErrorJson extends Error { json?: boolean; statusCode?: string | number; } -export function json404(req: ReposAppRequest, res: Response, next: NextFunction) { +export function json404(req, res, next) { return next(jsonError('Endpoint not found', 404)); } -export function isJsonError(error: IErrorJson | string | Error, url: string) { - const errorAsAny = error as any; - return errorAsAny?.json === true || url?.startsWith('/api/'); +export function isJsonError(error: IErrorJson | string | Error) { + return error && error['json'] === true; } export function jsonError(error: IErrorJson | string | Error, statusCode?: number): IErrorJson { diff --git a/middleware/keyVault.ts b/middleware/keyVault.ts index 77c90a60b..f03629d5d 100644 --- a/middleware/keyVault.ts +++ b/middleware/keyVault.ts @@ -4,7 +4,7 @@ // import { ClientSecretCredential } from '@azure/identity'; -import { SecretClient } from '@azure/keyvault-secrets'; +import { KeyVaultSecret, SecretClient } from '@azure/keyvault-secrets'; export interface IKeyVaultConfigurationOptions { tenantId: string; diff --git a/middleware/business/links.ts b/middleware/links/index.ts similarity index 90% rename from middleware/business/links.ts rename to middleware/links/index.ts index 2ff7e2a68..b0f24d8e1 100644 --- a/middleware/business/links.ts +++ b/middleware/links/index.ts @@ -6,25 +6,19 @@ // Within the context, tries to resolve a link if it _can_. It does not force that a user is linked! import { IndividualContext } from '../../business/user'; -import { getProviders } from '../../lib/transitional'; -import { wrapError } from '../../lib/utils'; +import { getProviders } from '../../transitional'; +import { wrapError } from '../../utils'; import { ReposAppRequest, IReposError } from '../../interfaces'; -import { NextFunction, Response } from 'express'; export function RequireLinkMatchesGitHubSessionExceptPrefixedRoute(prefix: string) { return requireLinkMatchesGitHubSession.bind(null, prefix); } -export function RequireLinkMatchesGitHubSession(req: ReposAppRequest, res: Response, next: NextFunction) { +export function RequireLinkMatchesGitHubSession(req: ReposAppRequest, res, next) { return requireLinkMatchesGitHubSession(null, req, res, next); } -function requireLinkMatchesGitHubSession( - allowedPrefix: string, - req: ReposAppRequest, - res: Response, - next: NextFunction -) { +function requireLinkMatchesGitHubSession(allowedPrefix: string, req: ReposAppRequest, res, next) { // trying to be equivalent to legacy code in ./usernameConsistency (lightweight) const context = req.individualContext; if (!context) { @@ -73,7 +67,7 @@ function requireLinkMatchesGitHubSession( return next(securityError); } -export async function AddLinkToRequest(req, res: Response, next: NextFunction) { +export async function AddLinkToRequest(req, res, next) { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const contextName = req.individualContext ? 'Individual User Context' : 'API Context'; if (!activeContext) { diff --git a/middleware/locals.ts b/middleware/locals.ts index 59ed4772f..2fbe3c770 100644 --- a/middleware/locals.ts +++ b/middleware/locals.ts @@ -4,12 +4,11 @@ // import os from 'os'; -import { NextFunction, Response } from 'express'; - import { ReposAppRequest } from '../interfaces'; -import { getProviders } from '../lib/transitional'; -export default function (req: ReposAppRequest, res: Response, next: NextFunction) { +import { getProviders } from '../transitional'; + +export default function (req: ReposAppRequest, res, next) { const { config, viewServices } = getProviders(req); req.app.locals.correlationId = req.correlationId; req.app.locals.scrubbedUrl = req.scrubbedUrl; diff --git a/middleware/logger.ts b/middleware/logger.ts index 7a3689a08..ef63838d3 100644 --- a/middleware/logger.ts +++ b/middleware/logger.ts @@ -6,7 +6,7 @@ import logger from 'morgan'; import { ReposAppRequest } from '../interfaces'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; const encryptionMetadataKey = '_ClientEncryptionMetadata2'; const piiFormat = diff --git a/middleware/lowercaser.ts b/middleware/lowercaser.ts index d4eecec20..7248e5427 100644 --- a/middleware/lowercaser.ts +++ b/middleware/lowercaser.ts @@ -3,12 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - -import { ReposAppRequest } from '../interfaces'; - export default function (params) { - return function (req: ReposAppRequest, res: Response, next: NextFunction) { + return function (req, res, next) { // lowercase parameters Object.getOwnPropertyNames(req.params).forEach((param) => { if (params.indexOf(param) > -1) { diff --git a/middleware/officeHyperlinks.ts b/middleware/officeHyperlinks.ts index 5a0d6daf3..e3e83bd96 100644 --- a/middleware/officeHyperlinks.ts +++ b/middleware/officeHyperlinks.ts @@ -5,8 +5,7 @@ // I no longer believe this file FYI... I don't think we need this any longer. -import { NextFunction, Response } from 'express'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; // Office uses a specialized pre-fetch to learn more about hyperlinks before // opening. As a result, if the Office user agent is in use, and the @@ -18,7 +17,7 @@ import { getProviders } from '../lib/transitional'; const GenericOfficeUserAgent = 'ms-office'; const WordUserAgent = 'Microsoft Office Word'; -export default function supportOfficeHyperlinks(req, res: Response, next: NextFunction) { +export default function supportOfficeHyperlinks(req, res, next) { const { insights } = getProviders(req); const userAgent = req.headers['user-agent']; const isAuthenticated = req.isAuthenticated ? req.isAuthenticated() : false; diff --git a/middleware/onboarding.ts b/middleware/onboarding.ts index 6a6b34535..225bbbe2b 100644 --- a/middleware/onboarding.ts +++ b/middleware/onboarding.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IProviders, IReposApplication, SiteConfiguration } from '../interfaces'; +import { IProviders } from '../interfaces'; // ---------------------------------------------------------------------------- // Onboarding helper @@ -14,7 +14,7 @@ import { IProviders, IReposApplication, SiteConfiguration } from '../interfaces' // rather a configuration/app initialization method just stored here to keep it // out of the way. // ---------------------------------------------------------------------------- -export default async function Onboard(app: IReposApplication, config: SiteConfiguration) { +export default async function Onboard(app, config) { const { operations } = app.settings.providers as IProviders; const onboardingOrganizations = config.github.organizations?.onboarding || []; for (const orgEntry of onboardingOrganizations) { diff --git a/middleware/passportConfig.ts b/middleware/passport-config.ts similarity index 96% rename from middleware/passportConfig.ts rename to middleware/passport-config.ts index 3f52f94a8..064eb605e 100644 --- a/middleware/passportConfig.ts +++ b/middleware/passport-config.ts @@ -3,9 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; import passport from 'passport'; - import { IKeyVaultSecretResolver } from '../lib/keyVaultResolver'; import getCompanySpecificDeployment from './companySpecificDeployment'; @@ -75,7 +73,7 @@ export default function (app: IReposApplication, config: SiteConfiguration) { passport.deserializeUser(serializer.deserialize(serializerOptions)); serializer.initialize(serializerOptions, app); - app.use((req: ReposAppRequest, res: Response, next: NextFunction) => { + app.use((req: ReposAppRequest, res, next) => { if (req?.insights?.commonProperties && config.authentication.scheme === 'aad' && req?.user?.azure?.oid) { req.insights.commonProperties.aadId = req.user.azure.oid; } diff --git a/middleware/passport-routes.ts b/middleware/passport-routes.ts index a0bb18142..642e332cc 100644 --- a/middleware/passport-routes.ts +++ b/middleware/passport-routes.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import type { Response, NextFunction } from 'express'; +import { Response, NextFunction } from 'express'; -import { redirectToReferrer, storeReferrer } from '../lib/utils'; -import { getProviders } from '../lib/transitional'; -import type { ReposAppRequest, IAppSession } from '../interfaces'; +import { redirectToReferrer, storeReferrer } from '../utils'; +import { getProviders } from '../transitional'; +import { ReposAppRequest, IAppSession } from '../interfaces'; import getCompanySpecificDeployment from './companySpecificDeployment'; import { attachAadPassportRoutes } from './passport/aadRoutes'; import { attachGitHubPassportRoutes } from './passport/githubRoutes'; @@ -228,7 +228,6 @@ export default function configurePassport(app, passport, config) { ? `Your ${config.brand.companyName} and GitHub accounts have been unlinked. You no longer have access to any ${config.brand.companyName} organizations, and you have been signed out of this portal.` : 'Goodbye', title: 'Goodbye', - clearLocalStorage: true, buttonText: unlinked ? 'Sign in to connect a new account' : 'Sign in', config: config.obfuscatedConfig, }); diff --git a/middleware/passport/aadRoutes.ts b/middleware/passport/aadRoutes.ts index 10fa64010..59780a355 100644 --- a/middleware/passport/aadRoutes.ts +++ b/middleware/passport/aadRoutes.ts @@ -5,22 +5,22 @@ import { NextFunction, Response } from 'express'; import { PassportStatic } from 'passport'; -import { type IReposApplication, type IReposError, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; -import { isCodespacesAuthenticating } from '../../lib/utils'; +import { IReposError, ReposAppRequest } from '../../interfaces'; +import { getProviders } from '../../transitional'; +import { isCodespacesAuthenticating } from '../../utils'; import { IPrimaryAuthenticationHelperMethods } from '../passport-routes'; import { aadStrategyUserPropertyName } from './aadStrategy'; const aadPassportStrategyName = 'azure-active-directory'; export function attachAadPassportRoutes( - app: IReposApplication, + app, config: any, passport: PassportStatic, helpers: IPrimaryAuthenticationHelperMethods ) { const signinPath = isCodespacesAuthenticating(config, 'aad') ? 'sign-in' : 'signin'; - app.get(`/${signinPath}`, function (req: ReposAppRequest, res: Response, next: NextFunction) { + app.get(`/${signinPath}`, function (req: ReposAppRequest, res, next) { if (req.isAuthenticated()) { const username = req.user?.azure?.username; if (username) { @@ -81,7 +81,7 @@ export function attachAadPassportRoutes( // links from apps that temporarily prevent sessions. Technically this seems to // impact Windows users who use Word to open links to the site. Collecting // telemetry for now. - app.get('/auth/azure/callback', (req: ReposAppRequest, res: Response, next: NextFunction) => { + app.get('/auth/azure/callback', (req: ReposAppRequest, res, next) => { const { insights } = getProviders(req); const isAuthenticated = req.isAuthenticated(); insights?.trackEvent({ diff --git a/middleware/passport/aadStrategy.ts b/middleware/passport/aadStrategy.ts index 9d1db1af8..25e894238 100644 --- a/middleware/passport/aadStrategy.ts +++ b/middleware/passport/aadStrategy.ts @@ -9,10 +9,10 @@ const debug = Debug.debug('startup'); import { AuthorizationCode } from 'simple-oauth2'; import { OIDCStrategy } from 'passport-azure-ad'; -import type { IProviders, IReposApplication, SiteConfiguration } from '../../interfaces'; +import { IProviders } from '../../interfaces'; import { GraphUserType } from '../../lib/graphProvider'; -import { getCodespacesHostname, isCodespacesAuthenticating } from '../../lib/utils'; +import { getCodespacesHostname, isCodespacesAuthenticating } from '../../utils'; export const aadStrategyName = 'azure-active-directory'; export const aadStrategyUserPropertyName = 'azure'; @@ -25,64 +25,19 @@ interface IAADUser { displayName: string; oid: string; username: string; - // oauthToken?: string; // we aren't using this, no need to store these + oauthToken?: string; } -/* cSpell:disable */ -type AadJwtJson = { - aio: string; - amr: string; - family_name: string; - given_name: string; - ipaddr: string; - name: string; - oid: string; - onprem_sid: string; - rh: string; - sub: string; - tid: string; - unique_name: string; - upn: string; - uti: string; - ver: string; -}; -/* cSpell:enable */ - -type AadResponseProfile = { - _json: AadJwtJson; - _raw: string; - displayName: string; - emails: undefined; - name: { - familyName: string; - givenName: string; - middleName: string; - }; - oid: string; - sub: string; - upn: string; -}; - -type AadBearerToken = { - access_token: string; - expireS_in: string; - expires_on: string; - ext_expires_in: string; - id_token: string; - refresh_token: string; - token_type: 'Bearer'; -}; - async function login( - app: IReposApplication, - config: SiteConfiguration, + app, + config, client: AuthorizationCode, - iss: string, - sub: string, - profile: AadResponseProfile, + iss, + sub, + profile, accessToken: string, refreshToken: string, - params: AadBearerToken + params ): Promise { const { graphProvider, insights } = app.settings.providers as IProviders; const oauthToken = JSON.stringify(params); @@ -100,7 +55,7 @@ async function login( displayName: impersonationResult.displayName, oid: impersonationResult.id, username: impersonationResult.userPrincipalName, - // oauthToken, + oauthToken, }, }; } @@ -120,21 +75,21 @@ async function login( displayName: profile.displayName, oid: profile.oid, username: profile.upn, - // oauthToken, + oauthToken, }, }; } function activeDirectorySubset( - app: IReposApplication, - config: SiteConfiguration, + app, + config, client: AuthorizationCode, - iss: string, - sub: string, - profile: AadResponseProfile, + iss, + sub, + profile, accessToken: string, refreshToken: string, - params: AadBearerToken, + params, done ) { login(app, config, client, iss, sub, profile, accessToken, refreshToken, params) @@ -146,9 +101,9 @@ function activeDirectorySubset( }); } -export default function createAADStrategy(app: IReposApplication, config: SiteConfiguration) { +export default function createAADStrategy(app, config) { const { redirectUrl, tenantId, clientId, clientSecret } = config.activeDirectory; - const codespaces = config?.github?.codespaces; + const codespaces = config?.github?.codespaces || {}; if (!clientId) { debug('No Azure Active Directory clientID configured, corporate authentication will be unavailable.'); return {}; diff --git a/middleware/passport/encryptionSerializer.ts b/middleware/passport/encryptionSerializer.ts index c35cfb106..b87cff659 100644 --- a/middleware/passport/encryptionSerializer.ts +++ b/middleware/passport/encryptionSerializer.ts @@ -4,7 +4,7 @@ // import { decryptEntityAsync, encryptEntityAsync, IEncryptionOptions } from '../../lib/encryption'; -import { wrapError } from '../../lib/utils'; +import { wrapError } from '../../utils'; import { LegacySerializer } from './serializer'; // NOTE TO DEVELOPERS: we are no longer using encrypted sessions at our company diff --git a/middleware/passport/githubRoutes.ts b/middleware/passport/githubRoutes.ts index 03f441ca7..07e0a287c 100644 --- a/middleware/passport/githubRoutes.ts +++ b/middleware/passport/githubRoutes.ts @@ -5,11 +5,10 @@ import { NextFunction, Response } from 'express'; import querystring from 'querystring'; -import { PassportStatic } from 'passport'; -import { IReposApplication, ReposAppRequest, SiteConfiguration } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; -import { isCodespacesAuthenticating } from '../../lib/utils'; +import { ReposAppRequest } from '../../interfaces'; +import { getProviders } from '../../transitional'; +import { isCodespacesAuthenticating } from '../../utils'; import { IAuthenticationHelperMethods } from '../passport-routes'; import { getGithubAppConfigurationOptions, @@ -20,9 +19,9 @@ import { } from '../passport/githubStrategy'; export function attachGitHubPassportRoutes( - app: IReposApplication, - config: SiteConfiguration, - passport: PassportStatic, + app, + config: any, + passport, helpers: IAuthenticationHelperMethods ) { const signinPath = isCodespacesAuthenticating(config, 'github') ? 'sign-in' : 'signin'; diff --git a/middleware/passport/githubStrategy.ts b/middleware/passport/githubStrategy.ts index fd056d788..ff98687dd 100644 --- a/middleware/passport/githubStrategy.ts +++ b/middleware/passport/githubStrategy.ts @@ -5,21 +5,10 @@ import { Strategy as GithubStrategy } from 'passport-github'; -import { - getCodespacesHostname, - isCodespacesAuthenticating, - isEnterpriseManagedUserLogin, -} from '../../lib/utils'; -import type { - IGitHubAccountDetails, - IProviders, - IReposApplication, - SiteConfiguration, -} from '../../interfaces'; -import type { ConfigGitHubCodespaces } from '../../config/github.codespaces.types'; +import { IGitHubAccountDetails, IProviders } from '../../interfaces'; +import { getCodespacesHostname, isCodespacesAuthenticating, isEnterpriseManagedUserLogin } from '../../utils'; import Debug from 'debug'; -import { ConfigGitHubOAuth2 } from '../../config/github.oauth2.types'; const debug = Debug.debug('startup'); export const githubStrategyName = 'github'; @@ -66,7 +55,7 @@ function impersonatedIdentityFromDetails( } function githubResponseToSubset( - app: IReposApplication, + app, modernAppInUse: boolean, accessToken: string, refreshToken: string, @@ -84,7 +73,7 @@ function githubResponseToSubset( } async function githubResponseToSubsetEx( - app: IReposApplication, + app, modernAppInUse: boolean, accessToken: string, refreshToken: string, @@ -153,7 +142,7 @@ function githubResponseToIncreasedScopeSubset( return done(null, subset); } -export function getGithubAppConfigurationOptions(config: SiteConfiguration) { +export function getGithubAppConfigurationOptions(config) { let legacyOAuthApp = config?.github?.oauth2?.clientId && config?.github?.oauth2?.clientSecret ? config.github.oauth2 : null; const customerFacingApp = @@ -179,9 +168,9 @@ export function getGithubAppConfigurationOptions(config: SiteConfiguration) { }; } -export default function createGithubStrategy(app: IReposApplication, config: SiteConfiguration) { +export default function createGithubStrategy(app, config) { const strategies = {}; - const codespaces = config?.github?.codespaces || ({} as ConfigGitHubCodespaces); + const codespaces = config?.github?.codespaces || {}; const { modernAppInUse, githubAppConfiguration, useIncreasedScopeLegacyAppIfNeeded } = getGithubAppConfigurationOptions(config); if (!githubAppConfiguration?.clientId) { @@ -194,7 +183,7 @@ export default function createGithubStrategy(app: IReposApplication, config: Sit const finalCallbackUrl = isCodespacesAuthenticating(config, 'github') && !codespaces?.block ? getCodespacesHostname(config) + redirectSuffix - : (githubAppConfiguration as ConfigGitHubOAuth2)?.callbackUrl; + : githubAppConfiguration.callbackUrl; let clientId = githubAppConfiguration.clientId; let clientSecret = githubAppConfiguration.clientSecret; let codespacesOverrideText = ''; diff --git a/middleware/rawBodyParser.ts b/middleware/rawBodyParser.ts index 1ef2e395a..984f9852e 100644 --- a/middleware/rawBodyParser.ts +++ b/middleware/rawBodyParser.ts @@ -3,11 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; import { ReposAppRequest } from '../interfaces'; -import { isWebhookIngestionEndpointEnabled } from '../lib/transitional'; +import { isWebhookIngestionEndpointEnabled } from '../transitional'; -export default function rawBodyParser(req: ReposAppRequest, res: Response, next: NextFunction) { +export default function rawBodyParser(req: ReposAppRequest, res, next) { if (!isWebhookIngestionEndpointEnabled(req)) { return next(); } diff --git a/middleware/react.ts b/middleware/react.ts index 8738e76fd..b797e1d76 100644 --- a/middleware/react.ts +++ b/middleware/react.ts @@ -3,15 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; +import { Response } from 'express'; import fs from 'fs'; import path from 'path'; import appPackage from '../package.json'; import { getStaticBlobCacheFallback } from '../lib/staticBlobCacheFallback'; -import { getProviders, splitSemiColonCommas } from '../lib/transitional'; -import type { ReposAppRequest, SiteConfiguration } from '../interfaces'; +import { getProviders, splitSemiColonCommas } from '../transitional'; +import { ReposAppRequest } from '../interfaces'; import { IndividualContext } from '../business/user'; const staticReactPackageNameKey = 'static-react-package-name'; @@ -31,44 +31,37 @@ type PackageJsonSubset = { flights?: Record; }; -type BasicFlightingOptions = { - enabled: boolean; -}; - type ContentOptions = { html: string; package: PackageJsonSubset; }; -type FlightingOptions = BasicFlightingOptions & - ContentOptions & { - divertEveryone?: boolean; - staticFlightIds?: Set; - flightName?: string; - }; +type FlightingOptions = ContentOptions & { + enabled: boolean; + divertEveryone: boolean; + staticFlightIds?: Set; + flightName: string; +}; export function injectReactClient() { const standardContent = getReactScriptsIndex(staticClientPackageName); - let flightingBasics: BasicFlightingOptions = null; let flightingOptions: FlightingOptions = null; - return function injectedRoute(req: ReposAppRequest, res: Response, next: NextFunction) { + return function injectedRoute(req: ReposAppRequest, res, next) { const { config } = getProviders(req); // special passthrough if (req.path.includes('/byClient')) { return next(); } if (!flightingOptions) { - flightingBasics = evaluateFlightConditions(req); - flightingOptions = flightingBasics as FlightingOptions; + flightingOptions = evaluateFlightConditions(req); } const activeContext = (req.individualContext || req.apiContext) as IndividualContext; - const flightEnabled = flightingBasics?.enabled === true; - const flightAvailable = flightEnabled && flightingOptions?.html; - const flightName = flightingOptions?.flightName; + const flightAvailable = flightingOptions.enabled && flightingOptions.html; + const flightName = flightAvailable ? flightingOptions.flightName : null; const userFlighted = - flightingOptions?.divertEveryone === true || + flightingOptions.divertEveryone === true || (activeContext?.corporateIdentity?.id && - flightingOptions?.staticFlightIds?.has(activeContext.corporateIdentity.id)); + flightingOptions.staticFlightIds?.has(activeContext.corporateIdentity.id)); const userFlightOverride = req.query.flight === '0' || req.query.flight === '1' ? req.query.flight : undefined; let inFlight = flightAvailable && (userFlighted || req.query.flight === '1'); @@ -148,7 +141,7 @@ export function injectReactClient() { }; } -function evaluateFlightConditions(req: ReposAppRequest): FlightingOptions | BasicFlightingOptions { +function evaluateFlightConditions(req: ReposAppRequest): FlightingOptions { const { config } = getProviders(req); if (config?.client?.flighting?.enabled === true && staticClientFlightingPackageName) { const options = getReactScriptsIndex(staticClientFlightingPackageName) as FlightingOptions; @@ -164,12 +157,9 @@ function evaluateFlightConditions(req: ReposAppRequest): FlightingOptions | Basi ); return options; } - return { - enabled: false, - }; } -function getUserClientFeatureFlags(config: SiteConfiguration, corporateId: string) { +function getUserClientFeatureFlags(config: any, corporateId: string) { const featureFlagList = config?.client?.flighting?.featureFlagUsers; if (featureFlagList && typeof featureFlagList === 'object') { const flights = []; diff --git a/middleware/scrubbedUrl.ts b/middleware/scrubbedUrl.ts index 1600724a8..0ed6f9496 100644 --- a/middleware/scrubbedUrl.ts +++ b/middleware/scrubbedUrl.ts @@ -3,12 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; -import { ReposAppRequest } from '../interfaces'; - // Scrub the incoming URL value(s) in the request, replacing tokens and other // secrets. -export default function (req: ReposAppRequest, res: Response, next: NextFunction) { +export default function (req, res, next) { let url = req.originalUrl || req.url; const secretKeys = ['code', 'token']; for (let i = 0; i < secretKeys.length; i++) { @@ -19,5 +16,5 @@ export default function (req: ReposAppRequest, res: Response, next: NextFunction } } req.scrubbedUrl = url; - return next(); + next(); } diff --git a/middleware/sslify.ts b/middleware/sslify.ts index 2b7a83dc5..4fd121d2d 100644 --- a/middleware/sslify.ts +++ b/middleware/sslify.ts @@ -4,7 +4,6 @@ // import sslify from 'express-sslify'; - import type { ConfigWebServer } from '../config/webServer.types'; export default function (webServerConfig: ConfigWebServer) { diff --git a/middleware/staticClientApp.ts b/middleware/staticClientApp.ts index 2cebc2dbe..14af5da60 100644 --- a/middleware/staticClientApp.ts +++ b/middleware/staticClientApp.ts @@ -8,13 +8,10 @@ import appPackage from '../package.json'; const packageVariableName = 'static-client-package-name'; const otherPackageVariableName = 'static-react-package-name'; -import type { IReposApplication } from '../interfaces'; -import type { ExpressWithStatic } from './types'; - import Debug from 'debug'; const debug = Debug.debug('startup'); -export function StaticClientApp(app: IReposApplication, express: ExpressWithStatic) { +export function StaticClientApp(app, express) { // Serve/host the static client app from the location reported by the private // NPM module for the Ember app. Assumes that the inclusion of the package // returns the path to host. diff --git a/middleware/staticClientApp2.ts b/middleware/staticClientApp2.ts index 73112124d..7fdc795bd 100644 --- a/middleware/staticClientApp2.ts +++ b/middleware/staticClientApp2.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { hasStaticReactClientApp } from '../lib/transitional'; +import { hasStaticReactClientApp } from '../transitional'; import appPackage from '../package.json'; @@ -16,7 +16,6 @@ const staticReactFlightingPackageNameKey = 'static-react-flight-package-name'; const staticClientFlightingPackageName = appPackage[staticReactFlightingPackageNameKey]; import Debug from 'debug'; -import { ExpressWithStatic } from './types'; const debug = Debug.debug('startup'); export type RuntimeConfigurationClient = { @@ -32,11 +31,7 @@ export type RootRuntimeConfigurationClient = { client?: RuntimeConfigurationClient; }; -export function StaticReactClientApp( - app: IReposApplication, - express: ExpressWithStatic, - config: SiteConfiguration -) { +export function StaticReactClientApp(app: IReposApplication, express, config: SiteConfiguration) { const clientRuntimeConfiguration: RuntimeConfigurationClient = {}; app.runtimeConfiguration.client = clientRuntimeConfiguration; diff --git a/middleware/staticSiteAssets.ts b/middleware/staticSiteAssets.ts index 5d56d4e50..155e0c41d 100644 --- a/middleware/staticSiteAssets.ts +++ b/middleware/staticSiteAssets.ts @@ -12,7 +12,7 @@ const debug = Debug.debug('startup'); import favicon from 'serve-favicon'; import path from 'path'; -import { CreateError } from '../lib/transitional'; +import { CreateError } from '../transitional'; const appRootPath = appRoot.toString(); diff --git a/middleware/supportMultipleAuthProviders.ts b/middleware/supportMultipleAuthProviders.ts index 0905cbab0..4cdb353a8 100644 --- a/middleware/supportMultipleAuthProviders.ts +++ b/middleware/supportMultipleAuthProviders.ts @@ -3,11 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { jsonError } from './jsonError'; import { IApiRequest } from './apiReposAuth'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; // We have made a decision to not use Passport for the API routes, which is why this // performs some passport-like functionality... @@ -26,7 +24,7 @@ export default function returnCombinedMiddleware(supportedProviders) { if (totalProviders <= 0) { throw new Error('supportedProviders must provide at least one provider to use for auth'); } - return function middleware(req: IApiRequest, res: Response, next: NextFunction) { + return function middleware(req: IApiRequest, res, next) { const { insights } = getProviders(req); let i = 0; let currentProvider = supportedProviders[i]; diff --git a/package-lock.json b/package-lock.json index 5e48390e4..911fbbe64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "opensource-management-portal", "version": "7.1.0", - "lockfileVersion": 3, + "lockfileVersion": 2, "requires": true, "packages": { "": { @@ -9,22 +9,21 @@ "version": "7.1.0", "license": "MIT", "dependencies": { - "@azure/cosmos": "4.0.0", + "@azure/cosmos": "3.17.3", "@azure/data-tables": "13.2.2", - "@azure/identity": "4.0.0", + "@azure/identity": "3.2.2", "@azure/keyvault-secrets": "4.7.0", - "@azure/service-bus": "7.9.3", - "@azure/storage-blob": "12.17.0", - "@azure/storage-queue": "12.16.0", - "@octokit/auth-app": "6.0.3", - "@octokit/plugin-paginate-graphql": "4.0.0", - "@octokit/request": "8.1.6", - "@octokit/rest": "20.0.2", - "@primer/octicons": "19.8.0", + "@azure/service-bus": "7.9.0", + "@azure/storage-blob": "12.14.0", + "@azure/storage-queue": "12.14.0", + "@octokit/auth-app": "4.0.13", + "@octokit/plugin-paginate-graphql": "2.0.1", + "@octokit/request": "6.2.5", + "@octokit/rest": "19.0.11", "app-root-path": "3.1.0", - "applicationinsights": "2.9.2", + "applicationinsights": "2.7.0", "async-prompt": "1.0.1", - "axios": "1.6.5", + "axios": "1.4.0", "basic-auth": "2.0.1", "body-parser": "1.20.2", "color-contrast-checker": "2.1.0", @@ -35,7 +34,7 @@ "deepmerge": "4.3.1", "dotenv": "16.3.1", "express": "4.18.2", - "express-async-handler": "1.2.0", + "express-async-handler": "1.1.4", "express-session": "1.17.3", "express-sslify": "1.2.0", "file-size": "1.0.0", @@ -44,93 +43,83 @@ "js-yaml": "4.1.0", "json-2-csv": "^3.18.0", "jsonc": "2.0.0", - "jsonwebtoken": "9.0.2", - "jwks-rsa": "3.1.0", + "jsonwebtoken": "9.0.1", + "jwks-rsa": "3.0.1", "language-map": "1.5.0", "lodash": "4.17.21", - "luxon": "3.4.4", + "luxon": "3.3.0", "memory-cache": "0.2.0", - "moment": "2.30.1", + "moment": "2.29.4", "morgan": "1.10.0", "node-jose": "2.2.0", - "nodemailer": "6.9.8", + "nodemailer": "6.9.4", "object-path": "0.11.8", - "passport": "0.7.0", + "octicons": "5.0.1", + "passport": "0.6.0", "passport-azure-ad": "4.3.5", "passport-github": "1.1.0", - "pg": "8.11.3", + "pg": "8.11.0", "pg-escape": "0.2.0", "pug": "3.0.2", "pug-load": "3.0.0", "recursive-readdir": "2.2.3", - "redis": "4.6.12", + "redis": "4.6.8", "secure-compare": "3.0.1", - "semver": "7.5.4", + "semver": "7.5.1", "serve-favicon": "2.5.0", "simple-oauth2": "5.0.0", "throat": "6.0.2", "tmp-promise": "3.0.3", - "validator": "13.11.0", + "validator": "13.9.0", "walk-back": "5.1.0" }, "devDependencies": { - "@types/cors": "2.8.17", - "@types/debug": "4.1.12", - "@types/express": "4.17.21", - "@types/express-session": "1.17.10", - "@types/jest": "29.5.11", - "@types/lodash": "4.14.202", - "@types/luxon": "3.4.0", - "@types/memory-cache": "0.2.5", - "@types/morgan": "1.9.9", - "@types/node": "20.11.0", - "@types/node-jose": "1.1.13", - "@types/object-path": "0.11.4", - "@types/passport": "1.0.16", - "@types/passport-azure-ad": "4.3.5", - "@types/passport-github": "1.1.12", - "@types/pg": "8.10.9", - "@types/pug": "2.0.10", - "@types/recursive-readdir": "2.2.4", - "@types/semver": "7.5.6", - "@types/simple-oauth2": "5.0.7", - "@types/validator": "13.11.8", - "@typescript-eslint/eslint-plugin": "6.18.1", - "@typescript-eslint/parser": "6.18.1", - "cspell": "8.3.2", - "eslint": "8.56.0", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-n": "16.6.2", - "eslint-plugin-prettier": "5.1.3", + "@types/debug": "4.1.7", + "@types/express": "4.17.17", + "@types/express-session": "1.17.7", + "@types/jest": "29.5.1", + "@types/lodash": "4.14.194", + "@types/luxon": "3.3.0", + "@types/memory-cache": "0.2.2", + "@types/morgan": "1.9.4", + "@types/node": "20.4.2", + "@types/node-jose": "1.1.10", + "@types/object-path": "0.11.1", + "@types/passport": "1.0.12", + "@types/passport-azure-ad": "4.3.1", + "@types/passport-github": "1.1.7", + "@types/pg": "8.10.1", + "@types/pug": "2.0.6", + "@types/recursive-readdir": "2.2.1", + "@types/semver": "7.5.0", + "@types/simple-oauth2": "5.0.4", + "@types/validator": "13.7.17", + "@typescript-eslint/eslint-plugin": "5.59.7", + "@typescript-eslint/parser": "5.59.7", + "cspell": "6.31.1", + "eslint": "8.41.0", + "eslint-config-prettier": "8.8.0", + "eslint-plugin-n": "16.0.0", + "eslint-plugin-prettier": "4.2.1", "husky": "8.0.3", - "jest": "29.7.0", + "jest": "29.5.0", "jest-junit": "16.0.0", - "lint-staged": "15.2.0", - "markdownlint-cli2": "0.12.0", - "prettier": "3.1.1", - "ts-jest": "29.1.1", - "ts-node": "10.9.2", + "lint-staged": "13.2.2", + "markdownlint-cli2": "0.7.1", + "prettier": "2.8.8", + "ts-jest": "29.1.0", + "ts-node": "10.9.1", "ts-prune": "0.10.3", - "typescript": "5.3.3" + "typescript": "5.0.4" }, "engines": { - "node": ">=18" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=16" } }, "node_modules/@ampproject/remapping": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -140,20 +129,18 @@ } }, "node_modules/@azure/abort-controller": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", - "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", + "version": "1.0.4", + "license": "MIT", "dependencies": { - "tslib": "^2.2.0" + "tslib": "^2.0.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=8.0.0" } }, "node_modules/@azure/core-amqp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@azure/core-amqp/-/core-amqp-4.1.0.tgz", - "integrity": "sha512-tjnviDypSAgjGBZCPw+sH7vDWz27N+z0xtQewp7+xH17/eb67VH4sApl3XHuxVBro6Y6pOfxCDpqFenOoGWz6Q==", + "version": "3.3.0", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -161,6 +148,7 @@ "@azure/logger": "^1.0.0", "buffer": "^6.0.0", "events": "^3.0.0", + "jssha": "^3.1.0", "process": "^0.11.10", "rhea": "^3.0.0", "rhea-promise": "^3.0.0", @@ -168,67 +156,57 @@ "util": "^0.12.1" }, "engines": { - "node": ">=18.0.0" + "node": ">=14.0.0" } }, - "node_modules/@azure/core-auth": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.5.0.tgz", - "integrity": "sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw==", + "node_modules/@azure/core-amqp/node_modules/@azure/core-util": { + "version": "1.3.2", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-util": "^1.1.0", "tslib": "^2.2.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@azure/core-client": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.7.3.tgz", - "integrity": "sha512-kleJ1iUTxcO32Y06dH9Pfi9K4U+Tlb111WXEnbt7R/ne+NLRwppZiTGJuTD5VVoxTMK5NTbEtm5t2vcdNCFe2g==", + "node_modules/@azure/core-asynciterator-polyfill": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.4.0", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.4.0", - "@azure/core-rest-pipeline": "^1.9.1", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=12.0.0" } }, - "node_modules/@azure/core-http": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.4.tgz", - "integrity": "sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ==", + "node_modules/@azure/core-client": { + "version": "1.5.0", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", + "@azure/core-asynciterator-polyfill": "^1.0.0", "@azure/core-auth": "^1.3.0", + "@azure/core-rest-pipeline": "^1.5.0", "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" + "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/core-http-compat": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-1.3.0.tgz", - "integrity": "sha512-ZN9avruqbQ5TxopzG3ih3KRy52n8OAbitX3fnZT5go4hzu0J+KVPSzkL+Wt3hpJpdG8WIfg1sBD1tWkgUdEpBA==", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.4", "@azure/core-client": "^1.3.0", @@ -238,36 +216,22 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/core-http/node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", - "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", - "dependencies": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/core-lro": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.5.4.tgz", - "integrity": "sha512-3GJiMVH7/10bulzOKGrrLeG/uCBH/9VtxqaMcB9lIqAeamI/xYQSHJL/KcsLDuH+yTjYpro/u6D/MuRe4dN70Q==", + "version": "2.2.4", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-util": "^1.2.0", + "@azure/core-tracing": "1.0.0-preview.13", "@azure/logger": "^1.0.0", "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/core-paging": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.5.0.tgz", - "integrity": "sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==", + "license": "MIT", "dependencies": { "tslib": "^2.2.0" }, @@ -276,28 +240,39 @@ } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.13.0.tgz", - "integrity": "sha512-a62aP/wppgmnfIkJLfcB4ssPBcH94WzrzPVJ3tlJt050zX4lfmtnvy95D3igDo3f31StO+9BgPrzvkj4aOxnoA==", + "version": "1.10.1", + "license": "MIT", "dependencies": { - "@azure/abort-controller": "^1.1.0", + "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.4.0", "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.3.0", + "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", + "form-data": "^4.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { "tslib": "^2.2.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "version": "1.0.0-preview.13", + "license": "MIT", "dependencies": { + "@opentelemetry/api": "^1.0.1", "tslib": "^2.2.0" }, "engines": { @@ -305,23 +280,21 @@ } }, "node_modules/@azure/core-util": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.6.1.tgz", - "integrity": "sha512-h5taHeySlsV9qxuK64KZxy4iln1BtMYlNt5jbuEFN3UFSAd1EwKg/Gjl5a6tZ/W8t6li3xPnutOx7zbDyXnPmQ==", + "version": "1.2.0", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", "tslib": "^2.2.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=14.0.0" } }, "node_modules/@azure/core-xml": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.4.tgz", - "integrity": "sha512-B1xI79Ur/u+KR69fGTcsMNj8KDjBSqAy0Ys6Byy4Qm1CqoUy7gCT5A7Pej0EBWRskuH6bpCwrAnosfmQEalkcg==", + "version": "1.3.3", + "license": "MIT", "dependencies": { - "fast-xml-parser": "^4.2.4", + "fast-xml-parser": "^4.0.8", "tslib": "^2.2.0" }, "engines": { @@ -329,9 +302,8 @@ } }, "node_modules/@azure/cosmos": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.0.0.tgz", - "integrity": "sha512-/Z27p1+FTkmjmm8jk90zi/HrczPHw2t8WecFnsnTe4xGocWl0Z4clP0YlLUTJPhRLWYa5upwD9rMvKJkS1f1kg==", + "version": "3.17.3", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -351,10 +323,19 @@ "node": ">=14.0.0" } }, + "node_modules/@azure/cosmos/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/data-tables": { "version": "13.2.2", - "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-13.2.2.tgz", - "integrity": "sha512-Dq2Aq0mMMF0BPzYQKdBY/OtO7VemP/foh6z+mJpUO1hRL+65C1rGQUJf20LJHotSyU8wHb4HJzOs+Z50GXSy1w==", + "license": "MIT", "dependencies": { "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", @@ -370,34 +351,54 @@ "node": ">=14.0.0" } }, + "node_modules/@azure/data-tables/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/identity": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.0.0.tgz", - "integrity": "sha512-gtPYxIL0kI39Dw4t3HvlbfhOdXqKD2MqDgynlklF0j728j51dcKgRo6FLX0QzpBw/1gGfLxjMXqq3nKOSQ2lmA==", + "version": "3.2.2", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.5.0", + "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.4.0", "@azure/core-rest-pipeline": "^1.1.0", "@azure/core-tracing": "^1.0.0", "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^3.5.0", - "@azure/msal-node": "^2.5.1", + "@azure/msal-browser": "^2.32.2", + "@azure/msal-common": "^9.0.2", + "@azure/msal-node": "^1.14.6", "events": "^3.0.0", "jws": "^4.0.0", "open": "^8.0.0", "stoppable": "^1.1.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { "tslib": "^2.2.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/keyvault-secrets": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.7.0.tgz", - "integrity": "sha512-YvlFXRQ+SI5NT4GtSFbb6HGo6prW3yzDab8tr6vga2/SjDQew3wJsCAAr/xwZz6XshFXCYEX26CDKmPf+SJKJg==", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -415,72 +416,100 @@ "node": ">=14.0.0" } }, + "node_modules/@azure/keyvault-secrets/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/logger": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz", - "integrity": "sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==", + "version": "1.0.3", + "license": "MIT", "dependencies": { "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/msal-browser": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.7.0.tgz", - "integrity": "sha512-ktDB/Gf7UDgYBJOnoIlh70lxIo4e1/D2UgHuayB4RntN1IlusfTtIVH3k8NpJMdl+38tfTXIaUoR+qlr5voZEg==", + "version": "2.37.0", + "license": "MIT", "dependencies": { - "@azure/msal-common": "14.6.0" + "@azure/msal-common": "13.0.0" }, "engines": { "node": ">=0.8.0" } }, + "node_modules/@azure/msal-browser/node_modules/@azure/msal-common": { + "version": "13.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/@azure/msal-common": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.6.0.tgz", - "integrity": "sha512-AGusT/JvxdzJIYi5u0n97cmhd3pUT6UuI6rEkT5iDeT2FGcV0/EB8pk+dy6GLPpYg9vhDCuyoYrEZGd+2UeCCQ==", + "version": "9.1.1", + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-node": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.6.1.tgz", - "integrity": "sha512-wYwz83pWatTNWUCkTi3cAOXbchad5FnZz/pbZz7b8Z6FuEqohXcTtg6BLip9SmcjN6FlbwUdJIZYOof2v1Gnrg==", + "version": "1.17.2", + "license": "MIT", "dependencies": { - "@azure/msal-common": "14.6.0", + "@azure/msal-common": "13.0.0", "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, "engines": { - "node": ">=16" + "node": "10 || 12 || 14 || 16 || 18" + } + }, + "node_modules/@azure/msal-node/node_modules/@azure/msal-common": { + "version": "13.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8.0" } }, "node_modules/@azure/opentelemetry-instrumentation-azure-sdk": { - "version": "1.0.0-beta.5", - "resolved": "https://registry.npmjs.org/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz", - "integrity": "sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==", + "version": "1.0.0-beta.3", + "license": "MIT", "dependencies": { "@azure/core-tracing": "^1.0.0", "@azure/logger": "^1.0.0", - "@opentelemetry/api": "^1.4.1", - "@opentelemetry/core": "^1.15.2", - "@opentelemetry/instrumentation": "^0.41.2", + "@opentelemetry/api": "^1.4.0", + "@opentelemetry/core": "^1.9.0", + "@opentelemetry/instrumentation": "^0.35.0", "tslib": "^2.2.0" }, "engines": { "node": ">=14.0.0" } }, + "node_modules/@azure/opentelemetry-instrumentation-azure-sdk/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/service-bus": { - "version": "7.9.3", - "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.9.3.tgz", - "integrity": "sha512-6g37YpVTzRHI75BkYPiB4zqbYhQHM1Jvd+sNfRCbXeRW5FLsWoXgFVTw3Jv5kkMMX1pUNtrkaQhEoeTwtm5v3w==", + "version": "7.9.0", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-amqp": "^4.1.0", + "@azure/core-amqp": "^3.3.0", "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", "@azure/core-paging": "^1.4.0", @@ -499,13 +528,33 @@ "tslib": "^2.2.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=14.0.0" + } + }, + "node_modules/@azure/service-bus/node_modules/@azure/core-tracing": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/service-bus/node_modules/@azure/core-util": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@azure/storage-blob": { - "version": "12.17.0", - "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.17.0.tgz", - "integrity": "sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==", + "version": "12.14.0", + "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^3.0.0", @@ -520,22 +569,44 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/storage-blob/node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", - "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "node_modules/@azure/storage-blob/node_modules/@azure/core-http": { + "version": "3.0.1", + "license": "MIT", "dependencies": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", + "@azure/logger": "^1.0.0", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.5.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" + } + }, + "node_modules/@azure/storage-blob/node_modules/xml2js": { + "version": "0.5.0", + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" } }, "node_modules/@azure/storage-queue": { - "version": "12.16.0", - "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.16.0.tgz", - "integrity": "sha512-HzwzMsNAh2PwLtx9WfXndj9elUr6duDFak5CjM6BxdWhLqf37VywPCWmEzjxuFfrq30c1T34+MjMXnN6YgqRUw==", + "version": "12.14.0", + "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.14.0.tgz", + "integrity": "sha512-1j6uxhzCcbEDVPOTNWIJ5CsLzOAU5U/bXgGZeT25fy6IghFTC1JlPGALez2CWJ9fBVj6AmSnsiBXL/77iXhSpg==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^3.0.0", @@ -548,117 +619,79 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/storage-queue/node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", - "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "node_modules/@azure/storage-queue/node_modules/@azure/core-http": { + "version": "3.0.1", + "license": "MIT", "dependencies": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", + "@azure/logger": "^1.0.0", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.5.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, + "node_modules/@azure/storage-queue/node_modules/xml2js": { + "version": "0.5.0", + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" + "node": ">=4.0.0" } }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/code-frame": { + "version": "7.21.4", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/highlight": "^7.18.6" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.21.7", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", - "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "version": "7.21.8", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.7", - "@babel/parser": "^7.23.6", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6", - "convert-source-map": "^2.0.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helpers": "^7.21.5", + "@babel/parser": "^7.21.8", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", + "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" + "json5": "^2.2.2", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -668,22 +701,25 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "6.3.0", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.21.5", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.6", + "@babel/types": "^7.21.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -693,190 +729,176 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.21.5", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.21.5", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", "lru-cache": "^5.1.1", - "semver": "^6.3.1" + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "6.3.0", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@babel/helper-environment-visitor": { - "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==", + "version": "7.21.5", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "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==", + "version": "7.21.0", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.18.6", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.21.4", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.21.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.21.5", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-simple-access": "^7.21.5", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.21.5", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.21.5", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "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==", + "version": "7.18.6", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.21.5", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "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==", + "version": "7.19.1", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.21.0", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", - "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", + "version": "7.21.5", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.18.6", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, "engines": { @@ -885,9 +907,8 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -897,9 +918,8 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -909,29 +929,39 @@ "node": ">=4" } }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -940,9 +970,8 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "version": "7.21.8", + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -952,9 +981,8 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -964,9 +992,8 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -976,9 +1003,8 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -988,9 +1014,8 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1000,9 +1025,8 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1011,12 +1035,11 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "version": "7.21.4", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1027,9 +1050,8 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1039,9 +1061,8 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1051,9 +1072,8 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1063,9 +1083,8 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1075,9 +1094,8 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1087,9 +1105,8 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1099,9 +1116,8 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1113,12 +1129,11 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "version": "7.21.4", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1128,34 +1143,32 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.20.7", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", - "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@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.23.6", - "@babel/types": "^7.23.6", - "debug": "^4.3.1", + "version": "7.21.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", + "debug": "^4.1.0", "globals": "^11.1.0" }, "engines": { @@ -1164,20 +1177,18 @@ }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.21.5", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1186,443 +1197,342 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/cspell-bundled-dicts": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.3.2.tgz", - "integrity": "sha512-3ubOgz1/MDixJbq//0rQ2omB3cSdhVJDviERZeiREGz4HOq84aaK1Fqbw5SjNZHvhpoq+AYXm6kJbIAH8YhKgg==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { - "@cspell/dict-ada": "^4.0.2", - "@cspell/dict-aws": "^4.0.1", - "@cspell/dict-bash": "^4.1.3", - "@cspell/dict-companies": "^3.0.29", - "@cspell/dict-cpp": "^5.0.10", - "@cspell/dict-cryptocurrencies": "^5.0.0", + "@cspell/dict-ada": "^4.0.1", + "@cspell/dict-aws": "^3.0.0", + "@cspell/dict-bash": "^4.1.1", + "@cspell/dict-companies": "^3.0.9", + "@cspell/dict-cpp": "^5.0.2", + "@cspell/dict-cryptocurrencies": "^3.0.1", "@cspell/dict-csharp": "^4.0.2", - "@cspell/dict-css": "^4.0.12", - "@cspell/dict-dart": "^2.0.3", - "@cspell/dict-django": "^4.1.0", - "@cspell/dict-docker": "^1.1.7", + "@cspell/dict-css": "^4.0.5", + "@cspell/dict-dart": "^2.0.2", + "@cspell/dict-django": "^4.0.2", + "@cspell/dict-docker": "^1.1.6", "@cspell/dict-dotnet": "^5.0.0", - "@cspell/dict-elixir": "^4.0.3", - "@cspell/dict-en_us": "^4.3.13", - "@cspell/dict-en-common-misspellings": "^2.0.0", + "@cspell/dict-elixir": "^4.0.2", + "@cspell/dict-en_us": "^4.3.2", + "@cspell/dict-en-common-misspellings": "^1.0.2", "@cspell/dict-en-gb": "1.1.33", - "@cspell/dict-filetypes": "^3.0.3", - "@cspell/dict-fonts": "^4.0.0", - "@cspell/dict-fsharp": "^1.0.1", + "@cspell/dict-filetypes": "^3.0.0", + "@cspell/dict-fonts": "^3.0.1", "@cspell/dict-fullstack": "^3.1.5", "@cspell/dict-gaming-terms": "^1.0.4", - "@cspell/dict-git": "^3.0.0", - "@cspell/dict-golang": "^6.0.5", + "@cspell/dict-git": "^2.0.0", + "@cspell/dict-golang": "^6.0.1", "@cspell/dict-haskell": "^4.0.1", - "@cspell/dict-html": "^4.0.5", + "@cspell/dict-html": "^4.0.3", "@cspell/dict-html-symbol-entities": "^4.0.0", - "@cspell/dict-java": "^5.0.6", - "@cspell/dict-k8s": "^1.0.2", + "@cspell/dict-java": "^5.0.5", + "@cspell/dict-k8s": "^1.0.1", "@cspell/dict-latex": "^4.0.0", - "@cspell/dict-lorem-ipsum": "^4.0.0", - "@cspell/dict-lua": "^4.0.3", - "@cspell/dict-makefile": "^1.0.0", - "@cspell/dict-node": "^4.0.3", - "@cspell/dict-npm": "^5.0.14", - "@cspell/dict-php": "^4.0.5", - "@cspell/dict-powershell": "^5.0.3", - "@cspell/dict-public-licenses": "^2.0.5", - "@cspell/dict-python": "^4.1.11", + "@cspell/dict-lorem-ipsum": "^3.0.0", + "@cspell/dict-lua": "^4.0.1", + "@cspell/dict-node": "^4.0.2", + "@cspell/dict-npm": "^5.0.5", + "@cspell/dict-php": "^4.0.1", + "@cspell/dict-powershell": "^5.0.1", + "@cspell/dict-public-licenses": "^2.0.2", + "@cspell/dict-python": "^4.0.2", "@cspell/dict-r": "^2.0.1", - "@cspell/dict-ruby": "^5.0.2", + "@cspell/dict-ruby": "^5.0.0", "@cspell/dict-rust": "^4.0.1", "@cspell/dict-scala": "^5.0.0", - "@cspell/dict-software-terms": "^3.3.15", - "@cspell/dict-sql": "^2.1.3", + "@cspell/dict-software-terms": "^3.1.6", + "@cspell/dict-sql": "^2.1.0", "@cspell/dict-svelte": "^1.0.2", "@cspell/dict-swift": "^2.0.1", - "@cspell/dict-typescript": "^3.1.2", + "@cspell/dict-typescript": "^3.1.1", "@cspell/dict-vue": "^3.0.0" }, "engines": { - "node": ">=18" - } - }, - "node_modules/@cspell/cspell-json-reporter": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.3.2.tgz", - "integrity": "sha512-gHSz4jXMJPcxx+lOGfXhHuoyenAWQ8PVA/atHFrWYKo1LzKTbpkEkrsDnlX8QNJubc3EMH63Uy+lOIaFDVyHiQ==", - "dev": true, - "dependencies": { - "@cspell/cspell-types": "8.3.2" - }, - "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/@cspell/cspell-pipe": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.3.2.tgz", - "integrity": "sha512-GZmDwvQGOjQi3IjD4k9xXeVTDANczksOsgVKb3v2QZk9mR4Qj8c6Uarjd4AgSiIhu/wBliJfzr5rWFJu4X2VfQ==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@cspell/cspell-resolver": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.3.2.tgz", - "integrity": "sha512-w2Tmb95bzdEz9L4W5qvsP5raZbyEzKL7N2ksU/+yh8NEJcTuExmAl/nMnb3aIk7m2b+kPHnMOcJuwfUMLmyv4A==", + "version": "6.31.1", "dev": true, - "dependencies": { - "global-directory": "^4.0.1" - }, + "license": "MIT", "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/@cspell/cspell-service-bus": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.3.2.tgz", - "integrity": "sha512-skTHNyVi74//W/O+f4IauDhm6twA9S2whkylonsIzPxEl4Pn3y2ZEMXNki/MWUwZfDIzKKSxlcREH61g7zCvhg==", + "version": "6.31.1", "dev": true, + "license": "MIT", "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/@cspell/cspell-types": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.3.2.tgz", - "integrity": "sha512-qS/gWd9ItOrN6ZX5pwC9lJjnBoyiAyhxYq0GUXuV892LQvwrBmECGk6KhsA1lPW7JJS7o57YTAS1jmXnmXMEpg==", + "version": "6.31.1", "dev": true, + "license": "MIT", "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/@cspell/dict-ada": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.0.2.tgz", - "integrity": "sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==", - "dev": true + "version": "4.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-aws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.1.tgz", - "integrity": "sha512-NXO+kTPQGqaaJKa4kO92NAXoqS+i99dQzf3/L1BxxWVSBS3/k1f3uhmqIh7Crb/n22W793lOm0D9x952BFga3Q==", - "dev": true + "version": "3.0.0", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-bash": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.1.3.tgz", - "integrity": "sha512-tOdI3QVJDbQSwPjUkOiQFhYcu2eedmX/PtEpVWg0aFps/r6AyjUQINtTgpqMYnYuq8O1QUIQqnpx21aovcgZCw==", - "dev": true + "version": "4.1.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-companies": { - "version": "3.0.31", - "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.0.31.tgz", - "integrity": "sha512-hKVpV/lcGKP4/DpEPS8P4osPvFH/YVLJaDn9cBIOH6/HSmL5LbFgJNKpMGaYRbhm2FEX56MKE3yn/MNeNYuesQ==", - "dev": true + "version": "3.0.10", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-cpp": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.1.1.tgz", - "integrity": "sha512-Qy9fNsR/5RcQ6G85gDKFjvzh0AdgAilLQeSXPtqY21Fx1kCjUqdVVJYMmHUREgcxH6ptAxtn5knTWU4PIhQtOw==", - "dev": true + "version": "5.0.3", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-cryptocurrencies": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.0.tgz", - "integrity": "sha512-Z4ARIw5+bvmShL+4ZrhDzGhnc9znaAGHOEMaB/GURdS/jdoreEDY34wdN0NtdLHDO5KO7GduZnZyqGdRoiSmYA==", - "dev": true + "version": "3.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-csharp": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.2.tgz", - "integrity": "sha512-1JMofhLK+4p4KairF75D3A924m5ERMgd1GvzhwK2geuYgd2ZKuGW72gvXpIV7aGf52E3Uu1kDXxxGAiZ5uVG7g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-css": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.12.tgz", - "integrity": "sha512-vGBgPM92MkHQF5/2jsWcnaahOZ+C6OE/fPvd5ScBP72oFY9tn5GLuomcyO0z8vWCr2e0nUSX1OGimPtcQAlvSw==", - "dev": true + "version": "4.0.6", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-dart": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.0.3.tgz", - "integrity": "sha512-cLkwo1KT5CJY5N5RJVHks2genFkNCl/WLfj+0fFjqNR+tk3tBI1LY7ldr9piCtSFSm4x9pO1x6IV3kRUY1lLiw==", - "dev": true - }, - "node_modules/@cspell/dict-data-science": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-1.0.11.tgz", - "integrity": "sha512-TaHAZRVe0Zlcc3C23StZqqbzC0NrodRwoSAc8dis+5qLeLLnOCtagYQeROQvDlcDg3X/VVEO9Whh4W/z4PAmYQ==", - "dev": true + "version": "2.0.2", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-django": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.0.tgz", - "integrity": "sha512-bKJ4gPyrf+1c78Z0Oc4trEB9MuhcB+Yg+uTTWsvhY6O2ncFYbB/LbEZfqhfmmuK/XJJixXfI1laF2zicyf+l0w==", - "dev": true + "version": "4.0.2", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-docker": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.7.tgz", - "integrity": "sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==", - "dev": true + "version": "1.1.6", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-dotnet": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-dotnet/-/dict-dotnet-5.0.0.tgz", - "integrity": "sha512-EOwGd533v47aP5QYV8GlSSKkmM9Eq8P3G/eBzSpH3Nl2+IneDOYOBLEUraHuiCtnOkNsz0xtZHArYhAB2bHWAw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-elixir": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-elixir/-/dict-elixir-4.0.3.tgz", - "integrity": "sha512-g+uKLWvOp9IEZvrIvBPTr/oaO6619uH/wyqypqvwpmnmpjcfi8+/hqZH8YNKt15oviK8k4CkINIqNhyndG9d9Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-en_us": { - "version": "4.3.13", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.13.tgz", - "integrity": "sha512-T6lHiGCjloGNE0d8CogF+efJZPCAP8zdzn+KnlI0Bmjaz5nvG2LTX7CXl1zkOl1nYYev0FuIk9WJ9YPVRjcFbQ==", - "dev": true + "version": "4.3.2", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-en-common-misspellings": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.0.tgz", - "integrity": "sha512-NOg8dlv37/YqLkCfBs5OXeJm/Wcfb/CzeOmOZJ2ZXRuxwsNuolb4TREUce0yAXRqMhawahY5TSDRJJBgKjBOdw==", - "dev": true + "version": "1.0.2", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-en-gb": { "version": "1.1.33", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz", - "integrity": "sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-filetypes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.3.tgz", - "integrity": "sha512-J9UP+qwwBLfOQ8Qg9tAsKtSY/WWmjj21uj6zXTI9hRLD1eG1uUOLcfVovAmtmVqUWziPSKMr87F6SXI3xmJXgw==", - "dev": true + "version": "3.0.0", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-fonts": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-fonts/-/dict-fonts-4.0.0.tgz", - "integrity": "sha512-t9V4GeN/m517UZn63kZPUYP3OQg5f0OBLSd3Md5CU3eH1IFogSvTzHHnz4Wqqbv8NNRiBZ3HfdY/pqREZ6br3Q==", - "dev": true - }, - "node_modules/@cspell/dict-fsharp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-fsharp/-/dict-fsharp-1.0.1.tgz", - "integrity": "sha512-23xyPcD+j+NnqOjRHgW3IU7Li912SX9wmeefcY0QxukbAxJ/vAN4rBpjSwwYZeQPAn3fxdfdNZs03fg+UM+4yQ==", - "dev": true + "version": "3.0.2", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-fullstack": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-fullstack/-/dict-fullstack-3.1.5.tgz", - "integrity": "sha512-6ppvo1dkXUZ3fbYn/wwzERxCa76RtDDl5Afzv2lijLoijGGUw5yYdLBKJnx8PJBGNLh829X352ftE7BElG4leA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-gaming-terms": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.0.5.tgz", - "integrity": "sha512-C3riccZDD3d9caJQQs1+MPfrUrQ+0KHdlj9iUR1QD92FgTOF6UxoBpvHUUZ9YSezslcmpFQK4xQQ5FUGS7uWfw==", - "dev": true + "version": "1.0.4", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-git": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.0.tgz", - "integrity": "sha512-simGS/lIiXbEaqJu9E2VPoYW1OTC2xrwPPXNXFMa2uo/50av56qOuaxDrZ5eH1LidFXwoc8HROCHYeKoNrDLSw==", - "dev": true + "version": "2.0.0", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-golang": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.5.tgz", - "integrity": "sha512-w4mEqGz4/wV+BBljLxduFNkMrd3rstBNDXmoX5kD4UTzIb4Sy0QybWCtg2iVT+R0KWiRRA56QKOvBsgXiddksA==", - "dev": true + "version": "6.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-haskell": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-haskell/-/dict-haskell-4.0.1.tgz", - "integrity": "sha512-uRrl65mGrOmwT7NxspB4xKXFUenNC7IikmpRZW8Uzqbqcu7ZRCUfstuVH7T1rmjRgRkjcIjE4PC11luDou4wEQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-html": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.5.tgz", - "integrity": "sha512-p0brEnRybzSSWi8sGbuVEf7jSTDmXPx7XhQUb5bgG6b54uj+Z0Qf0V2n8b/LWwIPJNd1GygaO9l8k3HTCy1h4w==", - "dev": true + "version": "4.0.3", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-html-symbol-entities": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.0.tgz", - "integrity": "sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-java": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-java/-/dict-java-5.0.6.tgz", - "integrity": "sha512-kdE4AHHHrixyZ5p6zyms1SLoYpaJarPxrz8Tveo6gddszBVVwIUZ+JkQE1bWNLK740GWzIXdkznpUfw1hP9nXw==", - "dev": true + "version": "5.0.5", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-k8s": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.2.tgz", - "integrity": "sha512-tLT7gZpNPnGa+IIFvK9SP1LrSpPpJ94a/DulzAPOb1Q2UBFwdpFd82UWhio0RNShduvKG/WiMZf/wGl98pn+VQ==", - "dev": true + "version": "1.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-latex": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-latex/-/dict-latex-4.0.0.tgz", - "integrity": "sha512-LPY4y6D5oI7D3d+5JMJHK/wxYTQa2lJMSNxps2JtuF8hbAnBQb3igoWEjEbIbRRH1XBM0X8dQqemnjQNCiAtxQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-lorem-ipsum": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.0.tgz", - "integrity": "sha512-1l3yjfNvMzZPibW8A7mQU4kTozwVZVw0AvFEdy+NcqtbxH+TvbSkNMqROOFWrkD2PjnKG0+Ea0tHI2Pi6Gchnw==", - "dev": true + "version": "3.0.0", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-lua": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-lua/-/dict-lua-4.0.3.tgz", - "integrity": "sha512-lDHKjsrrbqPaea13+G9s0rtXjMO06gPXPYRjRYawbNmo4E/e3XFfVzeci3OQDQNDmf2cPOwt9Ef5lu2lDmwfJg==", - "dev": true - }, - "node_modules/@cspell/dict-makefile": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-makefile/-/dict-makefile-1.0.0.tgz", - "integrity": "sha512-3W9tHPcSbJa6s0bcqWo6VisEDTSN5zOtDbnPabF7rbyjRpNo0uHXHRJQF8gAbFzoTzBBhgkTmrfSiuyQm7vBUQ==", - "dev": true + "version": "4.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-node": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-4.0.3.tgz", - "integrity": "sha512-sFlUNI5kOogy49KtPg8SMQYirDGIAoKBO3+cDLIwD4MLdsWy1q0upc7pzGht3mrjuyMiPRUV14Bb0rkVLrxOhg==", - "dev": true + "version": "4.0.2", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-npm": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.0.15.tgz", - "integrity": "sha512-sX0X5YWNW54F4baW7b5JJB6705OCBIZtUqjOghlJNORS5No7QY1IX1zc5FxNNu4gsaCZITAmfMi4ityXEsEThA==", - "dev": true + "version": "5.0.5", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-php": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.0.5.tgz", - "integrity": "sha512-9r8ao7Z/mH9Z8pSB7yLtyvcCJWw+/MnQpj7xGVYzIV7V2ZWDRjXZAMgteHMJ37m8oYz64q5d4tiipD300QSetQ==", - "dev": true + "version": "4.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-powershell": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-powershell/-/dict-powershell-5.0.3.tgz", - "integrity": "sha512-lEdzrcyau6mgzu1ie98GjOEegwVHvoaWtzQnm1ie4DyZgMr+N6D0Iyj1lzvtmt0snvsDFa5F2bsYzf3IMKcpcA==", - "dev": true + "version": "5.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-public-licenses": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.5.tgz", - "integrity": "sha512-91HK4dSRri/HqzAypHgduRMarJAleOX5NugoI8SjDLPzWYkwZ1ftuCXSk+fy8DLc3wK7iOaFcZAvbjmnLhVs4A==", - "dev": true + "version": "2.0.2", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-python": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.1.11.tgz", - "integrity": "sha512-XG+v3PumfzUW38huSbfT15Vqt3ihNb462ulfXifpQllPok5OWynhszCLCRQjQReV+dgz784ST4ggRxW452/kVg==", + "version": "4.0.4", "dev": true, - "dependencies": { - "@cspell/dict-data-science": "^1.0.11" - } + "license": "MIT" }, "node_modules/@cspell/dict-r": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-r/-/dict-r-2.0.1.tgz", - "integrity": "sha512-KCmKaeYMLm2Ip79mlYPc8p+B2uzwBp4KMkzeLd5E6jUlCL93Y5Nvq68wV5fRLDRTf7N1LvofkVFWfDcednFOgA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-ruby": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-ruby/-/dict-ruby-5.0.2.tgz", - "integrity": "sha512-cIh8KTjpldzFzKGgrqUX4bFyav5lC52hXDKo4LbRuMVncs3zg4hcSf4HtURY+f2AfEZzN6ZKzXafQpThq3dl2g==", - "dev": true + "version": "5.0.0", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-rust": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.2.tgz", - "integrity": "sha512-RhziKDrklzOntxAbY3AvNR58wnFGIo3YS8+dNeLY36GFuWOvXDHFStYw5Pod4f/VXbO/+1tXtywCC4zWfB2p1w==", - "dev": true + "version": "4.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-scala": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-scala/-/dict-scala-5.0.0.tgz", - "integrity": "sha512-ph0twaRoV+ylui022clEO1dZ35QbeEQaKTaV2sPOsdwIokABPIiK09oWwGK9qg7jRGQwVaRPEq0Vp+IG1GpqSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-software-terms": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-3.3.16.tgz", - "integrity": "sha512-ixorEP80LGxAU+ODVSn/CYIDjV0XAlZ2VrBu7CT+PwUFJ7h8o3JX1ywKB4qnt0hHru3JjWFtBoBThmZdrXnREQ==", - "dev": true + "version": "3.1.8", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-sql": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.1.3.tgz", - "integrity": "sha512-SEyTNKJrjqD6PAzZ9WpdSu6P7wgdNtGV2RV8Kpuw1x6bV+YsSptuClYG+JSdRExBTE6LwIe1bTklejUp3ZP8TQ==", - "dev": true + "version": "2.1.0", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-svelte": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-svelte/-/dict-svelte-1.0.2.tgz", - "integrity": "sha512-rPJmnn/GsDs0btNvrRBciOhngKV98yZ9SHmg8qI6HLS8hZKvcXc0LMsf9LLuMK1TmS2+WQFAan6qeqg6bBxL2Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-swift": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-swift/-/dict-swift-2.0.1.tgz", - "integrity": "sha512-gxrCMUOndOk7xZFmXNtkCEeroZRnS2VbeaIPiymGRHj5H+qfTAzAKxtv7jJbVA3YYvEzWcVE2oKDP4wcbhIERw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-typescript": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.1.2.tgz", - "integrity": "sha512-lcNOYWjLUvDZdLa0UMNd/LwfVdxhE9rKA+agZBGjL3lTA3uNvH7IUqSJM/IXhJoBpLLMVEOk8v1N9xi+vDuCdA==", - "dev": true + "version": "3.1.1", + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dict-vue": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-vue/-/dict-vue-3.0.0.tgz", - "integrity": "sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspell/dynamic-import": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.3.2.tgz", - "integrity": "sha512-4t0xM5luA3yQhar2xWvYK4wQSDB2r0u8XkpzzJqd57MnJXd7uIAxI0awGUrDXukadRaCo0tDIlMUBemH48SNVg==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { - "import-meta-resolve": "^4.0.0" + "import-meta-resolve": "^2.2.2" }, "engines": { - "node": ">=18.0" + "node": ">=14" } }, "node_modules/@cspell/strong-weak-map": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.3.2.tgz", - "integrity": "sha512-Mte/2000ap278kRYOUhiGWI7MNr1+A7WSWJmlcdP4CAH5SO20sZI3/cyZLjJJEyapdhK5vaP1L5J9sUcVDHd3A==", + "version": "6.31.1", "dev": true, + "license": "MIT", "engines": { - "node": ">=18" + "node": ">=14.6" } }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -1632,9 +1542,8 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1642,9 +1551,8 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -1656,23 +1564,21 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.5.1", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "2.0.3", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -1687,77 +1593,47 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.41.0", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@hapi/boom": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-10.0.1.tgz", - "integrity": "sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==", + "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^11.0.2" } }, "node_modules/@hapi/boom/node_modules/@hapi/hoek": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz", - "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==" + "version": "11.0.2", + "license": "BSD-3-Clause" }, "node_modules/@hapi/bourne": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-3.0.0.tgz", - "integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==" + "license": "BSD-3-Clause" }, "node_modules/@hapi/hoek": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-10.0.1.tgz", - "integrity": "sha512-CvlW7jmOhWzuqOqiJQ3rQVLMcREh0eel4IBnxDx2FAcK8g7qoJRQK4L1CPBASoCY6y8e6zuCy3f2g+HWdkzcMw==" + "license": "BSD-3-Clause" }, "node_modules/@hapi/topo": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@hapi/topo/node_modules/@hapi/hoek": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + "license": "BSD-3-Clause" }, "node_modules/@hapi/wreck": { "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-18.0.1.tgz", - "integrity": "sha512-OLHER70+rZxvDl75xq3xXOfd3e8XIvz8fWY0dqg92UvhZ29zo24vQgfqgHSYhB5ZiuFpSLeriOisAlxAo/1jWg==", + "license": "BSD-3-Clause", "dependencies": { "@hapi/boom": "^10.0.1", "@hapi/bourne": "^3.0.0", @@ -1765,51 +1641,26 @@ } }, "node_modules/@hapi/wreck/node_modules/@hapi/hoek": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz", - "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==" + "version": "11.0.2", + "license": "BSD-3-Clause" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.11.8", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -1819,85 +1670,14 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "version": "1.2.1", "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -1911,18 +1691,16 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -1933,9 +1711,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1946,9 +1723,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -1958,9 +1734,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -1973,9 +1748,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -1985,111 +1759,59 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/console/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -2105,160 +1827,84 @@ } } }, - "node_modules/@jest/core/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/core/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^29.7.0" + "jest-mock": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3" + "jest-get-type": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "^29.5.0", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -2266,13 +1912,13 @@ "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -2290,110 +1936,37 @@ } } }, - "node_modules/@jest/reporters/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@jest/schemas": { + "version": "29.4.3", "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/reporters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@jest/source-map": { + "version": "29.4.3", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/reporters/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -2402,14 +1975,13 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", + "@jest/test-result": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", + "jest-haste-map": "^29.5.0", "slash": "^3.0.0" }, "engines": { @@ -2417,22 +1989,21 @@ } }, "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -2442,75 +2013,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/transform/node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -2521,60 +2029,10 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2585,49 +2043,48 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.0", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "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==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.18", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "dev": true, + "license": "MIT" + }, "node_modules/@microsoft/applicationinsights-web-snippet": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-snippet/-/applicationinsights-web-snippet-1.0.1.tgz", - "integrity": "sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==" + "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2638,18 +2095,16 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2659,279 +2114,268 @@ } }, "node_modules/@octokit/auth-app": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.0.3.tgz", - "integrity": "sha512-9N7IlBAKEJR3tJgPSubCxIDYGXSdc+2xbkjYpk9nCyqREnH8qEMoMhiEB1WgoA9yTFp91El92XNXAi+AjuKnfw==", - "dependencies": { - "@octokit/auth-oauth-app": "^7.0.0", - "@octokit/auth-oauth-user": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", + "version": "4.0.13", + "license": "MIT", + "dependencies": { + "@octokit/auth-oauth-app": "^5.0.0", + "@octokit/auth-oauth-user": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", "deprecation": "^2.3.1", - "lru-cache": "^10.0.0", - "universal-github-app-jwt": "^1.1.2", + "lru-cache": "^9.0.0", + "universal-github-app-jwt": "^1.1.1", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" + } + }, + "node_modules/@octokit/auth-app/node_modules/lru-cache": { + "version": "9.1.1", + "license": "ISC", + "engines": { + "node": "14 || >=16.14" } }, "node_modules/@octokit/auth-oauth-app": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz", - "integrity": "sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg==", + "version": "5.0.5", + "license": "MIT", "dependencies": { - "@octokit/auth-oauth-device": "^6.0.0", - "@octokit/auth-oauth-user": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/types": "^12.0.0", + "@octokit/auth-oauth-device": "^4.0.0", + "@octokit/auth-oauth-user": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", "@types/btoa-lite": "^1.0.0", "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/auth-oauth-device": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.0.1.tgz", - "integrity": "sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw==", + "version": "4.0.4", + "license": "MIT", "dependencies": { - "@octokit/oauth-methods": "^4.0.0", - "@octokit/request": "^8.0.0", - "@octokit/types": "^12.0.0", + "@octokit/oauth-methods": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/auth-oauth-user": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.0.1.tgz", - "integrity": "sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw==", + "version": "2.1.1", + "license": "MIT", "dependencies": { - "@octokit/auth-oauth-device": "^6.0.0", - "@octokit/oauth-methods": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/types": "^12.0.0", + "@octokit/auth-oauth-device": "^4.0.0", + "@octokit/oauth-methods": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "@octokit/types": "^9.0.0" + }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/core": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.2.tgz", - "integrity": "sha512-cZUy1gUvd4vttMic7C0lwPed8IYXWYp8kHIMatyhY8t8n3Cpw2ILczkV5pGMPqef7v0bLo0pOHrEHarsau2Ydg==", - "dependencies": { - "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.0.0", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", + "version": "4.2.1", + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/endpoint": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", - "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", + "version": "7.0.5", + "license": "MIT", "dependencies": { - "@octokit/types": "^12.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/graphql": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", - "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", + "version": "5.0.5", + "license": "MIT", "dependencies": { - "@octokit/request": "^8.0.1", - "@octokit/types": "^12.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/oauth-authorization-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", - "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==", + "version": "5.0.0", + "license": "MIT", "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/oauth-methods": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-4.0.1.tgz", - "integrity": "sha512-1NdTGCoBHyD6J0n2WGXg9+yDLZrRNZ0moTEex/LSPr49m530WNKcCfXDghofYptr3st3eTii+EHoG5k/o+vbtw==", + "version": "2.0.5", + "license": "MIT", "dependencies": { - "@octokit/oauth-authorization-url": "^6.0.2", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", + "@octokit/oauth-authorization-url": "^5.0.0", + "@octokit/request": "^6.2.3", + "@octokit/request-error": "^3.0.3", + "@octokit/types": "^9.0.0", "btoa-lite": "^1.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/openapi-types": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz", - "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw==" + "version": "17.2.0", + "license": "MIT" }, "node_modules/@octokit/plugin-paginate-graphql": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-4.0.0.tgz", - "integrity": "sha512-7HcYW5tP7/Z6AETAPU14gp5H5KmCPT3hmJrS/5tO7HIgbwenYmgw4OY9Ma54FDySuxMwD+wsJlxtuGWwuZuItA==", - "engines": { - "node": ">= 18" - }, + "version": "2.0.1", + "license": "MIT", "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": ">=4" } }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz", - "integrity": "sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg==", + "version": "6.1.2", + "license": "MIT", "dependencies": { - "@octokit/types": "^12.4.0" + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" }, "engines": { - "node": ">= 18" + "node": ">= 14" }, "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": ">=4" } }, "node_modules/@octokit/plugin-request-log": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", - "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", - "engines": { - "node": ">= 18" - }, + "version": "1.0.4", + "license": "MIT", "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": ">=3" } }, "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.2.0.tgz", - "integrity": "sha512-ePbgBMYtGoRNXDyKGvr9cyHjQ163PbwD0y1MkDJCpkO2YH4OeXX40c4wYHKikHGZcpGPbcRLuy0unPUuafco8Q==", + "version": "7.1.2", + "license": "MIT", "dependencies": { - "@octokit/types": "^12.3.0" + "@octokit/types": "^9.2.3", + "deprecation": "^2.3.1" }, "engines": { - "node": ">= 18" + "node": ">= 14" }, "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": ">=3" } }, "node_modules/@octokit/request": { - "version": "8.1.6", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", - "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", + "version": "6.2.5", + "license": "MIT", "dependencies": { - "@octokit/endpoint": "^9.0.0", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/request-error": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", - "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", + "version": "3.0.3", + "license": "MIT", "dependencies": { - "@octokit/types": "^12.0.0", + "@octokit/types": "^9.0.0", "deprecation": "^2.0.0", "once": "^1.4.0" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, "node_modules/@octokit/rest": { - "version": "20.0.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", - "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", + "version": "19.0.11", + "license": "MIT", "dependencies": { - "@octokit/core": "^5.0.0", - "@octokit/plugin-paginate-rest": "^9.0.0", - "@octokit/plugin-request-log": "^4.0.0", - "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^7.1.2" }, "engines": { - "node": ">= 18" + "node": ">= 14" } }, + "node_modules/@octokit/tsconfig": { + "version": "1.0.2", + "license": "MIT" + }, "node_modules/@octokit/types": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.4.0.tgz", - "integrity": "sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ==", + "version": "9.2.3", + "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^19.1.0" + "@octokit/openapi-types": "^17.2.0" } }, "node_modules/@opentelemetry/api": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", - "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==", + "version": "1.4.1", + "license": "Apache-2.0", "engines": { "node": ">=8.0.0" } }, "node_modules/@opentelemetry/core": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.20.0.tgz", - "integrity": "sha512-lSRvk5AIdD6CtgYJcJXh0wGibQ3S/8bC2qbqKs9wK8e0K1tsWV6YkGFOqVc+jIRlCbZoIBeZzDe5UI+vb94uvg==", + "version": "1.13.0", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/semantic-conventions": "1.20.0" + "@opentelemetry/semantic-conventions": "1.13.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.8.0" + "@opentelemetry/api": ">=1.0.0 <1.5.0" } }, "node_modules/@opentelemetry/instrumentation": { - "version": "0.41.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz", - "integrity": "sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==", - "dependencies": { - "@types/shimmer": "^1.0.2", - "import-in-the-middle": "1.4.2", - "require-in-the-middle": "^7.1.1", - "semver": "^7.5.1", + "version": "0.35.1", + "license": "Apache-2.0", + "dependencies": { + "require-in-the-middle": "^5.0.3", + "semver": "^7.3.2", "shimmer": "^1.2.1" }, "engines": { @@ -2942,86 +2386,52 @@ } }, "node_modules/@opentelemetry/resources": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.20.0.tgz", - "integrity": "sha512-nOpV0vGegSq+9ze2cEDvO3BMA5pGBhmhKZiAlj+xQZjiEjPmJtdHIuBLRvptu2ahcbFJw85gIB9BYHZOvZK1JQ==", + "version": "1.13.0", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "1.20.0", - "@opentelemetry/semantic-conventions": "1.20.0" + "@opentelemetry/core": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.8.0" + "@opentelemetry/api": ">=1.0.0 <1.5.0" } }, "node_modules/@opentelemetry/sdk-trace-base": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.20.0.tgz", - "integrity": "sha512-BAIZ0hUgnhdb3OBQjn1FKGz/Iwie4l+uOMKklP7FGh7PTqEAbbzDNMJKaZQh6KepF7Fq+CZDRKslD3yrYy2Tzw==", + "version": "1.13.0", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "1.20.0", - "@opentelemetry/resources": "1.20.0", - "@opentelemetry/semantic-conventions": "1.20.0" + "@opentelemetry/core": "1.13.0", + "@opentelemetry/resources": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.8.0" + "@opentelemetry/api": ">=1.0.0 <1.5.0" } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.20.0.tgz", - "integrity": "sha512-3zLJJCgTKYpbqFX8drl8hOCHtdchELC+kGqlVcV4mHW1DiElTtv1Nt9EKBptTd1IfL56QkuYnWJ3DeHd2Gtu/A==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, + "version": "1.13.0", + "license": "Apache-2.0", "engines": { "node": ">=14" } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@primer/octicons": { - "version": "19.8.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.8.0.tgz", - "integrity": "sha512-Imze/fyW41Io5fN+27T5EAeXJrgBjMbz6nzU+wYbRylXvIAjLPUvaJPVoStiFlgSU+TjTUJqg5A9rgMDzTyMCg==", - "dependencies": { - "object-assign": "^4.1.1" - } - }, "node_modules/@redis/bloom": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/client": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.13.tgz", - "integrity": "sha512-epkUM9D0Sdmt93/8Ozk43PNjLi36RZzG+d/T1Gdu5AI8jvghonTeLYV69WVWdilvFo+PYxbP0TZ0saMvr6nscQ==", + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.9.tgz", + "integrity": "sha512-SffgN+P1zdWJWSXBvJeynvEnmnZrYmtKSRW00xl8pOPFOMJjxRR9u0frSxJpPR6Y4V+k54blJjGW7FgxbTI7bQ==", "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -3032,25 +2442,23 @@ } }, "node_modules/@redis/graph": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", - "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "version": "1.1.0", + "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "version": "1.0.4", + "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/search": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", - "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", + "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -3065,76 +2473,55 @@ }, "node_modules/@sideway/address": { "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@sideway/address/node_modules/@hapi/hoek": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + "license": "BSD-3-Clause" }, "node_modules/@sideway/formula": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + "license": "BSD-3-Clause" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + "license": "BSD-3-Clause" }, "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "version": "0.25.24", "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, "node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "version": "2.0.0", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "10.0.2", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^2.0.0" } }, "node_modules/@tootallnate/once": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/@ts-morph/common": { "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.12.3.tgz", - "integrity": "sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==", "dev": true, + "license": "MIT", "dependencies": { "fast-glob": "^3.2.7", "minimatch": "^3.0.4", @@ -3142,57 +2529,30 @@ "path-browserify": "^1.0.1" } }, - "node_modules/@ts-morph/common/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@ts-morph/common/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "version": "1.0.3", + "dev": true, + "license": "MIT" }, "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "version": "7.20.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -3202,77 +2562,60 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.6.4", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "version": "7.4.1", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "version": "7.18.5", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.20.7" + "@babel/types": "^7.3.0" } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.2", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/btoa-lite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.2.tgz", - "integrity": "sha512-ZYbcE2x7yrvNFJiU7xJGrpF/ihpkM7zKgw8bha3LNJSesvTtUNxbpzaT7WXBIryf6jovisrxTBvymxMeLLj1Mg==" + "version": "1.0.0", + "license": "MIT" }, "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "dev": true, + "version": "3.4.35", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "version": "4.1.7", "dev": true, + "license": "MIT", "dependencies": { "@types/ms": "*" } }, "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "version": "4.17.17", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -3281,9 +2624,8 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "version": "4.17.34", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -3292,193 +2634,174 @@ } }, "node_modules/@types/express-session": { - "version": "1.17.10", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.10.tgz", - "integrity": "sha512-U32bC/s0ejXijw5MAzyaV4tuZopCh/K7fPoUDyNbsRXHvPSeymygYD1RFL99YOLhF5PNOkzswvOTRaVHdL1zMw==", + "version": "1.17.7", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "version": "4.1.6", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, "node_modules/@types/is-buffer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/is-buffer/-/is-buffer-2.0.2.tgz", - "integrity": "sha512-G6OXy83Va+xEo8XgqAJYOuvOMxeey9xM5XKkvwJNmN8rVdcB+r15HvHsG86hl86JvU0y1aa7Z2ERkNFYWw9ySg==", + "version": "2.0.0", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "version": "2.0.4", + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "version": "3.0.0", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "version": "3.0.1", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/jest": { - "version": "29.5.11", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", - "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "version": "29.5.1", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "version": "7.0.11", + "dev": true, + "license": "MIT" }, "node_modules/@types/jsonwebtoken": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", - "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", + "version": "9.0.2", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/lodash": { - "version": "4.14.202", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", - "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", - "dev": true + "version": "4.14.194", + "dev": true, + "license": "MIT" }, "node_modules/@types/luxon": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.0.tgz", - "integrity": "sha512-PEVoA4MOfSsFNaPrZjIUGUZujBDxnO/tj2A2N9KfzlR+pNgpBdDuk0TmRvSMAVUP5q4q8IkMEZ8UOp3MIr+QgA==", - "dev": true + "version": "3.3.0", + "dev": true, + "license": "MIT" }, "node_modules/@types/memory-cache": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@types/memory-cache/-/memory-cache-0.2.5.tgz", - "integrity": "sha512-OIKRDDZUFeKT/rsko7/CGnR5qE8xTU8ogzyaaSDSHGkKwlSB/E6RopSF5fReo89khCAcGIoqSi723tDqUe6gYw==", - "dev": true + "version": "0.2.2", + "dev": true, + "license": "MIT" }, "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + "version": "1.3.2", + "license": "MIT" }, "node_modules/@types/morgan": { - "version": "1.9.9", - "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.9.tgz", - "integrity": "sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==", + "version": "1.9.4", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "dev": true + "version": "0.7.31", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "20.11.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", - "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", - "dependencies": { - "undici-types": "~5.26.4" - } + "version": "20.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", + "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" }, "node_modules/@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "version": "2.6.1", + "license": "MIT", "dependencies": { "@types/node": "*", - "form-data": "^4.0.0" + "form-data": "^3.0.0" + } + }, + "node_modules/@types/node-fetch/node_modules/form-data": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, "node_modules/@types/node-jose": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@types/node-jose/-/node-jose-1.1.13.tgz", - "integrity": "sha512-QjMd4yhwy1EvSToQn0YI3cD29YhyfxFwj7NecuymjLys2/P0FwxWnkgBlFxCai6Y3aBCe7rbwmqwJJawxlgcXw==", + "version": "1.1.10", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/oauth": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.4.tgz", - "integrity": "sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A==", + "version": "0.9.1", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/object-path": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/@types/object-path/-/object-path-0.11.4.tgz", - "integrity": "sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==", - "dev": true + "version": "0.11.1", + "dev": true, + "license": "MIT" }, "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true + "version": "4.0.0", + "dev": true, + "license": "MIT" }, "node_modules/@types/passport": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz", - "integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==", + "version": "1.0.12", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/passport-azure-ad": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/passport-azure-ad/-/passport-azure-ad-4.3.5.tgz", - "integrity": "sha512-dzWBDye7VvzWgKQbxImEvT0x1b0Vi37AYZrjN/XitTkstHsegDT97Wha5Aknoh4vPpv68DdaxZ4defK8YIk7kA==", + "version": "4.3.1", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*", "@types/passport": "*" } }, "node_modules/@types/passport-github": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@types/passport-github/-/passport-github-1.1.12.tgz", - "integrity": "sha512-VJpMEIH+cOoXB694QgcxuvWy2wPd1Oq3gqrg2Y9DMVBYs9TmH9L14qnqPDZsNMZKBDH+SvqRsGZj9SgHYeDgcA==", + "version": "1.1.7", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*", "@types/passport": "*", @@ -3486,10 +2809,9 @@ } }, "node_modules/@types/passport-oauth2": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.15.tgz", - "integrity": "sha512-9cUTP/HStNSZmhxXGuRrBJfEWzIEJRub2eyJu3CvkA+8HAMc9W3aKdFhVq+Qz1hi42qn+GvSAnz3zwacDSYWpw==", + "version": "1.4.11", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*", "@types/oauth": "*", @@ -3497,140 +2819,175 @@ } }, "node_modules/@types/pg": { - "version": "8.10.9", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.9.tgz", - "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", + "version": "8.10.1", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^4.0.1" } }, + "node_modules/@types/pg/node_modules/pg-types": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.0.1", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/pg/node_modules/postgres-array": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/pg/node_modules/postgres-bytea": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "obuf": "~1.1.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/pg/node_modules/postgres-date": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/pg/node_modules/postgres-interval": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "dev": true, + "license": "MIT" + }, "node_modules/@types/pug": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", - "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", - "dev": true + "version": "2.0.6", + "dev": true, + "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.11", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" + "version": "6.9.7", + "license": "MIT" }, "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + "version": "1.2.4", + "license": "MIT" }, "node_modules/@types/recursive-readdir": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@types/recursive-readdir/-/recursive-readdir-2.2.4.tgz", - "integrity": "sha512-84REEGT3lcgopvpkmGApzmU5UEG0valme5rQS/KGiguTkJ70/Au8UYZTyrzoZnY9svuX9351+1uvrRPzWDD/uw==", + "version": "2.2.1", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", - "dev": true + "version": "7.5.0", + "dev": true, + "license": "MIT" }, "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "version": "0.17.1", + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "version": "1.13.10", + "license": "MIT", "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", + "@types/mime": "^1", "@types/node": "*" } }, - "node_modules/@types/shimmer": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.0.5.tgz", - "integrity": "sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==" - }, "node_modules/@types/simple-oauth2": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@types/simple-oauth2/-/simple-oauth2-5.0.7.tgz", - "integrity": "sha512-8JbWVJbiTSBQP/7eiyGKyXWAqp3dKQZpaA+pdW16FCi32ujkzRMG8JfjoAzdWt6W8U591ZNdHcPtP2D7ILTKuA==", - "dev": true + "version": "5.0.4", + "dev": true, + "license": "MIT" }, "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true + "version": "2.0.1", + "dev": true, + "license": "MIT" }, "node_modules/@types/tunnel": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", - "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/validator": { - "version": "13.11.8", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.8.tgz", - "integrity": "sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ==", - "dev": true + "version": "13.7.17", + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.24", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "version": "21.0.0", + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", - "integrity": "sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==", + "version": "5.59.7", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/type-utils": "6.18.1", - "@typescript-eslint/utils": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/type-utils": "5.59.7", + "@typescript-eslint/utils": "5.59.7", "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -3639,26 +2996,24 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.1.tgz", - "integrity": "sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==", + "version": "5.59.7", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/typescript-estree": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -3667,16 +3022,15 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", - "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", + "version": "5.59.7", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1" + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -3684,25 +3038,24 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.1.tgz", - "integrity": "sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==", + "version": "5.59.7", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "6.18.1", - "@typescript-eslint/utils": "6.18.1", + "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/utils": "5.59.7", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "tsutils": "^3.21.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "*" }, "peerDependenciesMeta": { "typescript": { @@ -3711,12 +3064,11 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", - "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", + "version": "5.59.7", "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -3724,22 +3076,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", - "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", + "version": "5.59.7", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -3752,57 +3102,49 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", - "integrity": "sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==", + "version": "5.59.7", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/typescript-estree": "6.18.1", - "semver": "^7.5.4" + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", - "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", + "version": "5.59.7", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.18.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/accepts": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -3812,9 +3154,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.8.0", + "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3822,36 +3164,25 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.2.0", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", "dependencies": { "debug": "4" }, @@ -3859,11 +3190,22 @@ "node": ">= 6.0.0" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3877,9 +3219,8 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -3892,9 +3233,8 @@ }, "node_modules/ansi-escapes/node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -3903,24 +3243,22 @@ } }, "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "5.0.1", "dev": true, + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "version": "4.3.0", "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" @@ -3928,9 +3266,8 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3941,30 +3278,29 @@ }, "node_modules/app-root-path": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", - "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", + "license": "MIT", "engines": { "node": ">= 6.0.0" } }, "node_modules/applicationinsights": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.9.2.tgz", - "integrity": "sha512-wlDiD7v0BQNM8oNzsf9C836R5ze25u+CuCEZsbA5xMIXYYBxkqkWE/mo9GFJM7rsKaiGqpxEwWmePHKD2Lwy2w==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.7.0.tgz", + "integrity": "sha512-/vV5X6M4TlRA5NxNZAdCE0gukzfK24mb3z18D5Kl/CyIfSVIkafsIji3mK+Zi5q+7dn6H1CkFazlcnLf40anHw==", "dependencies": { - "@azure/core-auth": "^1.5.0", + "@azure/core-auth": "^1.4.0", "@azure/core-rest-pipeline": "1.10.1", "@azure/core-util": "1.2.0", - "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.5", + "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.3", "@microsoft/applicationinsights-web-snippet": "^1.0.1", - "@opentelemetry/api": "^1.7.0", - "@opentelemetry/core": "^1.19.0", - "@opentelemetry/sdk-trace-base": "^1.19.0", - "@opentelemetry/semantic-conventions": "^1.19.0", + "@opentelemetry/api": "^1.0.4", + "@opentelemetry/core": "^1.12.0", + "@opentelemetry/sdk-trace-base": "^1.12.0", + "@opentelemetry/semantic-conventions": "^1.12.0", "cls-hooked": "^4.2.2", "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "1.1.1", - "diagnostic-channel-publishers": "1.0.8" + "diagnostic-channel": "1.1.0", + "diagnostic-channel-publishers": "1.0.6" }, "engines": { "node": ">=8.0.0" @@ -3978,88 +3314,51 @@ } } }, - "node_modules/applicationinsights/node_modules/@azure/core-rest-pipeline": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz", - "integrity": "sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA==", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.4.0", - "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "form-data": "^4.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/applicationinsights/node_modules/@azure/core-util": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.2.0.tgz", - "integrity": "sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/arg": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "license": "Python-2.0" }, "node_modules/array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "license": "MIT" }, "node_modules/array-timsort": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", - "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/asap": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "license": "MIT" }, "node_modules/assert-never": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", - "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + "license": "MIT" }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + "node_modules/astral-regex": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, "node_modules/async-hook-jl": { "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", + "license": "MIT", "dependencies": { "stack-chain": "^1.3.7" }, @@ -4069,8 +3368,7 @@ }, "node_modules/async-listener": { "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "license": "BSD-2-Clause", "dependencies": { "semver": "^5.3.0", "shimmer": "^1.1.0" @@ -4080,17 +3378,15 @@ } }, "node_modules/async-listener/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "version": "5.7.1", + "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/async-prompt": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-prompt/-/async-prompt-1.0.1.tgz", - "integrity": "sha512-AdeC4NCuD0RxpbWm6pexY/AWMasHzMe+/zvdxdsAvpMmuz4in7N8OrKP7YzbRPYhUS+hibZNdUablgfE6Uj8UA==", + "license": "MIT", "dependencies": { "keypress": "~0.2.1" }, @@ -4100,13 +3396,11 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "license": "MIT" }, "node_modules/available-typed-arrays": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4115,25 +3409,23 @@ } }, "node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", + "version": "1.4.0", + "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.0", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/transform": "^29.7.0", + "@jest/transform": "^29.5.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", + "babel-preset-jest": "^29.5.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -4145,60 +3437,10 @@ "@babel/core": "^7.8.0" } }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -4210,36 +3452,10 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -4252,9 +3468,8 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -4274,12 +3489,11 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", + "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -4291,8 +3505,7 @@ }, "node_modules/babel-walk": { "version": "3.0.0-canary-5", - "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", - "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "license": "MIT", "dependencies": { "@babel/types": "^7.9.6" }, @@ -4302,13 +3515,10 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -4322,20 +3532,19 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/base64url": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/basic-auth": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" }, @@ -4344,14 +3553,12 @@ } }, "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + "version": "2.2.2", + "license": "Apache-2.0" }, "node_modules/body-parser": { "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -4373,31 +3580,37 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" + }, + "node_modules/body-parser/node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, + "version": "1.1.11", + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -4406,9 +3619,7 @@ } }, "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.21.5", "dev": true, "funding": [ { @@ -4418,17 +3629,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" }, "bin": { "browserslist": "cli.js" @@ -4439,9 +3647,8 @@ }, "node_modules/bs-logger": { "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, + "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -4451,22 +3658,18 @@ }, "node_modules/bser": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } }, "node_modules/btoa-lite": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==" + "license": "MIT" }, "node_modules/buffer": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -4481,6 +3684,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -4488,51 +3692,34 @@ }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + "license": "BSD-3-Clause" }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/buffer-writer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/builtins": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.0.0" } }, "node_modules/bunyan": { "version": "1.8.15", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", - "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", "engines": [ "node >=0.10.0" ], + "license": "MIT", "bin": { "bunyan": "bin/bunyan" }, @@ -4545,16 +3732,14 @@ }, "node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/cache-manager": { "version": "3.6.3", - "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-3.6.3.tgz", - "integrity": "sha512-dS4DnV6c6cQcVH5OxzIU1XZaACXwvVIiUPkFytnRmLOACuBGv3GQgRQ1RJGRRw4/9DF14ZK2RFlZu1TUgDniMg==", + "license": "MIT", "dependencies": { "async": "3.2.3", "lodash.clonedeep": "^4.5.0", @@ -4563,28 +3748,14 @@ }, "node_modules/cache-manager/node_modules/async": { "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" - }, - "node_modules/cache-manager/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "license": "MIT" }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.2", + "license": "MIT", "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4592,26 +3763,22 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001579", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", - "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==", + "version": "1.0.30001486", "dev": true, "funding": [ { @@ -4626,56 +3793,41 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk-template": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", - "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^5.2.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=14.16" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk-template?sponsor=1" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/character-parser": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", - "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "license": "MIT", "dependencies": { "is-regex": "^1.0.3" } }, "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "version": "3.8.0", "dev": true, "funding": [ { @@ -4683,20 +3835,28 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" + "version": "1.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, "node_modules/clear-module": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz", - "integrity": "sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^2.0.0", "resolve-from": "^5.0.0" @@ -4709,154 +3869,93 @@ } }, "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "version": "3.1.0", "dev": true, + "license": "MIT", "dependencies": { - "restore-cursor": "^4.0.0" + "restore-cursor": "^3.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "version": "3.1.0", "dev": true, + "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" + "string-width": "^5.0.0" }, "engines": { - "node": ">=18" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, + "license": "MIT", "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/cli-truncate/node_modules/string-width": { + "version": "5.1.2", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.0.1", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/cliui/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/cliui": { + "version": "8.0.1", "dev": true, + "license": "ISC", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=12" } }, "node_modules/cls-hooked": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", + "license": "BSD-2-Clause", "dependencies": { "async-hook-jl": "^1.7.6", "emitter-listener": "^1.0.1", @@ -4867,26 +3966,23 @@ } }, "node_modules/cls-hooked/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "version": "5.7.1", + "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/cluster-key-slot": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", "engines": { "node": ">=0.10.0" } }, "node_modules/co": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -4894,46 +3990,42 @@ }, "node_modules/code-block-writer": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", - "integrity": "sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true + "version": "1.0.1", + "dev": true, + "license": "MIT" }, "node_modules/color-contrast-checker": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/color-contrast-checker/-/color-contrast-checker-2.1.0.tgz", - "integrity": "sha512-6Y0aIEej3pwZTVlicIqVzhO6T4izDWouaIXnYoDdTuFFAMQ9nnN0dgHNP9J94jRnH6asjPq1/wzUKxwoNbWtRQ==" + "license": "Apache-2.0" }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "version": "1.1.4", + "dev": true, + "license": "MIT" }, "node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4942,19 +4034,17 @@ } }, "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "10.0.1", "dev": true, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=14" } }, "node_modules/comment-json": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz", - "integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==", "dev": true, + "license": "MIT", "dependencies": { "array-timsort": "^1.0.3", "core-util-is": "^1.0.3", @@ -4968,8 +4058,7 @@ }, "node_modules/compressible": { "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -4979,8 +4068,7 @@ }, "node_modules/compression": { "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -4996,53 +4084,56 @@ }, "node_modules/compression/node_modules/bytes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "license": "MIT" }, "node_modules/configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "version": "5.0.1", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/yeoman/configstore?sponsor=1" + "node": ">=8" + } + }, + "node_modules/configstore/node_modules/write-file-atomic": { + "version": "3.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "node_modules/connect-redis": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-7.1.0.tgz", - "integrity": "sha512-UaqO1EirWjON2ENsyau7N5lbkrdYBpS6mYlXSeff/OYXsd6EGZ+SXSmNPoljL2PSua8fgjAEaldSA73PMZQ9Eg==", + "license": "MIT", "engines": { "node": ">=16" }, @@ -5052,8 +4143,7 @@ }, "node_modules/constantinople": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", - "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "license": "MIT", "dependencies": { "@babel/parser": "^7.6.0", "@babel/types": "^7.6.1" @@ -5061,8 +4151,7 @@ }, "node_modules/content-disposition": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -5072,8 +4161,6 @@ }, "node_modules/content-disposition/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -5087,20 +4174,19 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/content-type": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/continuation-local-storage": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "license": "BSD-2-Clause", "dependencies": { "async-listener": "^0.6.0", "emitter-listener": "^1.1.1" @@ -5108,33 +4194,28 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cors": { "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -5144,319 +4225,180 @@ } }, "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.0.0", "dev": true, + "license": "MIT", "dependencies": { - "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/create-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/create-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/create-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" + "path-type": "^4.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=14" } }, - "node_modules/create-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/create-require": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } + "license": "MIT" }, "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "dev": true, - "dependencies": { - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "version": "2.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/cspell": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.3.2.tgz", - "integrity": "sha512-V8Ub3RO/a5lwSsltW/ib3Z3G/sczKtSpBBN1JChzbSCfEgaY2mJY8JW0BpkSV+Ug6uJitpXNOOaxa3Xr489i7g==", - "dev": true, - "dependencies": { - "@cspell/cspell-json-reporter": "8.3.2", - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-types": "8.3.2", - "@cspell/dynamic-import": "8.3.2", - "chalk": "^5.3.0", - "chalk-template": "^1.1.0", - "commander": "^11.1.0", - "cspell-gitignore": "8.3.2", - "cspell-glob": "8.3.2", - "cspell-io": "8.3.2", - "cspell-lib": "8.3.2", - "fast-glob": "^3.3.2", + "version": "6.31.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-pipe": "6.31.1", + "@cspell/dynamic-import": "6.31.1", + "chalk": "^4.1.2", + "commander": "^10.0.0", + "cspell-gitignore": "6.31.1", + "cspell-glob": "6.31.1", + "cspell-io": "6.31.1", + "cspell-lib": "6.31.1", + "fast-glob": "^3.2.12", "fast-json-stable-stringify": "^2.1.0", - "file-entry-cache": "^8.0.0", - "get-stdin": "^9.0.0", - "semver": "^7.5.4", - "strip-ansi": "^7.1.0", - "vscode-uri": "^3.0.8" + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "imurmurhash": "^0.1.4", + "semver": "^7.3.8", + "strip-ansi": "^6.0.1", + "vscode-uri": "^3.0.7" }, "bin": { - "cspell": "bin.mjs", + "cspell": "bin.js", "cspell-esm": "bin.mjs" }, "engines": { - "node": ">=18" + "node": ">=14" }, "funding": { "url": "https://github.com/streetsidesoftware/cspell?sponsor=1" } }, - "node_modules/cspell-config-lib": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.3.2.tgz", - "integrity": "sha512-Wc98XhBNLwDxnxCzMtgRJALI9a69cu3C5Gf1rGjNTKSFo9JYiQmju0Ur3z25Pkx9Sa86f+2IjvNCf33rUDSoBQ==", - "dev": true, - "dependencies": { - "@cspell/cspell-types": "8.3.2", - "comment-json": "^4.2.3", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/cspell-dictionary": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.3.2.tgz", - "integrity": "sha512-xyK95hO2BMPFxIo8zBwGml8035qOxSBdga1BMhwW/p2wDrQP8S4Cdm/54//tCDmKn6uRkFQvyOfWGaX2l8WMEg==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-types": "8.3.2", - "cspell-trie-lib": "8.3.2", - "fast-equals": "^5.0.1", - "gensequence": "^6.0.0" + "@cspell/cspell-pipe": "6.31.1", + "@cspell/cspell-types": "6.31.1", + "cspell-trie-lib": "6.31.1", + "fast-equals": "^4.0.3", + "gensequence": "^5.0.2" }, "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/cspell-gitignore": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.3.2.tgz", - "integrity": "sha512-3Qc9P5BVvl/cg//s2s+zIMGKcoH5v7oOtRgwn4UQry8yiyo19h0tiTKkSR574FMhF5NtcShTnwIwPSIXVBPFHA==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { - "cspell-glob": "8.3.2", - "find-up-simple": "^1.0.0" + "cspell-glob": "6.31.1", + "find-up": "^5.0.0" }, "bin": { "cspell-gitignore": "bin.mjs" }, "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/cspell-glob": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.3.2.tgz", - "integrity": "sha512-KtIFxE+3l5dGEofND4/CdZffXP8XN1+XGQKxJ96lIzWsc01mkotfhxTkla6mgvfH039t7BsY/SWv0460KyGslQ==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { "micromatch": "^4.0.5" }, "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/cspell-grammar": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.3.2.tgz", - "integrity": "sha512-tYCkOmRzJe1a6/R+8QGSwG7TwTgznLPqsHtepKzLmnS4YX54VXjKRI9zMARxXDzUVfyCSVdW5MyiY/0WTNoy+A==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-types": "8.3.2" + "@cspell/cspell-pipe": "6.31.1", + "@cspell/cspell-types": "6.31.1" }, "bin": { "cspell-grammar": "bin.mjs" }, "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/cspell-io": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.3.2.tgz", - "integrity": "sha512-WYpKsyBCQP0SY4gXnhW5fPuxcYchKYKG1PIXVV3ezFU4muSgW6GuLNbGuSfwv/8YNXRgFSN0e3hYH0rdBK2Aow==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { - "@cspell/cspell-service-bus": "8.3.2" + "@cspell/cspell-service-bus": "6.31.1", + "node-fetch": "^2.6.9" }, "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/cspell-lib": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.3.2.tgz", - "integrity": "sha512-wTvdaev/TyGB/ln6CVD1QbVs2D7/+QiajQ67S7yj1suLHM6YcNQQb/5sPAM8VPtj0E7PgwgPXf3bq18OtPvnFg==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { - "@cspell/cspell-bundled-dicts": "8.3.2", - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-resolver": "8.3.2", - "@cspell/cspell-types": "8.3.2", - "@cspell/dynamic-import": "8.3.2", - "@cspell/strong-weak-map": "8.3.2", + "@cspell/cspell-bundled-dicts": "6.31.1", + "@cspell/cspell-pipe": "6.31.1", + "@cspell/cspell-types": "6.31.1", + "@cspell/strong-weak-map": "6.31.1", "clear-module": "^4.1.2", "comment-json": "^4.2.3", - "configstore": "^6.0.0", - "cspell-config-lib": "8.3.2", - "cspell-dictionary": "8.3.2", - "cspell-glob": "8.3.2", - "cspell-grammar": "8.3.2", - "cspell-io": "8.3.2", - "cspell-trie-lib": "8.3.2", - "fast-equals": "^5.0.1", - "gensequence": "^6.0.0", + "configstore": "^5.0.1", + "cosmiconfig": "8.0.0", + "cspell-dictionary": "6.31.1", + "cspell-glob": "6.31.1", + "cspell-grammar": "6.31.1", + "cspell-io": "6.31.1", + "cspell-trie-lib": "6.31.1", + "fast-equals": "^4.0.3", + "find-up": "^5.0.0", + "gensequence": "^5.0.2", "import-fresh": "^3.3.0", "resolve-from": "^5.0.0", - "vscode-languageserver-textdocument": "^1.0.11", - "vscode-uri": "^3.0.8" + "resolve-global": "^1.0.0", + "vscode-languageserver-textdocument": "^1.0.8", + "vscode-uri": "^3.0.7" }, "engines": { - "node": ">=18" + "node": ">=14.6" } }, "node_modules/cspell-trie-lib": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.3.2.tgz", - "integrity": "sha512-8qh2FqzkLMwzlTlvO/5Z+89fhi30rrfekocpight/BmqKbE2XFJQD7wS2ml24e7q/rdHJLXVpJbY/V5mByucCA==", + "version": "6.31.1", "dev": true, + "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "8.3.2", - "@cspell/cspell-types": "8.3.2", - "gensequence": "^6.0.0" + "@cspell/cspell-pipe": "6.31.1", + "@cspell/cspell-types": "6.31.1", + "gensequence": "^5.0.2" }, "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -5470,87 +4412,57 @@ } }, "node_modules/dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "version": "0.7.0", "dev": true, - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } + "license": "MIT" }, "node_modules/deeks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/deeks/-/deeks-2.6.1.tgz", - "integrity": "sha512-PZrpz5xLo2JPZa3L+kqMMMdZU5pRwMysTM1xd6pLhNtgQw4Iq3wbF2QWaQTVh+HRq9Yg4rcjDIJ+scfGLxmsjQ==", + "version": "2.6.0", + "license": "MIT", "engines": { "node": ">= 12" } }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/deprecation": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + "license": "ISC" }, "node_modules/destroy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -5558,52 +4470,53 @@ }, "node_modules/detect-newline": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/diagnostic-channel": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz", - "integrity": "sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==", + "version": "1.1.0", + "license": "MIT", "dependencies": { - "semver": "^7.5.3" + "semver": "^5.3.0" } }, "node_modules/diagnostic-channel-publishers": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.8.tgz", - "integrity": "sha512-HmSm9hXxSPxA9BaLGY98QU1zsdjeCk113KjAYGPCen1ZP6mhVaTPzHd6UYv5r21DnWANi+f+NyPOHruGT9jpqQ==", + "version": "1.0.6", + "license": "MIT", "peerDependencies": { "diagnostic-channel": "*" } }, + "node_modules/diagnostic-channel/node_modules/semver": { + "version": "5.7.1", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/diff": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "version": "29.4.3", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -5612,18 +4525,16 @@ } }, "node_modules/doc-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-3.1.0.tgz", - "integrity": "sha512-Pv2hLQbUM8du5681lTWIYk0OtVBmNhMAeZNGeFhMMJBIR89Nw4XesBwee1Xtlfk83n71tn0Y6VsJOn4d3qIiTw==", + "version": "3.0.6", + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -5633,22 +4544,17 @@ }, "node_modules/doctypes": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" + "license": "MIT" }, "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "version": "5.3.0", "dev": true, + "license": "MIT", "dependencies": { "is-obj": "^2.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/dotenv": { @@ -5664,9 +4570,8 @@ }, "node_modules/dtrace-provider": { "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", "hasInstallScript": true, + "license": "BSD-2-Clause", "optional": true, "dependencies": { "nan": "^2.14.0" @@ -5677,42 +4582,36 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" } }, "node_modules/ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.639", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.639.tgz", - "integrity": "sha512-CkKf3ZUVZchr+zDpAlNLEEy2NJJ9T64ULWaDgy3THXXlPVPkLu3VOs9Bac44nebVtdwl2geSj6AxTtGDOxoXhg==", - "dev": true + "version": "1.4.392", + "dev": true, + "license": "ISC" }, "node_modules/emitter-listener": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "license": "BSD-2-Clause", "dependencies": { "shimmer": "^1.2.0" } }, "node_modules/emittery": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5721,63 +4620,44 @@ } }, "node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true + "version": "8.0.0", + "dev": true, + "license": "MIT" }, "node_modules/encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es6-promise": { "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "license": "MIT" }, "node_modules/escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5786,28 +4666,26 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.41.0", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.41.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", + "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -5817,6 +4695,7 @@ "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", @@ -5826,8 +4705,9 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", + "optionator": "^0.9.1", "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -5840,23 +4720,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-compat-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", - "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "version": "8.8.0", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -5865,14 +4732,12 @@ } }, "node_modules/eslint-plugin-es-x": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz", - "integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==", + "version": "6.2.1", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.1.2" + "@eslint-community/regexpp": "^4.5.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -5885,22 +4750,18 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "version": "16.0.0", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.5.0", - "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", - "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", + "eslint-plugin-es-x": "^6.1.0", + "ignore": "^5.1.1", + "is-core-module": "^2.12.0", "minimatch": "^3.1.2", "resolve": "^1.22.2", - "semver": "^7.5.3" + "semver": "^7.5.0" }, "engines": { "node": ">=16.0.0" @@ -5912,79 +4773,42 @@ "eslint": ">=7.0.0" } }, - "node_modules/eslint-plugin-n/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-n/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "version": "4.2.1", "dev": true, + "license": "MIT", "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" + "prettier-linter-helpers": "^1.0.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" + "node": ">=12.0.0" }, "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" }, "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, "eslint-config-prettier": { "optional": true } } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "5.1.1", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "estraverse": "^4.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=8.0.0" } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "3.4.1", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5992,146 +4816,48 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint/node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 8" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.0", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "brace-expansion": "^1.1.7" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": "*" - } - }, - "node_modules/eslint/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "license": "BSD-2-Clause", "engines": { - "node": ">=8" + "node": ">=4.0" } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "9.5.2", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -6144,9 +4870,8 @@ }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -6157,9 +4882,8 @@ }, "node_modules/esquery": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -6167,11 +4891,18 @@ "node": ">=0.10" } }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -6179,51 +4910,48 @@ "node": ">=4.0" } }, - "node_modules/estraverse": { + "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true - }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -6242,26 +4970,36 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/exit": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6269,8 +5007,7 @@ }, "node_modules/express": { "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -6309,14 +5046,12 @@ } }, "node_modules/express-async-handler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", - "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" + "version": "1.1.4", + "license": "MIT" }, "node_modules/express-session": { "version": "1.17.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", - "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "license": "MIT", "dependencies": { "cookie": "0.4.2", "cookie-signature": "1.0.6", @@ -6333,29 +5068,24 @@ }, "node_modules/express-session/node_modules/cookie": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/express-session/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/express-session/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/express-session/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -6369,17 +5099,16 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/express-sslify": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/express-sslify/-/express-sslify-1.2.0.tgz", - "integrity": "sha512-OOf2B3MxAVjEXPPWl4Z19wA2oMH+RCULJVhejPwuhiDDClr9QczZz5ycABLSnnN+oY8JcLs32ghs9cxOj0vi+w==" + "license": "MIT" }, "node_modules/express/node_modules/body-parser": { "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -6401,21 +5130,28 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" + }, + "node_modules/express/node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, "node_modules/express/node_modules/raw-body": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -6428,8 +5164,6 @@ }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -6443,34 +5177,28 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true + "version": "1.2.0", + "dev": true, + "license": "Apache-2.0" }, "node_modules/fast-equals": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", - "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "version": "4.0.3", "dev": true, - "engines": { - "node": ">=6.0.0" - } + "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.2.12", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -6484,9 +5212,8 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -6496,34 +5223,30 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + "license": "MIT" }, "node_modules/fast-xml-parser": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.3.tgz", - "integrity": "sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg==", + "version": "4.2.2", "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, { "type": "paypal", "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" } ], + "license": "MIT", "dependencies": { "strnum": "^1.0.5" }, @@ -6532,45 +5255,40 @@ } }, "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "version": "1.15.0", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fb-watchman": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } }, "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "version": "6.0.1", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^4.0.0" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=16.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/file-size": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-size/-/file-size-1.0.0.tgz", - "integrity": "sha512-tLIdonWTpABkU6Axg2yGChYdrOsy4V8xcm0IcyAP8fSsu6jiXLm5pgs083e4sq5fzNRZuAYolUbZyYmPvCKfwQ==" + "license": "MIT" }, "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==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6580,8 +5298,7 @@ }, "node_modules/finalhandler": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -6597,22 +5314,29 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -6624,48 +5348,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-up-simple": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", - "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/flat-cache": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.0.tgz", - "integrity": "sha512-EryKbCE/wxpxKniQlyas6PY1I9vwtF3uCBweX+N8KYTCn3Y12RTGtQAJ/bd5pl7kxUAc8v/R3Ake/N17OZiFqA==", + "version": "3.0.4", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4", - "rimraf": "^5.0.5" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=16" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true + "version": "3.2.5", + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.2", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -6677,44 +5385,14 @@ }, "node_modules/for-each": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/form-data": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -6726,31 +5404,26 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "version": "2.3.2", "dev": true, - "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -6760,69 +5433,47 @@ } }, "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "version": "1.1.1", + "license": "MIT" }, "node_modules/generic-pool": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", - "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/gensequence": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-6.0.0.tgz", - "integrity": "sha512-8WwuywE9pokJRAcg2QFR/plk3cVPebSUqRPzpGQh3WQ0wIiHAw+HyOQj5IuHyUTQBHpBKFoB2JUMu9zT3vJ16Q==", + "version": "5.0.2", "dev": true, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=14" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.0", + "license": "MIT", "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6830,20 +5481,18 @@ }, "node_modules/get-package-type": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "version": "8.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6851,9 +5500,8 @@ }, "node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6861,32 +5509,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, "node_modules/github-username-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/github-username-regex/-/github-username-regex-1.0.0.tgz", - "integrity": "sha512-EqDVkN0/5MQyDPOSDLInVRRXdeISRfcN1UW/1FUqD2knV1HHw8DndMB3UPNn5lO51DvRnjzbLXwWqNNV86PLOw==" + "license": "CC0-1.0" }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "7.2.0", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -6899,9 +5533,8 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -6909,46 +5542,21 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/global-directory": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", - "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "node_modules/global-dirs": { + "version": "0.1.1", "dev": true, + "license": "MIT", "dependencies": { - "ini": "4.1.1" + "ini": "^1.3.4" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "13.20.0", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -6961,9 +5569,8 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -6981,8 +5588,7 @@ }, "node_modules/gopd": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -6991,60 +5597,48 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "version": "4.2.10", + "license": "ISC" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "dev": true, + "license": "MIT" }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/has": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-own-prop": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", - "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7054,8 +5648,7 @@ }, "node_modules/has-tostringtag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -7066,21 +5659,9 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/hsts": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", - "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0" }, @@ -7090,14 +5671,12 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -7111,8 +5690,7 @@ }, "node_modules/http-proxy-agent": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "license": "MIT", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -7123,9 +5701,8 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "5.0.0", + "license": "MIT", "dependencies": { "agent-base": "6", "debug": "4" @@ -7136,18 +5713,16 @@ }, "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/husky": { "version": "8.0.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", - "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true, + "license": "MIT", "bin": { "husky": "lib/bin.js" }, @@ -7160,8 +5735,7 @@ }, "node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -7171,8 +5745,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -7186,22 +5758,21 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.2.0", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -7215,9 +5786,8 @@ }, "node_modules/import-fresh/node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -7227,29 +5797,16 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/import-in-the-middle": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz", - "integrity": "sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==", - "dependencies": { - "acorn": "^8.8.2", - "acorn-import-assertions": "^1.9.0", - "cjs-module-lexer": "^1.2.2", - "module-details-from-path": "^1.0.3" - } - }, "node_modules/import-local": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -7265,10 +5822,9 @@ } }, "node_modules/import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "version": "2.2.2", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7276,17 +5832,23 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -7294,30 +5856,23 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "license": "ISC" }, "node_modules/ini": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "version": "1.3.8", "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "license": "ISC" }, "node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/is-arguments": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -7331,13 +5886,10 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "license": "MIT" }, "node_modules/is-buffer": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "funding": [ { "type": "github", @@ -7352,29 +5904,14 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7383,11 +5920,10 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.12.0", + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "has": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7395,8 +5931,7 @@ }, "node_modules/is-docker": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -7409,8 +5944,7 @@ }, "node_modules/is-expression": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", - "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "license": "MIT", "dependencies": { "acorn": "^7.1.1", "object-assign": "^4.1.1" @@ -7418,8 +5952,7 @@ }, "node_modules/is-expression/node_modules/acorn": { "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -7429,38 +5962,31 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "version": "3.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/is-generator-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/is-generator-function": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -7473,9 +5999,8 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -7485,40 +6010,42 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-promise": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + "license": "MIT" }, "node_modules/is-regex": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -7532,9 +6059,8 @@ }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -7543,11 +6069,14 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "version": "1.1.10", + "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.11" + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -7558,14 +6087,12 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-wsl": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -7575,54 +6102,57 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "version": "3.2.0", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", - "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "version": "5.2.1", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" + "semver": "^6.3.0" }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "version": "3.0.0", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", + "make-dir": "^3.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -7633,10 +6163,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.5", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -7645,34 +6174,15 @@ "node": ">=8" } }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", "import-local": "^3.0.2", - "jest-cli": "^29.7.0" + "jest-cli": "^29.5.0" }, "bin": { "jest": "bin/jest.js" @@ -7690,13 +6200,11 @@ } }, "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", - "jest-util": "^29.7.0", "p-limit": "^3.1.0" }, "engines": { @@ -7704,28 +6212,27 @@ } }, "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^1.0.0", + "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", + "pretty-format": "^29.5.0", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" @@ -7734,71 +6241,22 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-circus/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", - "create-jest": "^29.7.0", "exit": "^0.1.2", + "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "prompts": "^2.0.1", "yargs": "^17.3.1" }, "bin": { @@ -7816,81 +6274,31 @@ } } }, - "node_modules/jest-cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -7910,124 +6318,24 @@ } } }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "version": "29.4.3", "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -8036,111 +6344,58 @@ } }, "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "version": "29.4.3", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "^29.5.0", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -8153,9 +6408,8 @@ }, "node_modules/jest-junit": { "version": "16.0.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", - "integrity": "sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "mkdirp": "^1.0.4", "strip-ansi": "^6.0.1", @@ -8166,117 +6420,44 @@ "node": ">=10.12.0" } }, - "node_modules/jest-junit/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-junit/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -8284,64 +6465,14 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-util": "^29.7.0" + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -8349,9 +6480,8 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -8365,26 +6495,24 @@ } }, "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "version": "29.4.3", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", + "jest-haste-map": "^29.5.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -8394,92 +6522,41 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-resolve/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-resolve/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -8487,81 +6564,31 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-runtime": { + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -8569,369 +6596,120 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.7.0", + "expect": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" + "pretty-format": "^29.5.0", + "semver": "^7.3.5" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-util": { + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-validate": { + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-snapshot/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-watcher": { + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", + "string-length": "^4.0.1" }, "engines": { - "node": ">=7.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "node_modules/jest-worker": { + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "jest-util": "^29.5.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-watcher/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" + "has-flag": "^4.0.0" }, "engines": { "node": ">=10" @@ -8941,45 +6719,39 @@ } }, "node_modules/joi": { - "version": "17.12.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.0.tgz", - "integrity": "sha512-HSLsmSmXz+PV9PYoi3p7cgIbj06WnEBNT28n+bbBNcPZXZFqCzzvGqpTBPujx/Z0nh1+KNQPDrNgdmQ8dq0qYw==", + "version": "17.9.2", + "license": "BSD-3-Clause", "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.4", + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.3", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } }, "node_modules/joi/node_modules/@hapi/hoek": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + "license": "BSD-3-Clause" }, "node_modules/jose": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", - "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", + "version": "4.14.4", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } }, "node_modules/js-stringify": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -8989,14 +6761,12 @@ }, "node_modules/jsbi": { "version": "3.2.5", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.2.5.tgz", - "integrity": "sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ==" + "license": "Apache-2.0" }, "node_modules/jsesc": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -9005,51 +6775,39 @@ } }, "node_modules/json-2-csv": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-3.20.0.tgz", - "integrity": "sha512-IbqUB+yaycVNB/q2fiY5kyRjy5kRiEXqvNvGlxM5L0Bfi0RdvklVHc4t9MfeYF1GsZVpZWDBs9LdWmSjsQ8jvg==", + "version": "3.18.0", + "license": "MIT", "dependencies": { - "deeks": "2.6.1", - "doc-path": "3.1.0" + "deeks": "2.6.0", + "doc-path": "3.0.6" }, "engines": { "node": ">= 12" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, "node_modules/json-parse-better-errors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -9059,8 +6817,7 @@ }, "node_modules/jsonc": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jsonc/-/jsonc-2.0.0.tgz", - "integrity": "sha512-B281bLCT2TRMQa+AQUQY5AGcqSOXBOKaYGP4wDzoA/+QswUfN8sODektbPEs9Baq7LGKun5jQbNFpzwGuVYKhw==", + "license": "MIT", "dependencies": { "fast-safe-stringify": "^2.0.6", "graceful-fs": "^4.1.15", @@ -9075,8 +6832,7 @@ }, "node_modules/jsonc/node_modules/mkdirp": { "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -9086,8 +6842,7 @@ }, "node_modules/jsonc/node_modules/parse-json": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "license": "MIT", "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -9097,20 +6852,14 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", + "integrity": "sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==", "dependencies": { "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", + "lodash": "^4.17.21", "ms": "^2.1.1", - "semver": "^7.5.4" + "semver": "^7.3.8" }, "engines": { "node": ">=12", @@ -9119,8 +6868,7 @@ }, "node_modules/jsonwebtoken/node_modules/jwa": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -9129,25 +6877,22 @@ }, "node_modules/jsonwebtoken/node_modules/jws": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, "node_modules/jssha": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.1.tgz", - "integrity": "sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==", + "version": "3.3.0", + "license": "BSD-3-Clause", "engines": { "node": "*" } }, "node_modules/jstransformer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", - "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "license": "MIT", "dependencies": { "is-promise": "^2.0.0", "promise": "^7.0.1" @@ -9155,8 +6900,7 @@ }, "node_modules/jwa": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "license": "MIT", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -9164,16 +6908,15 @@ } }, "node_modules/jwks-rsa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", - "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "version": "3.0.1", + "license": "MIT", "dependencies": { - "@types/express": "^4.17.17", - "@types/jsonwebtoken": "^9.0.2", + "@types/express": "^4.17.14", + "@types/jsonwebtoken": "^9.0.0", "debug": "^4.3.4", - "jose": "^4.14.6", + "jose": "^4.10.4", "limiter": "^1.1.5", - "lru-memoizer": "^2.2.0" + "lru-memoizer": "^2.1.4" }, "engines": { "node": ">=14" @@ -9181,8 +6924,7 @@ }, "node_modules/jws": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" @@ -9190,46 +6932,32 @@ }, "node_modules/keypress": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", - "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } + "license": "MIT" }, "node_modules/kleur": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/language-map": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/language-map/-/language-map-1.5.0.tgz", - "integrity": "sha512-n7gFZpe+DwEAX9cXVTw43i3wiudWDDtSn28RmdnS/HCPr284dQI/SztsamWanRr75oSlKSaGbV2nmWCTzGCoVg==" + "license": "MIT" }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -9239,110 +6967,116 @@ } }, "node_modules/lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "version": "2.1.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=14" + "node": ">=10" } }, "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + "version": "1.1.5" }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "version": "4.0.1", "dev": true, + "license": "MIT", "dependencies": { - "uc.micro": "^2.0.0" + "uc.micro": "^1.0.1" } }, "node_modules/lint-staged": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", - "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", + "version": "13.2.2", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "5.3.0", - "commander": "11.1.0", - "debug": "4.3.4", - "execa": "8.0.1", - "lilconfig": "3.0.0", - "listr2": "8.0.0", - "micromatch": "4.0.5", - "pidtree": "0.6.0", - "string-argv": "0.3.2", - "yaml": "2.3.4" + "chalk": "5.2.0", + "cli-truncate": "^3.1.0", + "commander": "^10.0.0", + "debug": "^4.3.4", + "execa": "^7.0.0", + "lilconfig": "2.1.0", + "listr2": "^5.0.7", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-inspect": "^1.12.3", + "pidtree": "^0.6.0", + "string-argv": "^0.3.1", + "yaml": "^2.2.2" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": ">=18.12.0" + "node": "^14.13.1 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/lint-staged" } }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/lint-staged/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "version": "7.1.1", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", - "signal-exit": "^4.1.0", + "signal-exit": "^3.0.7", "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=16.17" + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/lint-staged/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lint-staged/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "version": "4.3.1", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=16.17.0" + "node": ">=14.18.0" } }, "node_modules/lint-staged/node_modules/is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -9352,9 +7086,8 @@ }, "node_modules/lint-staged/node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -9363,10 +7096,9 @@ } }, "node_modules/lint-staged/node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.1.0", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -9377,14 +7109,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "node_modules/lint-staged/node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, + "license": "MIT", "engines": { "node": ">=12" }, @@ -9392,11 +7120,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { "node": ">=12" }, @@ -9404,52 +7134,75 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=14" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "node_modules/listr2": { + "version": "5.0.8", "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.19", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.8.0", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": ">=12" + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/cli-truncate": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", - "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", + "node_modules/listr2/node_modules/slice-ansi": { + "version": "3.0.0", "dev": true, + "license": "MIT", "dependencies": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", - "rfdc": "^1.3.0", - "wrap-ansi": "^9.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=8" } }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -9462,167 +7215,85 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "license": "MIT" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, - "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", - "dev": true, - "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-escapes": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", - "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", "dev": true, - "dependencies": { - "type-fest": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } + "license": "MIT" }, - "node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", - "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "node_modules/log-update": { + "version": "4.0.0", "dev": true, + "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.0.0" + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "version": "4.0.0", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/log-update/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", "dev": true, - "engines": { - "node": ">=14.16" + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "version": "5.2.0", + "license": "Apache-2.0" }, "node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": "14 || >=16.14" + "node": ">=10" } }, "node_modules/lru-memoizer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", - "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", + "version": "2.1.4", + "license": "MIT", "dependencies": { "lodash.clonedeep": "^4.5.0", "lru-cache": "~4.0.0" @@ -9630,8 +7301,7 @@ }, "node_modules/lru-memoizer/node_modules/lru-cache": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", + "license": "ISC", "dependencies": { "pseudomap": "^1.0.1", "yallist": "^2.0.0" @@ -9639,161 +7309,150 @@ }, "node_modules/lru-memoizer/node_modules/yallist": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + "license": "ISC" }, "node_modules/luxon": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", - "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", + "version": "3.3.0", + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "version": "3.1.0", "dev": true, + "license": "MIT", "dependencies": { - "semver": "^7.5.3" + "semver": "^6.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/make-error": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/makeerror": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } }, "node_modules/markdown-it": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.0.0.tgz", - "integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==", + "version": "13.0.1", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.0.0" + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" }, "bin": { - "markdown-it": "bin/markdown-it.mjs" + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "3.0.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/markdownlint": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.33.0.tgz", - "integrity": "sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==", + "version": "0.28.2", "dev": true, + "license": "MIT", "dependencies": { - "markdown-it": "14.0.0", - "markdownlint-micromark": "0.1.8" + "markdown-it": "13.0.1", + "markdownlint-micromark": "0.1.2" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/DavidAnson" + "node": ">=14.18.0" } }, "node_modules/markdownlint-cli2": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.12.0.tgz", - "integrity": "sha512-5nddNaPY1WC7BE1mkF8fiEkRDW8XbODwqYBPL3eyvFh7tLk74no+P8JRbCjghF7ozahCW5pF0TZ3ZS30m9H1Eg==", + "version": "0.7.1", "dev": true, + "license": "MIT", "dependencies": { - "globby": "14.0.0", - "markdownlint": "0.33.0", + "globby": "13.1.4", + "markdownlint": "0.28.2", "markdownlint-cli2-formatter-default": "0.0.4", "micromatch": "4.0.5", - "strip-json-comments": "5.0.1", - "yaml": "2.3.4" + "strip-json-comments": "5.0.0", + "yaml": "2.2.2" }, "bin": { - "markdownlint-cli2": "markdownlint-cli2.js" + "markdownlint-cli2": "markdownlint-cli2.js", + "markdownlint-cli2-config": "markdownlint-cli2-config.js", + "markdownlint-cli2-fix": "markdownlint-cli2-fix.js" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/DavidAnson" + "node": ">=14.18.0" } }, "node_modules/markdownlint-cli2-formatter-default": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.4.tgz", - "integrity": "sha512-xm2rM0E+sWgjpPn1EesPXx5hIyrN2ddUnUwnbCsD/ONxYtw3PX6LydvdH6dciWAoFDpwzbHM1TO7uHfcMd6IYg==", "dev": true, + "license": "MIT", "peerDependencies": { "markdownlint-cli2": ">=0.0.4" } }, "node_modules/markdownlint-cli2/node_modules/globby": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "version": "13.1.4", "dev": true, + "license": "MIT", "dependencies": { - "@sindresorhus/merge-streams": "^1.0.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" - }, - "engines": { - "node": ">=18" + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdownlint-cli2/node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true, "engines": { - "node": ">=12" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/markdownlint-cli2/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "version": "4.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=14.16" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/markdownlint-cli2/node_modules/strip-json-comments": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", - "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", + "version": "5.0.0", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -9802,69 +7461,57 @@ } }, "node_modules/markdownlint-micromark": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.8.tgz", - "integrity": "sha512-1ouYkMRo9/6gou9gObuMDnvZM8jC/ly3QCFQyoSPCS2XV1ZClU0xpKbL1Ar3bWWRT1RnBZkWUEiNKrI2CwiBQA==", + "version": "0.1.2", "dev": true, + "license": "MIT", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/DavidAnson" + "node": ">=14.18.0" } }, "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true + "version": "1.0.1", + "dev": true, + "license": "MIT" }, "node_modules/media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/memory-cache": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", - "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==" + "license": "BSD-2-Clause" }, "node_modules/merge-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "license": "MIT" }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -9875,8 +7522,7 @@ }, "node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -9886,16 +7532,14 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -9905,50 +7549,30 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, + "version": "3.1.2", + "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } + "version": "1.2.6", + "license": "MIT" }, "node_modules/mkdirp": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -9958,21 +7582,18 @@ }, "node_modules/module-details-from-path": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "license": "MIT" }, "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "version": "2.29.4", + "license": "MIT", "engines": { "node": "*" } }, "node_modules/morgan": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "license": "MIT", "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", @@ -9986,37 +7607,22 @@ }, "node_modules/morgan/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/morgan/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/morgan/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "license": "MIT" }, "node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "license": "MIT" }, "node_modules/mv": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "license": "MIT", "optional": true, "dependencies": { "mkdirp": "~0.5.1", @@ -10027,20 +7633,9 @@ "node": ">=0.8.0" } }, - "node_modules/mv/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/mv/node_modules/glob": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "license": "ISC", "optional": true, "dependencies": { "inflight": "^1.0.4", @@ -10053,22 +7648,9 @@ "node": "*" } }, - "node_modules/mv/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "optional": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/mv/node_modules/mkdirp": { "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", "optional": true, "dependencies": { "minimist": "^1.2.6" @@ -10079,8 +7661,7 @@ }, "node_modules/mv/node_modules/rimraf": { "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "license": "ISC", "optional": true, "dependencies": { "glob": "^6.0.1" @@ -10090,21 +7671,23 @@ } }, "node_modules/nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "version": "2.15.0", + "license": "MIT", "optional": true }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "dev": true, + "license": "MIT" }, "node_modules/ncp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "license": "MIT", "optional": true, "bin": { "ncp": "bin/ncp" @@ -10112,21 +7695,18 @@ }, "node_modules/negotiator": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/node-abort-controller": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" + "license": "MIT" }, "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "version": "2.6.11", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -10142,24 +7722,37 @@ } } }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-forge": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } }, "node_modules/node-int64": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-jose": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.2.0.tgz", - "integrity": "sha512-XPCvJRr94SjLrSIm4pbYHKLEaOsDvJCpyFw/6V/KK/IXmyZ6SFBzAUDO9HQf4DB/nTEFcRGH87mNciOP23kFjw==", + "license": "Apache-2.0", "dependencies": { "base64url": "^3.0.1", "buffer": "^6.0.3", @@ -10173,45 +7766,37 @@ } }, "node_modules/node-jose/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], + "version": "9.0.0", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.10", + "dev": true, + "license": "MIT" }, "node_modules/nodemailer": { - "version": "6.9.8", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.8.tgz", - "integrity": "sha512-cfrYUk16e67Ks051i4CntM9kshRYei1/o/Gi8K1d+R34OIs21xdFnW7Pt7EucmVKA0LKtqUGNcjMZ7ehjl49mQ==", + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.4.tgz", + "integrity": "sha512-CXjQvrQZV4+6X5wP6ZIgdehJamI63MFoYFGGPtHudWym9qaEHDNdPzaj5bfMCvxG1vhAileSWW90q7nL0N36mA==", "engines": { "node": ">=6.0.0" } }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -10221,43 +7806,41 @@ }, "node_modules/oauth": { "version": "0.9.15", - "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", - "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" + "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.12.3", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-path": { "version": "0.11.8", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz", - "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==", + "license": "MIT", "engines": { "node": ">= 10.12.0" } }, "node_modules/obuf": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/octicons": { + "version": "5.0.1", + "license": "(OFL-1.1 OR MIT)" }, "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "version": "2.3.0", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -10267,25 +7850,22 @@ }, "node_modules/on-headers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -10297,9 +7877,8 @@ } }, "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "version": "8.4.0", + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -10313,17 +7892,16 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.1", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { "node": ">= 0.8.0" @@ -10331,9 +7909,8 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -10346,9 +7923,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -10359,30 +7935,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/packet-reader": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + "license": "MIT" }, "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + "version": "2.0.4", + "license": "(MIT AND Zlib)" }, "node_modules/parent-module": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", - "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.1.0" }, @@ -10392,9 +7978,8 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -10410,16 +7995,14 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/passport": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", - "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", + "version": "0.6.0", + "license": "MIT", "dependencies": { "passport-strategy": "1.x.x", "pause": "0.0.1", @@ -10435,8 +8018,7 @@ }, "node_modules/passport-azure-ad": { "version": "4.3.5", - "resolved": "https://registry.npmjs.org/passport-azure-ad/-/passport-azure-ad-4.3.5.tgz", - "integrity": "sha512-LBpXEght7hCMuMNFK4oegdN0uPBa3lpDMy71zQoB0zPg1RrGwdzpjwTiN1WzN0hY77fLyjz9tBr3TGAxnSgtEg==", + "license": "MIT", "dependencies": { "async": "^3.2.3", "base64url": "^3.0.0", @@ -10454,10 +8036,13 @@ "node": ">= 8.0.0" } }, + "node_modules/passport-azure-ad/node_modules/async": { + "version": "3.2.4", + "license": "MIT" + }, "node_modules/passport-azure-ad/node_modules/jwa": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -10466,34 +8051,15 @@ }, "node_modules/passport-azure-ad/node_modules/jws": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, - "node_modules/passport-azure-ad/node_modules/passport": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", - "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", - "dependencies": { - "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, "node_modules/passport-github": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/passport-github/-/passport-github-1.1.0.tgz", - "integrity": "sha512-XARXJycE6fFh/dxF+Uut8OjlwbFEXgbPVj/+V+K7cvriRK7VcAOm+NgBmbiLM9Qv3SSxEAV+V6fIk89nYHXa8A==", + "license": "MIT", "dependencies": { "passport-oauth2": "1.x.x" }, @@ -10502,9 +8068,8 @@ } }, "node_modules/passport-oauth2": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz", - "integrity": "sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==", + "version": "1.6.1", + "license": "MIT", "dependencies": { "base64url": "3.x.x", "oauth": "0.9.x", @@ -10522,93 +8087,65 @@ }, "node_modules/passport-strategy": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", "engines": { "node": ">= 0.4.0" } }, "node_modules/path-browserify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "license": "MIT" }, "node_modules/path-to-regexp": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" + "version": "0.0.1" }, "node_modules/pg": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", - "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "version": "8.11.0", + "license": "MIT", "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.6.2", - "pg-pool": "^3.6.1", + "pg-connection-string": "^2.6.0", + "pg-pool": "^3.6.0", "pg-protocol": "^1.6.0", "pg-types": "^2.1.0", "pgpass": "1.x" @@ -10617,7 +8154,7 @@ "node": ">= 8.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.1.1" + "pg-cloudflare": "^1.1.0" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -10629,73 +8166,47 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "version": "1.1.0", + "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", - "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + "version": "2.6.0", + "license": "MIT" }, "node_modules/pg-escape": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/pg-escape/-/pg-escape-0.2.0.tgz", - "integrity": "sha512-QfXcpxyN9vT+kvexQpTeNyiwCxs4LPXLAV/C0EeLTJPCF61swhGdDlnHcuDgxJudgKGfQYiCkegg0GsSKSvvEg==" + "license": "MIT" }, "node_modules/pg-int8": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", "engines": { "node": ">=4.0.0" } }, "node_modules/pg-numeric": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", - "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", "dev": true, + "license": "ISC", "engines": { "node": ">=4" } }, "node_modules/pg-pool": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", - "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "version": "3.6.0", + "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + "license": "MIT" }, "node_modules/pg-types": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", - "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", - "dev": true, - "dependencies": { - "pg-int8": "1.0.1", - "pg-numeric": "1.0.2", - "postgres-array": "~3.0.1", - "postgres-bytea": "~3.0.0", - "postgres-date": "~2.0.1", - "postgres-interval": "^3.0.0", - "postgres-range": "^1.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pg/node_modules/pg-types": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", @@ -10707,60 +8218,22 @@ "node": ">=4" } }, - "node_modules/pg/node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/pg/node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pg/node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pg/node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pgpass": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", "dependencies": { "split2": "^4.1.0" } }, "node_modules/picocolors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -10770,9 +8243,8 @@ }, "node_modules/pidtree": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "dev": true, + "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -10781,19 +8253,17 @@ } }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.5", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -10803,9 +8273,8 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -10816,9 +8285,8 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -10828,9 +8296,8 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -10843,9 +8310,8 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -10854,69 +8320,58 @@ } }, "node_modules/postgres-array": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", - "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", - "dev": true, + "version": "2.0.0", + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=4" } }, "node_modules/postgres-bytea": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", - "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", - "dev": true, - "dependencies": { - "obuf": "~1.1.2" - }, + "version": "1.0.0", + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, "node_modules/postgres-date": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", - "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", - "dev": true, + "version": "1.0.7", + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, "node_modules/postgres-interval": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", - "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", - "dev": true, + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, "node_modules/postgres-range": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", - "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", - "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "version": "2.8.8", "dev": true, + "license": "MIT", "bin": { - "prettier": "bin/prettier.cjs" + "prettier": "bin-prettier.js" }, "engines": { - "node": ">=14" + "node": ">=10.13.0" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -10924,9 +8379,8 @@ }, "node_modules/prettier-linter-helpers": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, + "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -10935,12 +8389,11 @@ } }, "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "version": "29.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -10948,32 +8401,39 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/priorityqueuejs": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz", - "integrity": "sha512-lg++21mreCEOuGWTbO5DnJKAdxfjrdN0S9ysoW9SzdSJvbkWpkaDdpG/cdsPCsEnoLUwmd9m3WcZhngW7yKA2g==" + "license": "MIT" }, "node_modules/process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/promise": { "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "license": "MIT", "dependencies": { "asap": "~2.0.3" } }, "node_modules/prompts": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -10984,8 +8444,7 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -10996,18 +8455,15 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "license": "MIT" }, "node_modules/pseudomap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + "license": "ISC" }, "node_modules/pug": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", - "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "license": "MIT", "dependencies": { "pug-code-gen": "^3.0.2", "pug-filters": "^4.0.0", @@ -11021,8 +8477,7 @@ }, "node_modules/pug-attrs": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", - "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "license": "MIT", "dependencies": { "constantinople": "^4.0.1", "js-stringify": "^1.0.2", @@ -11031,8 +8486,7 @@ }, "node_modules/pug-code-gen": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", - "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "license": "MIT", "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", @@ -11046,13 +8500,11 @@ }, "node_modules/pug-error": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", - "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + "license": "MIT" }, "node_modules/pug-filters": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", - "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "license": "MIT", "dependencies": { "constantinople": "^4.0.1", "jstransformer": "1.0.0", @@ -11063,8 +8515,7 @@ }, "node_modules/pug-lexer": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", - "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "license": "MIT", "dependencies": { "character-parser": "^2.2.0", "is-expression": "^4.0.0", @@ -11073,8 +8524,7 @@ }, "node_modules/pug-linker": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", - "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "license": "MIT", "dependencies": { "pug-error": "^2.0.0", "pug-walk": "^2.0.0" @@ -11082,8 +8532,7 @@ }, "node_modules/pug-load": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", - "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "license": "MIT", "dependencies": { "object-assign": "^4.1.1", "pug-walk": "^2.0.0" @@ -11091,8 +8540,7 @@ }, "node_modules/pug-parser": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", - "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "license": "MIT", "dependencies": { "pug-error": "^2.0.0", "token-stream": "1.0.0" @@ -11100,44 +8548,29 @@ }, "node_modules/pug-runtime": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", - "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + "license": "MIT" }, "node_modules/pug-strip-comments": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", - "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "license": "MIT", "dependencies": { "pug-error": "^2.0.0" } }, "node_modules/pug-walk": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", - "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + "license": "MIT" }, "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "version": "2.1.1", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "version": "6.0.2", "dev": true, "funding": [ { @@ -11148,12 +8581,12 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/qs": { "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -11166,8 +8599,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -11182,28 +8613,26 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/random-bytes": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -11216,14 +8645,12 @@ }, "node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/recursive-readdir": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "license": "MIT", "dependencies": { "minimatch": "^3.0.5" }, @@ -11231,76 +8658,52 @@ "node": ">=6.0.0" } }, - "node_modules/recursive-readdir/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/recursive-readdir/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/redis": { - "version": "4.6.12", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.12.tgz", - "integrity": "sha512-41Xuuko6P4uH4VPe5nE3BqXHB7a9lkFL0J29AlxKaIfD6eWO8VO/5PDF9ad2oS+mswMsfFxaM5DlE3tnXT+P8Q==", + "version": "4.6.8", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", + "integrity": "sha512-S7qNkPUYrsofQ0ztWlTHSaK0Qqfl1y+WMIxrzeAGNG+9iUZB4HGeBgkHxE6uJJ6iXrkvLd1RVJ2nvu6H1sAzfQ==", "dependencies": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.13", - "@redis/graph": "1.1.1", - "@redis/json": "1.0.6", - "@redis/search": "1.1.6", + "@redis/client": "1.5.9", + "@redis/graph": "1.1.0", + "@redis/json": "1.0.4", + "@redis/search": "1.1.3", "@redis/time-series": "1.0.5" } }, "node_modules/repeat-string": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10" } }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-in-the-middle": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz", - "integrity": "sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw==", + "version": "5.2.0", + "license": "MIT", "dependencies": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", "resolve": "^1.22.1" }, "engines": { - "node": ">=8.6.0" + "node": ">=6" } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.2", + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.11.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -11313,9 +8716,8 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -11325,75 +8727,67 @@ }, "node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/resolve-pkg-maps": { + "node_modules/resolve-global": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + "license": "MIT", + "dependencies": { + "global-dirs": "^0.1.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/resolve.exports": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "version": "3.1.0", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rfdc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", - "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", - "dev": true + "version": "1.3.0", + "dev": true, + "license": "MIT" }, "node_modules/rhea": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rhea/-/rhea-3.0.2.tgz", - "integrity": "sha512-0G1ZNM9yWin8VLvTxyISKH6KfR6gl1TW/1+5yMKPf2r1efhkzTLze09iFtT2vpDjuWIVtSmXz8r18lk/dO8qwQ==", + "license": "Apache-2.0", "dependencies": { "debug": "^4.3.3" } }, "node_modules/rhea-promise": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rhea-promise/-/rhea-promise-3.0.1.tgz", - "integrity": "sha512-Fcqgml7lgoyi7fH1ClsSyFr/xwToijEN3rULFgrIcL+7EHeduxkWogFxNHjFzHf2YGScAckJDaDxS1RdlTUQYw==", + "license": "Apache-2.0", "dependencies": { "debug": "^3.1.0", "rhea": "^3.0.0", @@ -11402,47 +8796,19 @@ }, "node_modules/rhea-promise/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, + "version": "3.0.2", + "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "glob": "^7.1.3" }, "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -11450,8 +8816,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -11467,48 +8831,49 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "license": "MIT" }, "node_modules/safe-json-stringify": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", - "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "license": "MIT", "optional": true }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "license": "MIT" }, "node_modules/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + "version": "1.2.4", + "license": "ISC" }, "node_modules/secure-compare": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==" + "license": "MIT" }, "node_modules/semaphore": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", - "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==", "engines": { "node": ">=0.8.0" } }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.5.1", + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -11519,21 +8884,9 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/send": { "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -11555,26 +8908,32 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "license": "MIT" + }, + "node_modules/send/node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, "node_modules/serve-favicon": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", - "integrity": "sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==", + "license": "MIT", "dependencies": { "etag": "~1.8.1", "fresh": "0.5.2", @@ -11588,18 +8947,15 @@ }, "node_modules/serve-favicon/node_modules/ms": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "license": "MIT" }, "node_modules/serve-favicon/node_modules/safe-buffer": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "license": "MIT" }, "node_modules/serve-static": { "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -11610,31 +8966,14 @@ "node": ">= 0.8.0" } }, - "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", - "dependencies": { - "define-data-property": "^1.1.1", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -11644,22 +8983,19 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shimmer": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + "license": "BSD-2-Clause" }, "node_modules/side-channel": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -11671,14 +9007,12 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/simple-oauth2": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/simple-oauth2/-/simple-oauth2-5.0.0.tgz", - "integrity": "sha512-8291lo/z5ZdpmiOFzOs1kF3cxn22bMj5FFH+DNUppLJrpoIlM1QnFiE7KpshHu3J3i21TVcx4yW+gXYjdCKDLQ==", + "license": "Apache-2.0", "dependencies": { "@hapi/hoek": "^10.0.1", "@hapi/wreck": "^18.0.0", @@ -11688,24 +9022,21 @@ }, "node_modules/sisteransi": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slice-ansi": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -11719,9 +9050,8 @@ }, "node_modules/slice-ansi/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -11729,49 +9059,54 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-support": { "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "version": "4.1.0", + "license": "ISC", "engines": { "node": ">= 10.x" } }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/stack-chain": { "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==" + "license": "MIT" }, "node_modules/stack-utils": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -11781,25 +9116,22 @@ }, "node_modules/stack-utils/node_modules/escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/stoppable": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", - "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "license": "MIT", "engines": { "node": ">=4", "npm": ">=6" @@ -11807,18 +9139,16 @@ }, "node_modules/string-argv": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6.19" } }, "node_modules/string-length": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -11827,50 +9157,10 @@ "node": ">=10" } }, - "node_modules/string-length/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-length/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string-width": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", - "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", - "dev": true, - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11880,63 +9170,10 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11944,36 +9181,24 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -11983,14 +9208,12 @@ }, "node_modules/strnum": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + "license": "MIT" }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -12000,8 +9223,7 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -12009,27 +9231,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/synckit": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", - "dev": true, - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/test-exclude": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -12039,43 +9244,23 @@ "node": ">=8" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/throat": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", - "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" }, "node_modules/tmp": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "license": "MIT", "dependencies": { "rimraf": "^3.0.0" }, @@ -12085,45 +9270,27 @@ }, "node_modules/tmp-promise": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "license": "MIT", "dependencies": { "tmp": "^0.2.0" } }, - "node_modules/tmp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/tmpl": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -12133,48 +9300,27 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/token-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", - "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "license": "MIT" }, "node_modules/true-myth": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/true-myth/-/true-myth-4.1.1.tgz", - "integrity": "sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg==", "dev": true, + "license": "MIT", "engines": { "node": "10.* || >= 12.*" } }, - "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", - "dev": true, - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, "node_modules/ts-jest": { - "version": "29.1.1", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", - "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", + "version": "29.1.0", "dev": true, + "license": "MIT", "dependencies": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", @@ -12182,7 +9328,7 @@ "json5": "^2.2.3", "lodash.memoize": "4.x", "make-error": "1.x", - "semver": "^7.5.3", + "semver": "7.x", "yargs-parser": "^21.0.1" }, "bin": { @@ -12215,19 +9361,17 @@ }, "node_modules/ts-morph": { "version": "13.0.3", - "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-13.0.3.tgz", - "integrity": "sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw==", "dev": true, + "license": "MIT", "dependencies": { "@ts-morph/common": "~0.12.3", "code-block-writer": "^11.0.0" } }, "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "version": "10.9.1", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -12268,9 +9412,8 @@ }, "node_modules/ts-prune": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/ts-prune/-/ts-prune-0.10.3.tgz", - "integrity": "sha512-iS47YTbdIcvN8Nh/1BFyziyUqmjXz7GVzWu02RaZXqb+e/3Qe1B7IQ4860krOeCGUeJmterAlaM2FRH0Ue0hjw==", "dev": true, + "license": "MIT", "dependencies": { "commander": "^6.2.1", "cosmiconfig": "^7.0.1", @@ -12285,31 +9428,69 @@ }, "node_modules/ts-prune/node_modules/commander": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "node_modules/ts-prune/node_modules/cosmiconfig": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "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/ts-prune/node_modules/yaml": { + "version": "1.10.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "license": "0BSD" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "license": "MIT", "engines": { "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -12319,18 +9500,16 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -12340,8 +9519,7 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -12352,36 +9530,32 @@ }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, + "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.0.4", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=14.17" + "node": ">=12.20" } }, "node_modules/uc.micro": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.0.0.tgz", - "integrity": "sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==", - "dev": true + "version": "1.0.6", + "dev": true, + "license": "MIT" }, "node_modules/uid-safe": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "license": "MIT", "dependencies": { "random-bytes": "~1.0.0" }, @@ -12391,67 +9565,40 @@ }, "node_modules/uid2": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", - "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==" - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "version": "2.0.0", "dev": true, + "license": "MIT", "dependencies": { - "crypto-random-string": "^4.0.0" + "crypto-random-string": "^2.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/universal-github-app-jwt": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.2.tgz", - "integrity": "sha512-t1iB2FmLFE+yyJY9+3wMx0ejB+MQpEVkH0gQv7dR6FZyltyq+ZZO0uDpbopxhrZ3SLEO4dCEkIujOMldEQ2iOA==", + "version": "1.1.1", + "license": "MIT", "dependencies": { "@types/jsonwebtoken": "^9.0.0", - "jsonwebtoken": "^9.0.2" + "jsonwebtoken": "^9.0.0" } }, "node_modules/universal-user-agent": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" + "version": "6.0.0", + "license": "ISC" }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.0.11", "dev": true, "funding": [ { @@ -12467,6 +9614,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -12480,17 +9628,15 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/util": { "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -12501,117 +9647,94 @@ }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "version": "9.1.0", "dev": true, + "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" + "convert-source-map": "^1.6.0" }, "engines": { "node": ">=10.12.0" } }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, "node_modules/valid-url": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" + "version": "1.0.9" }, "node_modules/validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "version": "13.9.0", + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/void-elements": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz", - "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==", - "dev": true + "version": "1.0.8", + "dev": true, + "license": "MIT" }, "node_modules/vscode-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", - "dev": true + "version": "3.0.7", + "dev": true, + "license": "MIT" }, "node_modules/walk-back": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.0.tgz", - "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==", + "license": "MIT", "engines": { "node": ">=12.17" } }, "node_modules/walker": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -12623,15 +9746,15 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "version": "1.1.9", + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", + "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" }, "engines": { "node": ">= 0.4" @@ -12642,8 +9765,7 @@ }, "node_modules/with": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", - "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "license": "MIT", "dependencies": { "@babel/parser": "^7.9.6", "@babel/types": "^7.9.6", @@ -12654,29 +9776,18 @@ "node": ">= 10.0.0" } }, - "node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "node_modules/word-wrap": { + "version": "1.2.3", "dev": true, - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, + "license": "MIT", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", + "node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -12689,192 +9800,73 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "license": "ISC" }, "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "version": "4.0.2", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "version": "4.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/xml": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", - "dev": true - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } + "dev": true, + "license": "MIT" }, "node_modules/xmlbuilder": { "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", "engines": { "node": ">=4.0" } }, "node_modules/xtend": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", "engines": { "node": ">=0.4" } }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "license": "ISC" }, "node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "version": "2.2.2", "dev": true, + "license": "ISC", "engines": { "node": ">= 14" } }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -12890,77 +9882,24 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yn": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -12968,5 +9907,6344 @@ "url": "https://github.com/sponsors/sindresorhus" } } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.1", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@azure/abort-controller": { + "version": "1.0.4", + "requires": { + "tslib": "^2.0.0" + } + }, + "@azure/core-amqp": { + "version": "3.3.0", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-util": "^1.1.1", + "@azure/logger": "^1.0.0", + "buffer": "^6.0.0", + "events": "^3.0.0", + "jssha": "^3.1.0", + "process": "^0.11.10", + "rhea": "^3.0.0", + "rhea-promise": "^3.0.0", + "tslib": "^2.2.0", + "util": "^0.12.1" + }, + "dependencies": { + "@azure/core-util": { + "version": "1.3.2", + "requires": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + } + } + } + }, + "@azure/core-asynciterator-polyfill": { + "version": "1.0.2" + }, + "@azure/core-auth": { + "version": "1.4.0", + "requires": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + } + }, + "@azure/core-client": { + "version": "1.5.0", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-asynciterator-polyfill": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-rest-pipeline": "^1.5.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + } + }, + "@azure/core-http-compat": { + "version": "1.3.0", + "requires": { + "@azure/abort-controller": "^1.0.4", + "@azure/core-client": "^1.3.0", + "@azure/core-rest-pipeline": "^1.3.0" + } + }, + "@azure/core-lro": { + "version": "2.2.4", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + } + }, + "@azure/core-paging": { + "version": "1.5.0", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/core-rest-pipeline": { + "version": "1.10.1", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "form-data": "^4.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "requires": { + "tslib": "^2.2.0" + } + } + } + }, + "@azure/core-tracing": { + "version": "1.0.0-preview.13", + "requires": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + } + }, + "@azure/core-util": { + "version": "1.2.0", + "requires": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + } + }, + "@azure/core-xml": { + "version": "1.3.3", + "requires": { + "fast-xml-parser": "^4.0.8", + "tslib": "^2.2.0" + } + }, + "@azure/cosmos": { + "version": "3.17.3", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-rest-pipeline": "^1.2.0", + "@azure/core-tracing": "^1.0.0", + "debug": "^4.1.1", + "fast-json-stable-stringify": "^2.1.0", + "jsbi": "^3.1.3", + "node-abort-controller": "^3.0.0", + "priorityqueuejs": "^1.0.0", + "semaphore": "^1.0.5", + "tslib": "^2.2.0", + "universal-user-agent": "^6.0.0", + "uuid": "^8.3.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "requires": { + "tslib": "^2.2.0" + } + } + } + }, + "@azure/data-tables": { + "version": "13.2.2", + "requires": { + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-xml": "^1.0.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "requires": { + "tslib": "^2.2.0" + } + } + } + }, + "@azure/identity": { + "version": "3.2.2", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.4.0", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^2.32.2", + "@azure/msal-common": "^9.0.2", + "@azure/msal-node": "^1.14.6", + "events": "^3.0.0", + "jws": "^4.0.0", + "open": "^8.0.0", + "stoppable": "^1.1.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "requires": { + "tslib": "^2.2.0" + } + } + } + }, + "@azure/keyvault-secrets": { + "version": "4.7.0", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.5.0", + "@azure/core-http-compat": "^1.3.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-rest-pipeline": "^1.8.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "requires": { + "tslib": "^2.2.0" + } + } + } + }, + "@azure/logger": { + "version": "1.0.3", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/msal-browser": { + "version": "2.37.0", + "requires": { + "@azure/msal-common": "13.0.0" + }, + "dependencies": { + "@azure/msal-common": { + "version": "13.0.0" + } + } + }, + "@azure/msal-common": { + "version": "9.1.1" + }, + "@azure/msal-node": { + "version": "1.17.2", + "requires": { + "@azure/msal-common": "13.0.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "dependencies": { + "@azure/msal-common": { + "version": "13.0.0" + } + } + }, + "@azure/opentelemetry-instrumentation-azure-sdk": { + "version": "1.0.0-beta.3", + "requires": { + "@azure/core-tracing": "^1.0.0", + "@azure/logger": "^1.0.0", + "@opentelemetry/api": "^1.4.0", + "@opentelemetry/core": "^1.9.0", + "@opentelemetry/instrumentation": "^0.35.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "requires": { + "tslib": "^2.2.0" + } + } + } + }, + "@azure/service-bus": { + "version": "7.9.0", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-amqp": "^3.3.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-paging": "^1.4.0", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.1.1", + "@azure/core-xml": "^1.0.0", + "@azure/logger": "^1.0.0", + "@types/is-buffer": "^2.0.0", + "buffer": "^6.0.0", + "is-buffer": "^2.0.3", + "jssha": "^3.1.0", + "long": "^5.2.0", + "process": "^0.11.10", + "rhea-promise": "^3.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "requires": { + "tslib": "^2.2.0" + } + }, + "@azure/core-util": { + "version": "1.3.2", + "requires": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + } + } + } + }, + "@azure/storage-blob": { + "version": "12.14.0", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-http": "^3.0.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "events": "^3.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/core-http": { + "version": "3.0.1", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", + "@azure/logger": "^1.0.0", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.5.0" + } + }, + "xml2js": { + "version": "0.5.0", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + } + } + }, + "@azure/storage-queue": { + "version": "12.14.0", + "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.14.0.tgz", + "integrity": "sha512-1j6uxhzCcbEDVPOTNWIJ5CsLzOAU5U/bXgGZeT25fy6IghFTC1JlPGALez2CWJ9fBVj6AmSnsiBXL/77iXhSpg==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-http": "^3.0.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/core-http": { + "version": "3.0.1", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", + "@azure/logger": "^1.0.0", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.5.0" + } + }, + "xml2js": { + "version": "0.5.0", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + } + } + }, + "@babel/code-frame": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.21.7", + "dev": true + }, + "@babel/core": { + "version": "7.21.8", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helpers": "^7.21.5", + "@babel/parser": "^7.21.8", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "dev": true + }, + "semver": { + "version": "6.3.0", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.21.5", + "dev": true, + "requires": { + "@babel/types": "^7.21.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.21.5", + "dev": true, + "requires": { + "@babel/compat-data": "^7.21.5", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "semver": { + "version": "6.3.0", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.21.5", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/types": "^7.21.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.21.5", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-simple-access": "^7.21.5", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.21.5", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.21.5", + "dev": true, + "requires": { + "@babel/types": "^7.21.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.21.5" + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1" + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "dev": true + }, + "@babel/helpers": { + "version": "7.21.5", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.21.8" + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.21.4", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/template": { + "version": "7.20.7", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.5", + "dev": true, + "requires": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.21.5", + "requires": { + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true + }, + "@cspell/cspell-bundled-dicts": { + "version": "6.31.1", + "dev": true, + "requires": { + "@cspell/dict-ada": "^4.0.1", + "@cspell/dict-aws": "^3.0.0", + "@cspell/dict-bash": "^4.1.1", + "@cspell/dict-companies": "^3.0.9", + "@cspell/dict-cpp": "^5.0.2", + "@cspell/dict-cryptocurrencies": "^3.0.1", + "@cspell/dict-csharp": "^4.0.2", + "@cspell/dict-css": "^4.0.5", + "@cspell/dict-dart": "^2.0.2", + "@cspell/dict-django": "^4.0.2", + "@cspell/dict-docker": "^1.1.6", + "@cspell/dict-dotnet": "^5.0.0", + "@cspell/dict-elixir": "^4.0.2", + "@cspell/dict-en_us": "^4.3.2", + "@cspell/dict-en-common-misspellings": "^1.0.2", + "@cspell/dict-en-gb": "1.1.33", + "@cspell/dict-filetypes": "^3.0.0", + "@cspell/dict-fonts": "^3.0.1", + "@cspell/dict-fullstack": "^3.1.5", + "@cspell/dict-gaming-terms": "^1.0.4", + "@cspell/dict-git": "^2.0.0", + "@cspell/dict-golang": "^6.0.1", + "@cspell/dict-haskell": "^4.0.1", + "@cspell/dict-html": "^4.0.3", + "@cspell/dict-html-symbol-entities": "^4.0.0", + "@cspell/dict-java": "^5.0.5", + "@cspell/dict-k8s": "^1.0.1", + "@cspell/dict-latex": "^4.0.0", + "@cspell/dict-lorem-ipsum": "^3.0.0", + "@cspell/dict-lua": "^4.0.1", + "@cspell/dict-node": "^4.0.2", + "@cspell/dict-npm": "^5.0.5", + "@cspell/dict-php": "^4.0.1", + "@cspell/dict-powershell": "^5.0.1", + "@cspell/dict-public-licenses": "^2.0.2", + "@cspell/dict-python": "^4.0.2", + "@cspell/dict-r": "^2.0.1", + "@cspell/dict-ruby": "^5.0.0", + "@cspell/dict-rust": "^4.0.1", + "@cspell/dict-scala": "^5.0.0", + "@cspell/dict-software-terms": "^3.1.6", + "@cspell/dict-sql": "^2.1.0", + "@cspell/dict-svelte": "^1.0.2", + "@cspell/dict-swift": "^2.0.1", + "@cspell/dict-typescript": "^3.1.1", + "@cspell/dict-vue": "^3.0.0" + } + }, + "@cspell/cspell-pipe": { + "version": "6.31.1", + "dev": true + }, + "@cspell/cspell-service-bus": { + "version": "6.31.1", + "dev": true + }, + "@cspell/cspell-types": { + "version": "6.31.1", + "dev": true + }, + "@cspell/dict-ada": { + "version": "4.0.1", + "dev": true + }, + "@cspell/dict-aws": { + "version": "3.0.0", + "dev": true + }, + "@cspell/dict-bash": { + "version": "4.1.1", + "dev": true + }, + "@cspell/dict-companies": { + "version": "3.0.10", + "dev": true + }, + "@cspell/dict-cpp": { + "version": "5.0.3", + "dev": true + }, + "@cspell/dict-cryptocurrencies": { + "version": "3.0.1", + "dev": true + }, + "@cspell/dict-csharp": { + "version": "4.0.2", + "dev": true + }, + "@cspell/dict-css": { + "version": "4.0.6", + "dev": true + }, + "@cspell/dict-dart": { + "version": "2.0.2", + "dev": true + }, + "@cspell/dict-django": { + "version": "4.0.2", + "dev": true + }, + "@cspell/dict-docker": { + "version": "1.1.6", + "dev": true + }, + "@cspell/dict-dotnet": { + "version": "5.0.0", + "dev": true + }, + "@cspell/dict-elixir": { + "version": "4.0.3", + "dev": true + }, + "@cspell/dict-en_us": { + "version": "4.3.2", + "dev": true + }, + "@cspell/dict-en-common-misspellings": { + "version": "1.0.2", + "dev": true + }, + "@cspell/dict-en-gb": { + "version": "1.1.33", + "dev": true + }, + "@cspell/dict-filetypes": { + "version": "3.0.0", + "dev": true + }, + "@cspell/dict-fonts": { + "version": "3.0.2", + "dev": true + }, + "@cspell/dict-fullstack": { + "version": "3.1.5", + "dev": true + }, + "@cspell/dict-gaming-terms": { + "version": "1.0.4", + "dev": true + }, + "@cspell/dict-git": { + "version": "2.0.0", + "dev": true + }, + "@cspell/dict-golang": { + "version": "6.0.1", + "dev": true + }, + "@cspell/dict-haskell": { + "version": "4.0.1", + "dev": true + }, + "@cspell/dict-html": { + "version": "4.0.3", + "dev": true + }, + "@cspell/dict-html-symbol-entities": { + "version": "4.0.0", + "dev": true + }, + "@cspell/dict-java": { + "version": "5.0.5", + "dev": true + }, + "@cspell/dict-k8s": { + "version": "1.0.1", + "dev": true + }, + "@cspell/dict-latex": { + "version": "4.0.0", + "dev": true + }, + "@cspell/dict-lorem-ipsum": { + "version": "3.0.0", + "dev": true + }, + "@cspell/dict-lua": { + "version": "4.0.1", + "dev": true + }, + "@cspell/dict-node": { + "version": "4.0.2", + "dev": true + }, + "@cspell/dict-npm": { + "version": "5.0.5", + "dev": true + }, + "@cspell/dict-php": { + "version": "4.0.1", + "dev": true + }, + "@cspell/dict-powershell": { + "version": "5.0.1", + "dev": true + }, + "@cspell/dict-public-licenses": { + "version": "2.0.2", + "dev": true + }, + "@cspell/dict-python": { + "version": "4.0.4", + "dev": true + }, + "@cspell/dict-r": { + "version": "2.0.1", + "dev": true + }, + "@cspell/dict-ruby": { + "version": "5.0.0", + "dev": true + }, + "@cspell/dict-rust": { + "version": "4.0.1", + "dev": true + }, + "@cspell/dict-scala": { + "version": "5.0.0", + "dev": true + }, + "@cspell/dict-software-terms": { + "version": "3.1.8", + "dev": true + }, + "@cspell/dict-sql": { + "version": "2.1.0", + "dev": true + }, + "@cspell/dict-svelte": { + "version": "1.0.2", + "dev": true + }, + "@cspell/dict-swift": { + "version": "2.0.1", + "dev": true + }, + "@cspell/dict-typescript": { + "version": "3.1.1", + "dev": true + }, + "@cspell/dict-vue": { + "version": "3.0.0", + "dev": true + }, + "@cspell/dynamic-import": { + "version": "6.31.1", + "dev": true, + "requires": { + "import-meta-resolve": "^2.2.2" + } + }, + "@cspell/strong-weak-map": { + "version": "6.31.1", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.5.1", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.0.3", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.2", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@eslint/js": { + "version": "8.41.0", + "dev": true + }, + "@hapi/boom": { + "version": "10.0.1", + "requires": { + "@hapi/hoek": "^11.0.2" + }, + "dependencies": { + "@hapi/hoek": { + "version": "11.0.2" + } + } + }, + "@hapi/bourne": { + "version": "3.0.0" + }, + "@hapi/hoek": { + "version": "10.0.1" + }, + "@hapi/topo": { + "version": "5.1.0", + "requires": { + "@hapi/hoek": "^9.0.0" + }, + "dependencies": { + "@hapi/hoek": { + "version": "9.3.0" + } + } + }, + "@hapi/wreck": { + "version": "18.0.1", + "requires": { + "@hapi/boom": "^10.0.1", + "@hapi/bourne": "^3.0.0", + "@hapi/hoek": "^11.0.2" + }, + "dependencies": { + "@hapi/hoek": { + "version": "11.0.2" + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "find-up": { + "version": "4.1.0", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "dev": true + }, + "@jest/console": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0" + } + }, + "@jest/expect": { + "version": "29.5.0", + "dev": true, + "requires": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + } + }, + "@jest/expect-utils": { + "version": "29.5.0", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3" + } + }, + "@jest/fake-timers": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "@jest/globals": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" + } + }, + "@jest/reporters": { + "version": "29.5.0", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + } + }, + "@jest/schemas": { + "version": "29.4.3", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.25.16" + } + }, + "@jest/source-map": { + "version": "29.4.3", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "dev": true + } + } + }, + "@microsoft/applicationinsights-web-snippet": { + "version": "1.0.1" + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-app": { + "version": "4.0.13", + "requires": { + "@octokit/auth-oauth-app": "^5.0.0", + "@octokit/auth-oauth-user": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "deprecation": "^2.3.1", + "lru-cache": "^9.0.0", + "universal-github-app-jwt": "^1.1.1", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "9.1.1" + } + } + }, + "@octokit/auth-oauth-app": { + "version": "5.0.5", + "requires": { + "@octokit/auth-oauth-device": "^4.0.0", + "@octokit/auth-oauth-user": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "@types/btoa-lite": "^1.0.0", + "btoa-lite": "^1.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/auth-oauth-device": { + "version": "4.0.4", + "requires": { + "@octokit/oauth-methods": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/auth-oauth-user": { + "version": "2.1.1", + "requires": { + "@octokit/auth-oauth-device": "^4.0.0", + "@octokit/oauth-methods": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/auth-token": { + "version": "3.0.3", + "requires": { + "@octokit/types": "^9.0.0" + } + }, + "@octokit/core": { + "version": "4.2.1", + "requires": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "7.0.5", + "requires": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "5.0.5", + "requires": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/oauth-authorization-url": { + "version": "5.0.0" + }, + "@octokit/oauth-methods": { + "version": "2.0.5", + "requires": { + "@octokit/oauth-authorization-url": "^5.0.0", + "@octokit/request": "^6.2.3", + "@octokit/request-error": "^3.0.3", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0" + } + }, + "@octokit/openapi-types": { + "version": "17.2.0" + }, + "@octokit/plugin-paginate-graphql": { + "version": "2.0.1", + "requires": {} + }, + "@octokit/plugin-paginate-rest": { + "version": "6.1.2", + "requires": { + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "requires": {} + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "7.1.2", + "requires": { + "@octokit/types": "^9.2.3", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "6.2.5", + "requires": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "3.0.3", + "requires": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "19.0.11", + "requires": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^7.1.2" + } + }, + "@octokit/tsconfig": { + "version": "1.0.2" + }, + "@octokit/types": { + "version": "9.2.3", + "requires": { + "@octokit/openapi-types": "^17.2.0" + } + }, + "@opentelemetry/api": { + "version": "1.4.1" + }, + "@opentelemetry/core": { + "version": "1.13.0", + "requires": { + "@opentelemetry/semantic-conventions": "1.13.0" + } + }, + "@opentelemetry/instrumentation": { + "version": "0.35.1", + "requires": { + "require-in-the-middle": "^5.0.3", + "semver": "^7.3.2", + "shimmer": "^1.2.1" + } + }, + "@opentelemetry/resources": { + "version": "1.13.0", + "requires": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" + } + }, + "@opentelemetry/sdk-trace-base": { + "version": "1.13.0", + "requires": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/resources": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" + } + }, + "@opentelemetry/semantic-conventions": { + "version": "1.13.0" + }, + "@redis/bloom": { + "version": "1.2.0", + "requires": {} + }, + "@redis/client": { + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.9.tgz", + "integrity": "sha512-SffgN+P1zdWJWSXBvJeynvEnmnZrYmtKSRW00xl8pOPFOMJjxRR9u0frSxJpPR6Y4V+k54blJjGW7FgxbTI7bQ==", + "requires": { + "cluster-key-slot": "1.1.2", + "generic-pool": "3.9.0", + "yallist": "4.0.0" + } + }, + "@redis/graph": { + "version": "1.1.0", + "requires": {} + }, + "@redis/json": { + "version": "1.0.4", + "requires": {} + }, + "@redis/search": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", + "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", + "requires": {} + }, + "@redis/time-series": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "requires": {} + }, + "@sideway/address": { + "version": "4.1.4", + "requires": { + "@hapi/hoek": "^9.0.0" + }, + "dependencies": { + "@hapi/hoek": { + "version": "9.3.0" + } + } + }, + "@sideway/formula": { + "version": "3.0.1" + }, + "@sideway/pinpoint": { + "version": "2.0.0" + }, + "@sinclair/typebox": { + "version": "0.25.24", + "dev": true + }, + "@sinonjs/commons": { + "version": "2.0.0", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } + }, + "@tootallnate/once": { + "version": "2.0.0" + }, + "@ts-morph/common": { + "version": "0.12.3", + "dev": true, + "requires": { + "fast-glob": "^3.2.7", + "minimatch": "^3.0.4", + "mkdirp": "^1.0.4", + "path-browserify": "^1.0.1" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "dev": true + }, + "@types/babel__core": { + "version": "7.20.0", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.18.5", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/body-parser": { + "version": "1.19.2", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/btoa-lite": { + "version": "1.0.0" + }, + "@types/connect": { + "version": "3.4.35", + "requires": { + "@types/node": "*" + } + }, + "@types/debug": { + "version": "4.1.7", + "dev": true, + "requires": { + "@types/ms": "*" + } + }, + "@types/express": { + "version": "4.17.17", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.34", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/express-session": { + "version": "1.17.7", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/graceful-fs": { + "version": "4.1.6", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/is-buffer": { + "version": "2.0.0", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "29.5.1", + "dev": true, + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "dev": true + }, + "@types/jsonwebtoken": { + "version": "9.0.2", + "requires": { + "@types/node": "*" + } + }, + "@types/lodash": { + "version": "4.14.194", + "dev": true + }, + "@types/luxon": { + "version": "3.3.0", + "dev": true + }, + "@types/memory-cache": { + "version": "0.2.2", + "dev": true + }, + "@types/mime": { + "version": "1.3.2" + }, + "@types/morgan": { + "version": "1.9.4", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/ms": { + "version": "0.7.31", + "dev": true + }, + "@types/node": { + "version": "20.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", + "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" + }, + "@types/node-fetch": { + "version": "2.6.1", + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, + "@types/node-jose": { + "version": "1.1.10", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/oauth": { + "version": "0.9.1", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/object-path": { + "version": "0.11.1", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "dev": true + }, + "@types/passport": { + "version": "1.0.12", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/passport-azure-ad": { + "version": "4.3.1", + "dev": true, + "requires": { + "@types/express": "*", + "@types/passport": "*" + } + }, + "@types/passport-github": { + "version": "1.1.7", + "dev": true, + "requires": { + "@types/express": "*", + "@types/passport": "*", + "@types/passport-oauth2": "*" + } + }, + "@types/passport-oauth2": { + "version": "1.4.11", + "dev": true, + "requires": { + "@types/express": "*", + "@types/oauth": "*", + "@types/passport": "*" + } + }, + "@types/pg": { + "version": "8.10.1", + "dev": true, + "requires": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^4.0.1" + }, + "dependencies": { + "pg-types": { + "version": "4.0.1", + "dev": true, + "requires": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.0.1", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + } + }, + "postgres-array": { + "version": "3.0.2", + "dev": true + }, + "postgres-bytea": { + "version": "3.0.0", + "dev": true, + "requires": { + "obuf": "~1.1.2" + } + }, + "postgres-date": { + "version": "2.0.1", + "dev": true + }, + "postgres-interval": { + "version": "3.0.0", + "dev": true + } + } + }, + "@types/prettier": { + "version": "2.7.2", + "dev": true + }, + "@types/pug": { + "version": "2.0.6", + "dev": true + }, + "@types/qs": { + "version": "6.9.7" + }, + "@types/range-parser": { + "version": "1.2.4" + }, + "@types/recursive-readdir": { + "version": "2.2.1", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/semver": { + "version": "7.5.0", + "dev": true + }, + "@types/send": { + "version": "0.17.1", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.13.10", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/simple-oauth2": { + "version": "5.0.4", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.1", + "dev": true + }, + "@types/tunnel": { + "version": "0.0.3", + "requires": { + "@types/node": "*" + } + }, + "@types/validator": { + "version": "13.7.17", + "dev": true + }, + "@types/yargs": { + "version": "17.0.24", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.59.7", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/type-utils": "5.59.7", + "@typescript-eslint/utils": "5.59.7", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.59.7", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.59.7", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.59.7", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/utils": "5.59.7", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.59.7", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.59.7", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + } + }, + "accepts": { + "version": "1.3.8", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.0", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "8.2.0", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "requires": { + "debug": "4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.2", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "app-root-path": { + "version": "3.1.0" + }, + "applicationinsights": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.7.0.tgz", + "integrity": "sha512-/vV5X6M4TlRA5NxNZAdCE0gukzfK24mb3z18D5Kl/CyIfSVIkafsIji3mK+Zi5q+7dn6H1CkFazlcnLf40anHw==", + "requires": { + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "1.10.1", + "@azure/core-util": "1.2.0", + "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.3", + "@microsoft/applicationinsights-web-snippet": "^1.0.1", + "@opentelemetry/api": "^1.0.4", + "@opentelemetry/core": "^1.12.0", + "@opentelemetry/sdk-trace-base": "^1.12.0", + "@opentelemetry/semantic-conventions": "^1.12.0", + "cls-hooked": "^4.2.2", + "continuation-local-storage": "^3.2.1", + "diagnostic-channel": "1.1.0", + "diagnostic-channel-publishers": "1.0.6" + } + }, + "arg": { + "version": "4.1.3", + "dev": true + }, + "argparse": { + "version": "2.0.1" + }, + "array-flatten": { + "version": "1.1.1" + }, + "array-timsort": { + "version": "1.0.3", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "dev": true + }, + "asap": { + "version": "2.0.6" + }, + "assert-never": { + "version": "1.2.1" + }, + "astral-regex": { + "version": "2.0.0", + "dev": true + }, + "async-hook-jl": { + "version": "1.7.6", + "requires": { + "stack-chain": "^1.3.7" + } + }, + "async-listener": { + "version": "0.6.10", + "requires": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1" + } + } + }, + "async-prompt": { + "version": "1.0.1", + "requires": { + "keypress": "~0.2.1" + } + }, + "asynckit": { + "version": "0.4.0" + }, + "available-typed-arrays": { + "version": "1.0.5" + }, + "axios": { + "version": "1.4.0", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "babel-jest": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "29.5.0", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "babel-walk": { + "version": "3.0.0-canary-5", + "requires": { + "@babel/types": "^7.9.6" + } + }, + "balanced-match": { + "version": "1.0.2" + }, + "base64-js": { + "version": "1.5.1" + }, + "base64url": { + "version": "3.0.1" + }, + "basic-auth": { + "version": "2.0.1", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "before-after-hook": { + "version": "2.2.2" + }, + "body-parser": { + "version": "1.20.2", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + }, + "on-finished": { + "version": "2.4.1", + "requires": { + "ee-first": "1.1.1" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.5", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + } + }, + "bs-logger": { + "version": "0.2.6", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "btoa-lite": { + "version": "1.0.0" + }, + "buffer": { + "version": "6.0.3", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1" + }, + "buffer-from": { + "version": "1.1.2", + "dev": true + }, + "buffer-writer": { + "version": "2.0.0" + }, + "builtins": { + "version": "5.0.1", + "dev": true, + "requires": { + "semver": "^7.0.0" + } + }, + "bunyan": { + "version": "1.8.15", + "requires": { + "dtrace-provider": "~0.8", + "moment": "^2.19.3", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, + "bytes": { + "version": "3.1.2" + }, + "cache-manager": { + "version": "3.6.3", + "requires": { + "async": "3.2.3", + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + }, + "dependencies": { + "async": { + "version": "3.2.3" + } + } + }, + "call-bind": { + "version": "1.0.2", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001486", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "dev": true + }, + "character-parser": { + "version": "2.2.0", + "requires": { + "is-regex": "^1.0.3" + } + }, + "ci-info": { + "version": "3.8.0", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.2", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "dev": true + }, + "clear-module": { + "version": "4.1.2", + "dev": true, + "requires": { + "parent-module": "^2.0.0", + "resolve-from": "^5.0.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "3.1.0", + "dev": true, + "requires": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.0.1", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "cliui": { + "version": "8.0.1", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "cls-hooked": { + "version": "4.2.2", + "requires": { + "async-hook-jl": "^1.7.6", + "emitter-listener": "^1.0.1", + "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1" + } + } + }, + "cluster-key-slot": { + "version": "1.1.2" + }, + "co": { + "version": "4.6.0", + "dev": true + }, + "code-block-writer": { + "version": "11.0.3", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "dev": true + }, + "color-contrast-checker": { + "version": "2.1.0" + }, + "color-convert": { + "version": "2.0.1", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "dev": true + }, + "colorette": { + "version": "2.0.20", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "10.0.1", + "dev": true + }, + "comment-json": { + "version": "4.2.3", + "dev": true, + "requires": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "compressible": { + "version": "2.0.18", + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "bytes": { + "version": "3.0.0" + }, + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + } + } + }, + "concat-map": { + "version": "0.0.1" + }, + "configstore": { + "version": "5.0.1", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "write-file-atomic": { + "version": "3.0.3", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } + } + }, + "connect-redis": { + "version": "7.1.0", + "requires": {} + }, + "constantinople": { + "version": "4.0.1", + "requires": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "content-disposition": { + "version": "0.5.4", + "requires": { + "safe-buffer": "5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1" + } + } + }, + "content-type": { + "version": "1.0.5" + }, + "continuation-local-storage": { + "version": "3.2.1", + "requires": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, + "convert-source-map": { + "version": "2.0.0", + "dev": true + }, + "cookie": { + "version": "0.5.0" + }, + "cookie-signature": { + "version": "1.0.6" + }, + "core-util-is": { + "version": "1.0.3", + "dev": true + }, + "cors": { + "version": "2.8.5", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "8.0.0", + "dev": true, + "requires": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + } + }, + "create-require": { + "version": "1.1.1", + "dev": true + }, + "crypto-random-string": { + "version": "2.0.0", + "dev": true + }, + "cspell": { + "version": "6.31.1", + "dev": true, + "requires": { + "@cspell/cspell-pipe": "6.31.1", + "@cspell/dynamic-import": "6.31.1", + "chalk": "^4.1.2", + "commander": "^10.0.0", + "cspell-gitignore": "6.31.1", + "cspell-glob": "6.31.1", + "cspell-io": "6.31.1", + "cspell-lib": "6.31.1", + "fast-glob": "^3.2.12", + "fast-json-stable-stringify": "^2.1.0", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "imurmurhash": "^0.1.4", + "semver": "^7.3.8", + "strip-ansi": "^6.0.1", + "vscode-uri": "^3.0.7" + } + }, + "cspell-dictionary": { + "version": "6.31.1", + "dev": true, + "requires": { + "@cspell/cspell-pipe": "6.31.1", + "@cspell/cspell-types": "6.31.1", + "cspell-trie-lib": "6.31.1", + "fast-equals": "^4.0.3", + "gensequence": "^5.0.2" + } + }, + "cspell-gitignore": { + "version": "6.31.1", + "dev": true, + "requires": { + "cspell-glob": "6.31.1", + "find-up": "^5.0.0" + } + }, + "cspell-glob": { + "version": "6.31.1", + "dev": true, + "requires": { + "micromatch": "^4.0.5" + } + }, + "cspell-grammar": { + "version": "6.31.1", + "dev": true, + "requires": { + "@cspell/cspell-pipe": "6.31.1", + "@cspell/cspell-types": "6.31.1" + } + }, + "cspell-io": { + "version": "6.31.1", + "dev": true, + "requires": { + "@cspell/cspell-service-bus": "6.31.1", + "node-fetch": "^2.6.9" + } + }, + "cspell-lib": { + "version": "6.31.1", + "dev": true, + "requires": { + "@cspell/cspell-bundled-dicts": "6.31.1", + "@cspell/cspell-pipe": "6.31.1", + "@cspell/cspell-types": "6.31.1", + "@cspell/strong-weak-map": "6.31.1", + "clear-module": "^4.1.2", + "comment-json": "^4.2.3", + "configstore": "^5.0.1", + "cosmiconfig": "8.0.0", + "cspell-dictionary": "6.31.1", + "cspell-glob": "6.31.1", + "cspell-grammar": "6.31.1", + "cspell-io": "6.31.1", + "cspell-trie-lib": "6.31.1", + "fast-equals": "^4.0.3", + "find-up": "^5.0.0", + "gensequence": "^5.0.2", + "import-fresh": "^3.3.0", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0", + "vscode-languageserver-textdocument": "^1.0.8", + "vscode-uri": "^3.0.7" + } + }, + "cspell-trie-lib": { + "version": "6.31.1", + "dev": true, + "requires": { + "@cspell/cspell-pipe": "6.31.1", + "@cspell/cspell-types": "6.31.1", + "gensequence": "^5.0.2" + } + }, + "debug": { + "version": "4.3.4", + "requires": { + "ms": "2.1.2" + } + }, + "dedent": { + "version": "0.7.0", + "dev": true + }, + "deeks": { + "version": "2.6.0" + }, + "deep-is": { + "version": "0.1.4", + "dev": true + }, + "deepmerge": { + "version": "4.3.1" + }, + "define-lazy-prop": { + "version": "2.0.0" + }, + "delayed-stream": { + "version": "1.0.0" + }, + "depd": { + "version": "2.0.0" + }, + "deprecation": { + "version": "2.3.1" + }, + "destroy": { + "version": "1.2.0" + }, + "detect-newline": { + "version": "3.1.0", + "dev": true + }, + "diagnostic-channel": { + "version": "1.1.0", + "requires": { + "semver": "^5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1" + } + } + }, + "diagnostic-channel-publishers": { + "version": "1.0.6", + "requires": {} + }, + "diff": { + "version": "4.0.2", + "dev": true + }, + "diff-sequences": { + "version": "29.4.3", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doc-path": { + "version": "3.0.6" + }, + "doctrine": { + "version": "3.0.0", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "doctypes": { + "version": "1.1.0" + }, + "dot-prop": { + "version": "5.3.0", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" + }, + "dtrace-provider": { + "version": "0.8.8", + "optional": true, + "requires": { + "nan": "^2.14.0" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "dev": true + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "ee-first": { + "version": "1.1.1" + }, + "electron-to-chromium": { + "version": "1.4.392", + "dev": true + }, + "emitter-listener": { + "version": "1.1.2", + "requires": { + "shimmer": "^1.2.0" + } + }, + "emittery": { + "version": "0.13.1", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "dev": true + }, + "encodeurl": { + "version": "1.0.2" + }, + "error-ex": { + "version": "1.3.2", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-promise": { + "version": "4.2.8" + }, + "escalade": { + "version": "3.1.1", + "dev": true + }, + "escape-html": { + "version": "1.0.3" + }, + "escape-string-regexp": { + "version": "4.0.0", + "dev": true + }, + "eslint": { + "version": "8.41.0", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.41.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "eslint-scope": { + "version": "7.2.0", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "8.8.0", + "dev": true, + "requires": {} + }, + "eslint-plugin-es-x": { + "version": "6.2.1", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.5.0" + } + }, + "eslint-plugin-n": { + "version": "16.0.0", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "builtins": "^5.0.1", + "eslint-plugin-es-x": "^6.1.0", + "ignore": "^5.1.1", + "is-core-module": "^2.12.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.2", + "semver": "^7.5.0" + } + }, + "eslint-plugin-prettier": { + "version": "4.2.1", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "3.4.1", + "dev": true + }, + "espree": { + "version": "9.5.2", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esprima": { + "version": "4.0.1", + "dev": true + }, + "esquery": { + "version": "1.5.0", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "dev": true + }, + "etag": { + "version": "1.8.1" + }, + "events": { + "version": "3.3.0" + }, + "execa": { + "version": "5.1.1", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + } + } + }, + "exit": { + "version": "0.1.2", + "dev": true + }, + "expect": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "express": { + "version": "4.18.2", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.20.1", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + }, + "on-finished": { + "version": "2.4.1", + "requires": { + "ee-first": "1.1.1" + } + }, + "raw-body": { + "version": "2.5.1", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "safe-buffer": { + "version": "5.2.1" + } + } + }, + "express-async-handler": { + "version": "1.1.4" + }, + "express-session": { + "version": "1.17.3", + "requires": { + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "cookie": { + "version": "0.4.2" + }, + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + }, + "safe-buffer": { + "version": "5.2.1" + } + } + }, + "express-sslify": { + "version": "1.2.0" + }, + "fast-deep-equal": { + "version": "3.1.3", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "dev": true + }, + "fast-equals": { + "version": "4.0.3", + "dev": true + }, + "fast-glob": { + "version": "3.2.12", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0" + }, + "fast-levenshtein": { + "version": "2.0.6", + "dev": true + }, + "fast-safe-stringify": { + "version": "2.1.1" + }, + "fast-xml-parser": { + "version": "4.2.2", + "requires": { + "strnum": "^1.0.5" + } + }, + "fastq": { + "version": "1.15.0", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fb-watchman": { + "version": "2.0.2", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-size": { + "version": "1.0.0" + }, + "fill-range": { + "version": "7.0.1", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + }, + "on-finished": { + "version": "2.4.1", + "requires": { + "ee-first": "1.1.1" + } + } + } + }, + "find-up": { + "version": "5.0.0", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "dev": true + }, + "follow-redirects": { + "version": "1.15.2" + }, + "for-each": { + "version": "0.3.3", + "requires": { + "is-callable": "^1.1.3" + } + }, + "form-data": { + "version": "4.0.0", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0" + }, + "fresh": { + "version": "0.5.2" + }, + "fs.realpath": { + "version": "1.0.0" + }, + "fsevents": { + "version": "2.3.2", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1" + }, + "generic-pool": { + "version": "3.9.0" + }, + "gensequence": { + "version": "5.0.2", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.0", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-package-type": { + "version": "0.1.0", + "dev": true + }, + "get-stdin": { + "version": "8.0.0", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "dev": true + }, + "github-username-regex": { + "version": "1.0.0" + }, + "glob": { + "version": "7.2.0", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "global-dirs": { + "version": "0.1.1", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "13.20.0", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.10" + }, + "grapheme-splitter": { + "version": "1.0.4", + "dev": true + }, + "graphemer": { + "version": "1.4.0", + "dev": true + }, + "has": { + "version": "1.0.3", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "dev": true + }, + "has-own-prop": { + "version": "2.0.0", + "dev": true + }, + "has-symbols": { + "version": "1.0.3" + }, + "has-tostringtag": { + "version": "1.0.0", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hsts": { + "version": "2.2.0", + "requires": { + "depd": "2.0.0" + } + }, + "html-escaper": { + "version": "2.0.2", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-proxy-agent": { + "version": "5.0.0", + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "dev": true + }, + "husky": { + "version": "8.0.3", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1" + }, + "ignore": { + "version": "5.2.0", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "parent-module": { + "version": "1.0.1", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "dev": true + } + } + }, + "import-local": { + "version": "3.1.0", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "import-meta-resolve": { + "version": "2.2.2", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4" + }, + "ini": { + "version": "1.3.8", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1" + }, + "is-arguments": { + "version": "1.1.1", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1" + }, + "is-buffer": { + "version": "2.0.5" + }, + "is-callable": { + "version": "1.2.7" + }, + "is-core-module": { + "version": "2.12.0", + "requires": { + "has": "^1.0.3" + } + }, + "is-docker": { + "version": "2.2.1" + }, + "is-expression": { + "version": "4.0.0", + "requires": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1" + } + } + }, + "is-extglob": { + "version": "2.1.1", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.3", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0" + }, + "is-promise": { + "version": "2.2.2" + }, + "is-regex": { + "version": "1.1.4", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-stream": { + "version": "2.0.1", + "dev": true + }, + "is-typed-array": { + "version": "1.1.10", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "requires": { + "is-docker": "^2.0.0" + } + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.5", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", + "import-local": "^3.0.2", + "jest-cli": "^29.5.0" + } + }, + "jest-changed-files": { + "version": "29.5.0", + "dev": true, + "requires": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-cli": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + } + }, + "jest-config": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "29.5.0", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-docblock": { + "version": "29.4.3", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" + } + }, + "jest-environment-node": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "jest-get-type": { + "version": "29.4.3", + "dev": true + }, + "jest-haste-map": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-junit": { + "version": "16.0.0", + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2", + "xml": "^1.0.1" + } + }, + "jest-leak-detector": { + "version": "29.5.0", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-matcher-utils": { + "version": "29.5.0", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-message-util": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.3", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "29.4.3", + "dev": true + }, + "jest-resolve": { + "version": "29.5.0", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "29.5.0", + "dev": true, + "requires": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" + } + }, + "jest-runner": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + } + }, + "jest-runtime": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-snapshot": { + "version": "29.5.0", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.5.0", + "semver": "^7.3.5" + } + }, + "jest-util": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "dev": true + } + } + }, + "jest-watcher": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "29.5.0", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.5.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "joi": { + "version": "17.9.2", + "requires": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.3", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + }, + "dependencies": { + "@hapi/hoek": { + "version": "9.3.0" + } + } + }, + "jose": { + "version": "4.14.4" + }, + "js-stringify": { + "version": "1.0.2" + }, + "js-tokens": { + "version": "4.0.0", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "requires": { + "argparse": "^2.0.1" + } + }, + "jsbi": { + "version": "3.2.5" + }, + "jsesc": { + "version": "2.5.2", + "dev": true + }, + "json-2-csv": { + "version": "3.18.0", + "requires": { + "deeks": "2.6.0", + "doc-path": "3.0.6" + } + }, + "json-parse-better-errors": { + "version": "1.0.2" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true + }, + "json5": { + "version": "2.2.3", + "dev": true + }, + "jsonc": { + "version": "2.0.0", + "requires": { + "fast-safe-stringify": "^2.0.6", + "graceful-fs": "^4.1.15", + "mkdirp": "^0.5.1", + "parse-json": "^4.0.0", + "strip-bom": "^4.0.0", + "strip-json-comments": "^3.0.1" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.6", + "requires": { + "minimist": "^1.2.6" + } + }, + "parse-json": { + "version": "4.0.0", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "jsonwebtoken": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", + "integrity": "sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==", + "requires": { + "jws": "^3.2.2", + "lodash": "^4.17.21", + "ms": "^2.1.1", + "semver": "^7.3.8" + }, + "dependencies": { + "jwa": { + "version": "1.4.1", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + } + } + }, + "jssha": { + "version": "3.3.0" + }, + "jstransformer": { + "version": "1.0.0", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "jwa": { + "version": "2.0.0", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jwks-rsa": { + "version": "3.0.1", + "requires": { + "@types/express": "^4.17.14", + "@types/jsonwebtoken": "^9.0.0", + "debug": "^4.3.4", + "jose": "^4.10.4", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.4" + } + }, + "jws": { + "version": "4.0.0", + "requires": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "keypress": { + "version": "0.2.1" + }, + "kleur": { + "version": "3.0.3", + "dev": true + }, + "language-map": { + "version": "1.5.0" + }, + "leven": { + "version": "3.1.0", + "dev": true + }, + "levn": { + "version": "0.4.1", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lilconfig": { + "version": "2.1.0", + "dev": true + }, + "limiter": { + "version": "1.1.5" + }, + "lines-and-columns": { + "version": "1.2.4", + "dev": true + }, + "linkify-it": { + "version": "4.0.1", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "lint-staged": { + "version": "13.2.2", + "dev": true, + "requires": { + "chalk": "5.2.0", + "cli-truncate": "^3.1.0", + "commander": "^10.0.0", + "debug": "^4.3.4", + "execa": "^7.0.0", + "lilconfig": "2.1.0", + "listr2": "^5.0.7", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-inspect": "^1.12.3", + "pidtree": "^0.6.0", + "string-argv": "^0.3.1", + "yaml": "^2.2.2" + }, + "dependencies": { + "chalk": { + "version": "5.2.0", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "7.1.1", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + } + }, + "human-signals": { + "version": "4.3.1", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "dev": true + }, + "npm-run-path": { + "version": "5.1.0", + "dev": true, + "requires": { + "path-key": "^4.0.0" + }, + "dependencies": { + "path-key": { + "version": "4.0.0", + "dev": true + } + } + }, + "onetime": { + "version": "6.0.0", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "strip-final-newline": { + "version": "3.0.0", + "dev": true + } + } + }, + "listr2": { + "version": "5.0.8", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.19", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.8.0", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "cli-truncate": { + "version": "2.1.0", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "slice-ansi": { + "version": "3.0.0", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "locate-path": { + "version": "6.0.0", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21" + }, + "lodash.clonedeep": { + "version": "4.5.0" + }, + "lodash.memoize": { + "version": "4.1.2", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "dev": true + }, + "log-update": { + "version": "4.0.0", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "slice-ansi": { + "version": "4.0.0", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "long": { + "version": "5.2.0" + }, + "lru-cache": { + "version": "6.0.0", + "requires": { + "yallist": "^4.0.0" + } + }, + "lru-memoizer": { + "version": "2.1.4", + "requires": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.0.2", + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2" + } + } + }, + "luxon": { + "version": "3.3.0" + }, + "make-dir": { + "version": "3.1.0", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "dev": true + }, + "makeerror": { + "version": "1.0.12", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "markdown-it": { + "version": "13.0.1", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "3.0.1", + "dev": true + } + } + }, + "markdownlint": { + "version": "0.28.2", + "dev": true, + "requires": { + "markdown-it": "13.0.1", + "markdownlint-micromark": "0.1.2" + } + }, + "markdownlint-cli2": { + "version": "0.7.1", + "dev": true, + "requires": { + "globby": "13.1.4", + "markdownlint": "0.28.2", + "markdownlint-cli2-formatter-default": "0.0.4", + "micromatch": "4.0.5", + "strip-json-comments": "5.0.0", + "yaml": "2.2.2" + }, + "dependencies": { + "globby": { + "version": "13.1.4", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "slash": { + "version": "4.0.0", + "dev": true + }, + "strip-json-comments": { + "version": "5.0.0", + "dev": true + } + } + }, + "markdownlint-cli2-formatter-default": { + "version": "0.0.4", + "dev": true, + "requires": {} + }, + "markdownlint-micromark": { + "version": "0.1.2", + "dev": true + }, + "mdurl": { + "version": "1.0.1", + "dev": true + }, + "media-typer": { + "version": "0.3.0" + }, + "memory-cache": { + "version": "0.2.0" + }, + "merge-descriptors": { + "version": "1.0.1" + }, + "merge-stream": { + "version": "2.0.0", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "dev": true + }, + "methods": { + "version": "1.1.2" + }, + "micromatch": { + "version": "4.0.5", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0" + }, + "mime-db": { + "version": "1.52.0" + }, + "mime-types": { + "version": "2.1.35", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6" + }, + "mkdirp": { + "version": "1.0.4", + "dev": true + }, + "module-details-from-path": { + "version": "1.0.3" + }, + "moment": { + "version": "2.29.4" + }, + "morgan": { + "version": "1.10.0", + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + } + } + }, + "ms": { + "version": "2.1.2" + }, + "mv": { + "version": "2.1.1", + "optional": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "mkdirp": { + "version": "0.5.6", + "optional": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "rimraf": { + "version": "2.4.5", + "optional": true, + "requires": { + "glob": "^6.0.1" + } + } + } + }, + "nan": { + "version": "2.15.0", + "optional": true + }, + "natural-compare": { + "version": "1.4.0", + "dev": true + }, + "natural-compare-lite": { + "version": "1.4.0", + "dev": true + }, + "ncp": { + "version": "2.0.0", + "optional": true + }, + "negotiator": { + "version": "0.6.3" + }, + "node-abort-controller": { + "version": "3.1.1" + }, + "node-fetch": { + "version": "2.6.11", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3" + }, + "webidl-conversions": { + "version": "3.0.1" + }, + "whatwg-url": { + "version": "5.0.0", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, + "node-forge": { + "version": "1.3.1" + }, + "node-int64": { + "version": "0.4.0", + "dev": true + }, + "node-jose": { + "version": "2.2.0", + "requires": { + "base64url": "^3.0.1", + "buffer": "^6.0.3", + "es6-promise": "^4.2.8", + "lodash": "^4.17.21", + "long": "^5.2.0", + "node-forge": "^1.2.1", + "pako": "^2.0.4", + "process": "^0.11.10", + "uuid": "^9.0.0" + }, + "dependencies": { + "uuid": { + "version": "9.0.0" + } + } + }, + "node-releases": { + "version": "2.0.10", + "dev": true + }, + "nodemailer": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.4.tgz", + "integrity": "sha512-CXjQvrQZV4+6X5wP6ZIgdehJamI63MFoYFGGPtHudWym9qaEHDNdPzaj5bfMCvxG1vhAileSWW90q7nL0N36mA==" + }, + "normalize-path": { + "version": "3.0.0", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "oauth": { + "version": "0.9.15" + }, + "object-assign": { + "version": "4.1.1" + }, + "object-inspect": { + "version": "1.12.3" + }, + "object-path": { + "version": "0.11.8" + }, + "obuf": { + "version": "1.1.2", + "dev": true + }, + "octicons": { + "version": "5.0.1" + }, + "on-finished": { + "version": "2.3.0", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2" + }, + "once": { + "version": "1.4.0", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.0", + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "optionator": { + "version": "0.9.1", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "3.1.0", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-map": { + "version": "4.0.0", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "dev": true + }, + "packet-reader": { + "version": "1.0.0" + }, + "pako": { + "version": "2.0.4" + }, + "parent-module": { + "version": "2.0.0", + "dev": true, + "requires": { + "callsites": "^3.1.0" + } + }, + "parse-json": { + "version": "5.2.0", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parseurl": { + "version": "1.3.3" + }, + "passport": { + "version": "0.6.0", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1", + "utils-merge": "^1.0.1" + } + }, + "passport-azure-ad": { + "version": "4.3.5", + "requires": { + "async": "^3.2.3", + "base64url": "^3.0.0", + "bunyan": "^1.8.14", + "cache-manager": "^3.6.1", + "https-proxy-agent": "^5.0.0", + "jws": "^3.1.3", + "lodash": "^4.11.2", + "node-jose": "^2.2.0", + "oauth": "0.9.15", + "passport": "^0.6.0", + "valid-url": "^1.0.6" + }, + "dependencies": { + "async": { + "version": "3.2.4" + }, + "jwa": { + "version": "1.4.1", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + } + } + }, + "passport-github": { + "version": "1.1.0", + "requires": { + "passport-oauth2": "1.x.x" + } + }, + "passport-oauth2": { + "version": "1.6.1", + "requires": { + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + } + }, + "passport-strategy": { + "version": "1.0.0" + }, + "path-browserify": { + "version": "1.0.1", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1" + }, + "path-key": { + "version": "3.1.1", + "dev": true + }, + "path-parse": { + "version": "1.0.7" + }, + "path-to-regexp": { + "version": "0.1.7" + }, + "path-type": { + "version": "4.0.0", + "dev": true + }, + "pause": { + "version": "0.0.1" + }, + "pg": { + "version": "8.11.0", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-cloudflare": "^1.1.0", + "pg-connection-string": "^2.6.0", + "pg-pool": "^3.6.0", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + } + }, + "pg-cloudflare": { + "version": "1.1.0", + "optional": true + }, + "pg-connection-string": { + "version": "2.6.0" + }, + "pg-escape": { + "version": "0.2.0" + }, + "pg-int8": { + "version": "1.0.1" + }, + "pg-numeric": { + "version": "1.0.2", + "dev": true + }, + "pg-pool": { + "version": "3.6.0", + "requires": {} + }, + "pg-protocol": { + "version": "1.6.0" + }, + "pg-types": { + "version": "2.2.0", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.5", + "requires": { + "split2": "^4.1.0" + } + }, + "picocolors": { + "version": "1.0.0", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "dev": true + }, + "pidtree": { + "version": "0.6.0", + "dev": true + }, + "pirates": { + "version": "4.0.5", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "postgres-array": { + "version": "2.0.0" + }, + "postgres-bytea": { + "version": "1.0.0" + }, + "postgres-date": { + "version": "1.0.7" + }, + "postgres-interval": { + "version": "1.2.0", + "requires": { + "xtend": "^4.0.0" + } + }, + "postgres-range": { + "version": "1.1.3", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "dev": true + }, + "prettier": { + "version": "2.8.8", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-format": { + "version": "29.5.0", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "dev": true + } + } + }, + "priorityqueuejs": { + "version": "1.0.0" + }, + "process": { + "version": "0.11.10" + }, + "promise": { + "version": "7.3.1", + "requires": { + "asap": "~2.0.3" + } + }, + "prompts": { + "version": "2.4.2", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "proxy-addr": { + "version": "2.0.7", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "proxy-from-env": { + "version": "1.1.0" + }, + "pseudomap": { + "version": "1.0.2" + }, + "pug": { + "version": "3.0.2", + "requires": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "pug-attrs": { + "version": "3.0.0", + "requires": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "pug-code-gen": { + "version": "3.0.2", + "requires": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "pug-error": { + "version": "2.0.0" + }, + "pug-filters": { + "version": "4.0.0", + "requires": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "pug-lexer": { + "version": "5.0.1", + "requires": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "pug-linker": { + "version": "4.0.0", + "requires": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "pug-load": { + "version": "3.0.0", + "requires": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "pug-parser": { + "version": "6.0.0", + "requires": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "pug-runtime": { + "version": "3.0.1" + }, + "pug-strip-comments": { + "version": "2.0.0", + "requires": { + "pug-error": "^2.0.0" + } + }, + "pug-walk": { + "version": "2.0.0" + }, + "punycode": { + "version": "2.1.1", + "dev": true + }, + "pure-rand": { + "version": "6.0.2", + "dev": true + }, + "qs": { + "version": "6.11.0", + "requires": { + "side-channel": "^1.0.4" + } + }, + "queue-microtask": { + "version": "1.2.3", + "dev": true + }, + "random-bytes": { + "version": "1.0.0" + }, + "range-parser": { + "version": "1.2.1" + }, + "raw-body": { + "version": "2.5.2", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "dev": true + }, + "recursive-readdir": { + "version": "2.2.3", + "requires": { + "minimatch": "^3.0.5" + } + }, + "redis": { + "version": "4.6.8", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", + "integrity": "sha512-S7qNkPUYrsofQ0ztWlTHSaK0Qqfl1y+WMIxrzeAGNG+9iUZB4HGeBgkHxE6uJJ6iXrkvLd1RVJ2nvu6H1sAzfQ==", + "requires": { + "@redis/bloom": "1.2.0", + "@redis/client": "1.5.9", + "@redis/graph": "1.1.0", + "@redis/json": "1.0.4", + "@redis/search": "1.1.3", + "@redis/time-series": "1.0.5" + } + }, + "repeat-string": { + "version": "1.6.1", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "dev": true + }, + "require-in-the-middle": { + "version": "5.2.0", + "requires": { + "debug": "^4.1.1", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.1" + } + }, + "resolve": { + "version": "1.22.2", + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "dev": true + }, + "resolve-global": { + "version": "1.0.0", + "dev": true, + "requires": { + "global-dirs": "^0.1.1" + } + }, + "resolve.exports": { + "version": "2.0.2", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "dev": true + }, + "rfdc": { + "version": "1.3.0", + "dev": true + }, + "rhea": { + "version": "3.0.2", + "requires": { + "debug": "^4.3.3" + } + }, + "rhea-promise": { + "version": "3.0.1", + "requires": { + "debug": "^3.1.0", + "rhea": "^3.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "rimraf": { + "version": "3.0.2", + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "7.8.1", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "safe-buffer": { + "version": "5.1.2" + }, + "safe-json-stringify": { + "version": "1.2.0", + "optional": true + }, + "safer-buffer": { + "version": "2.1.2" + }, + "sax": { + "version": "1.2.4" + }, + "secure-compare": { + "version": "3.0.1" + }, + "semaphore": { + "version": "1.1.0" + }, + "semver": { + "version": "7.5.1", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.18.0", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0" + } + } + }, + "ms": { + "version": "2.1.3" + }, + "on-finished": { + "version": "2.4.1", + "requires": { + "ee-first": "1.1.1" + } + } + } + }, + "serve-favicon": { + "version": "2.5.0", + "requires": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1" + }, + "safe-buffer": { + "version": "5.1.1" + } + } + }, + "serve-static": { + "version": "1.15.0", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0" + }, + "shebang-command": { + "version": "2.0.0", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "dev": true + }, + "shimmer": { + "version": "1.2.1" + }, + "side-channel": { + "version": "1.0.4", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "dev": true + }, + "simple-oauth2": { + "version": "5.0.0", + "requires": { + "@hapi/hoek": "^10.0.1", + "@hapi/wreck": "^18.0.0", + "debug": "^4.3.4", + "joi": "^17.6.4" + } + }, + "sisteransi": { + "version": "1.0.5", + "dev": true + }, + "slash": { + "version": "3.0.0", + "dev": true + }, + "slice-ansi": { + "version": "5.0.0", + "dev": true, + "requires": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "4.0.0", + "dev": true + } + } + }, + "source-map": { + "version": "0.6.1", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "split2": { + "version": "4.1.0" + }, + "sprintf-js": { + "version": "1.0.3", + "dev": true + }, + "stack-chain": { + "version": "1.3.7" + }, + "stack-utils": { + "version": "2.0.6", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "dev": true + } + } + }, + "statuses": { + "version": "2.0.1" + }, + "stoppable": { + "version": "1.1.0" + }, + "string-argv": { + "version": "0.3.2", + "dev": true + }, + "string-length": { + "version": "4.0.2", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0" + }, + "strip-final-newline": { + "version": "2.0.0", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1" + }, + "strnum": { + "version": "1.0.5" + }, + "supports-color": { + "version": "7.2.0", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0" + }, + "test-exclude": { + "version": "6.0.0", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "dev": true + }, + "throat": { + "version": "6.0.2" + }, + "through": { + "version": "2.3.8", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "requires": { + "rimraf": "^3.0.0" + } + }, + "tmp-promise": { + "version": "3.0.3", + "requires": { + "tmp": "^0.2.0" + } + }, + "tmpl": { + "version": "1.0.5", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0" + }, + "to-regex-range": { + "version": "5.0.1", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1" + }, + "token-stream": { + "version": "1.0.0" + }, + "true-myth": { + "version": "4.1.1", + "dev": true + }, + "ts-jest": { + "version": "29.1.0", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + } + }, + "ts-morph": { + "version": "13.0.3", + "dev": true, + "requires": { + "@ts-morph/common": "~0.12.3", + "code-block-writer": "^11.0.0" + } + }, + "ts-node": { + "version": "10.9.1", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "ts-prune": { + "version": "0.10.3", + "dev": true, + "requires": { + "commander": "^6.2.1", + "cosmiconfig": "^7.0.1", + "json5": "^2.1.3", + "lodash": "^4.17.21", + "true-myth": "^4.1.0", + "ts-morph": "^13.0.1" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "dev": true + }, + "cosmiconfig": { + "version": "7.1.0", + "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" + } + }, + "yaml": { + "version": "1.10.2", + "dev": true + } + } + }, + "tslib": { + "version": "2.3.1" + }, + "tsutils": { + "version": "3.21.0", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "dev": true + } + } + }, + "tunnel": { + "version": "0.0.6" + }, + "type-check": { + "version": "0.4.0", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "dev": true + }, + "type-fest": { + "version": "0.20.2", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "5.0.4", + "dev": true + }, + "uc.micro": { + "version": "1.0.6", + "dev": true + }, + "uid-safe": { + "version": "2.1.5", + "requires": { + "random-bytes": "~1.0.0" + } + }, + "uid2": { + "version": "0.0.4" + }, + "unique-string": { + "version": "2.0.0", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universal-github-app-jwt": { + "version": "1.1.1", + "requires": { + "@types/jsonwebtoken": "^9.0.0", + "jsonwebtoken": "^9.0.0" + } + }, + "universal-user-agent": { + "version": "6.0.0" + }, + "unpipe": { + "version": "1.0.0" + }, + "update-browserslist-db": { + "version": "1.0.11", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util": { + "version": "0.12.5", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "utils-merge": { + "version": "1.0.1" + }, + "uuid": { + "version": "8.3.2" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "dev": true + }, + "v8-to-istanbul": { + "version": "9.1.0", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "dev": true + } + } + }, + "valid-url": { + "version": "1.0.9" + }, + "validator": { + "version": "13.9.0" + }, + "vary": { + "version": "1.1.2" + }, + "void-elements": { + "version": "3.1.0" + }, + "vscode-languageserver-textdocument": { + "version": "1.0.8", + "dev": true + }, + "vscode-uri": { + "version": "3.0.7", + "dev": true + }, + "walk-back": { + "version": "5.1.0" + }, + "walker": { + "version": "1.0.8", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "which": { + "version": "2.0.2", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-typed-array": { + "version": "1.1.9", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, + "with": { + "version": "7.0.2", + "requires": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + } + }, + "word-wrap": { + "version": "1.2.3", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2" + }, + "write-file-atomic": { + "version": "4.0.2", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "dev": true + }, + "xml": { + "version": "1.0.1", + "dev": true + }, + "xmlbuilder": { + "version": "11.0.1" + }, + "xtend": { + "version": "4.0.2" + }, + "y18n": { + "version": "5.0.8", + "dev": true + }, + "yallist": { + "version": "4.0.0" + }, + "yaml": { + "version": "2.2.2", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "dev": true + }, + "yn": { + "version": "3.1.1", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "dev": true + } } } diff --git a/package.json b/package.json index 1b2d5c589..a86483193 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,9 @@ { "name": "opensource-management-portal", "author": "Microsoft Corporation", + "contributors": [ + "Jeff Wilcox " + ], "version": "7.1.0", "license": "MIT", "private": true, @@ -17,23 +20,20 @@ ], "scripts": { "build": "tsc", - "dev:local": "DEBUG=startup EXIT_IMMEDIATELY=1 node ./dist/scripts/localEnvironment.js", "find-deadcode": "ts-prune", - "find-circular-dependencies": "npx madge --circular --extensions ts .", "fix:js": "eslint --fix .", - "fix:md": "markdownlint-cli2 --config ./.config/.markdownlint-cli2.jsonc --fix \"**/*.md\"", + "fix:md": "markdownlint-cli2-fix \"**/*.md\"", "fix": "npm run fix:js && npm run fix:md", "lint:js": "eslint .", - "lint:json": "echo OK", - "lint:md": "markdownlint-cli2 --config ./.config/.markdownlint-cli2.jsonc \"**/*.md\"", - "lint:spell": "cspell --config ./.cspell.json --no-progress \"**\"", - "lint": "npm run lint:json && npm run lint:js && npm run lint:md && npm run lint:spell", - "prepare": "husky install || echo No Husky.", + "lint:md": "markdownlint-cli2 \"**/*.md\"", + "lint:spell": "cspell --no-progress \"**\"", + "lint": "npm run lint:js && npm run lint:md && npm run lint:spell", + "prepare": "npx husky install", "start-4000": "PORT=4000 DEBUG=startup node ./dist/bin/www", "start-in-container": "node ./bin/www", "start": "node ./dist/bin/www", - "test:ci": "jest --config ./test/jest.config.ts --watchAll=false --reporters=default --reporters=jest-junit", - "test": "jest --config ./test/jest.config.ts" + "test:ci": "jest --watchAll=false --reporters=default --reporters=jest-junit", + "test": "jest" }, "lint-staged": { "*": [ @@ -41,7 +41,7 @@ "cspell --no-must-find-files" ], "*.{js,ts}": "eslint --fix", - "*.md": "markdownlint-cli2 --fix --config ./.config/.markdownlint-cli2.jsonc" + "*.md": "markdownlint-cli2-fix" }, "jest-junit": { "suiteNameTemplate": "{filepath}", @@ -65,22 +65,21 @@ "_end_microsoft_internal_": 0, "//...": "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ", "dependencies": { - "@azure/cosmos": "4.0.0", + "@azure/cosmos": "3.17.3", "@azure/data-tables": "13.2.2", - "@azure/identity": "4.0.0", + "@azure/identity": "3.2.2", "@azure/keyvault-secrets": "4.7.0", - "@azure/service-bus": "7.9.3", - "@azure/storage-blob": "12.17.0", - "@azure/storage-queue": "12.16.0", - "@octokit/plugin-paginate-graphql": "4.0.0", - "@octokit/request": "8.1.6", - "@octokit/auth-app": "6.0.3", - "@octokit/rest": "20.0.2", - "@primer/octicons": "19.8.0", + "@azure/service-bus": "7.9.0", + "@azure/storage-blob": "12.14.0", + "@azure/storage-queue": "12.14.0", + "@octokit/plugin-paginate-graphql": "2.0.1", + "@octokit/request": "6.2.5", + "@octokit/auth-app": "4.0.13", + "@octokit/rest": "19.0.11", "app-root-path": "3.1.0", - "applicationinsights": "2.9.2", + "applicationinsights": "2.7.0", "async-prompt": "1.0.1", - "axios": "1.6.5", + "axios": "1.4.0", "basic-auth": "2.0.1", "body-parser": "1.20.2", "color-contrast-checker": "2.1.0", @@ -91,7 +90,7 @@ "deepmerge": "4.3.1", "dotenv": "16.3.1", "express": "4.18.2", - "express-async-handler": "1.2.0", + "express-async-handler": "1.1.4", "express-session": "1.17.3", "express-sslify": "1.2.0", "file-size": "1.0.0", @@ -100,76 +99,76 @@ "js-yaml": "4.1.0", "json-2-csv": "^3.18.0", "jsonc": "2.0.0", - "jsonwebtoken": "9.0.2", - "jwks-rsa": "3.1.0", + "jsonwebtoken": "9.0.1", + "jwks-rsa": "3.0.1", "language-map": "1.5.0", "lodash": "4.17.21", - "luxon": "3.4.4", + "luxon": "3.3.0", "memory-cache": "0.2.0", - "moment": "2.30.1", + "moment": "2.29.4", "morgan": "1.10.0", "node-jose": "2.2.0", - "nodemailer": "6.9.8", + "nodemailer": "6.9.4", "object-path": "0.11.8", - "passport": "0.7.0", + "octicons": "5.0.1", + "passport": "0.6.0", "passport-azure-ad": "4.3.5", "passport-github": "1.1.0", - "pg": "8.11.3", + "pg": "8.11.0", "pg-escape": "0.2.0", "pug": "3.0.2", "pug-load": "3.0.0", "recursive-readdir": "2.2.3", - "redis": "4.6.12", + "redis": "4.6.8", "secure-compare": "3.0.1", - "semver": "7.5.4", + "semver": "7.5.1", "serve-favicon": "2.5.0", "simple-oauth2": "5.0.0", "throat": "6.0.2", "tmp-promise": "3.0.3", - "validator": "13.11.0", + "validator": "13.9.0", "walk-back": "5.1.0" }, "devDependencies": { - "@types/cors": "2.8.17", - "@types/debug": "4.1.12", - "@types/express": "4.17.21", - "@types/express-session": "1.17.10", - "@types/jest": "29.5.11", - "@types/lodash": "4.14.202", - "@types/luxon": "3.4.0", - "@types/memory-cache": "0.2.5", - "@types/morgan": "1.9.9", - "@types/node": "20.11.0", - "@types/node-jose": "1.1.13", - "@types/object-path": "0.11.4", - "@types/passport": "1.0.16", - "@types/passport-azure-ad": "4.3.5", - "@types/passport-github": "1.1.12", - "@types/pg": "8.10.9", - "@types/pug": "2.0.10", - "@types/recursive-readdir": "2.2.4", - "@types/semver": "7.5.6", - "@types/simple-oauth2": "5.0.7", - "@types/validator": "13.11.8", - "@typescript-eslint/eslint-plugin": "6.18.1", - "@typescript-eslint/parser": "6.18.1", - "cspell": "8.3.2", - "eslint": "8.56.0", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-n": "16.6.2", - "eslint-plugin-prettier": "5.1.3", + "@types/debug": "4.1.7", + "@types/express": "4.17.17", + "@types/express-session": "1.17.7", + "@types/jest": "29.5.1", + "@types/lodash": "4.14.194", + "@types/luxon": "3.3.0", + "@types/memory-cache": "0.2.2", + "@types/morgan": "1.9.4", + "@types/node": "20.4.2", + "@types/node-jose": "1.1.10", + "@types/object-path": "0.11.1", + "@types/passport": "1.0.12", + "@types/passport-azure-ad": "4.3.1", + "@types/passport-github": "1.1.7", + "@types/pg": "8.10.1", + "@types/pug": "2.0.6", + "@types/recursive-readdir": "2.2.1", + "@types/semver": "7.5.0", + "@types/simple-oauth2": "5.0.4", + "@types/validator": "13.7.17", + "@typescript-eslint/eslint-plugin": "5.59.7", + "@typescript-eslint/parser": "5.59.7", + "cspell": "6.31.1", + "eslint": "8.41.0", + "eslint-config-prettier": "8.8.0", + "eslint-plugin-n": "16.0.0", + "eslint-plugin-prettier": "4.2.1", "husky": "8.0.3", - "jest": "29.7.0", + "jest": "29.5.0", "jest-junit": "16.0.0", - "lint-staged": "15.2.0", - "markdownlint-cli2": "0.12.0", - "prettier": "3.1.1", - "ts-jest": "29.1.1", - "ts-node": "10.9.2", + "lint-staged": "13.2.2", + "markdownlint-cli2": "0.7.1", + "prettier": "2.8.8", + "ts-jest": "29.1.0", + "ts-node": "10.9.1", "ts-prune": "0.10.3", - "typescript": "5.3.3" + "typescript": "5.0.4" }, "engines": { - "node": ">=18" + "node": ">=16" } } diff --git a/data/pg.sql b/pg.sql similarity index 100% rename from data/pg.sql rename to pg.sql diff --git a/routes/administration/app.ts b/routes/administration/app.ts index b5add5da4..ea3419bb3 100644 --- a/routes/administration/app.ts +++ b/routes/administration/app.ts @@ -3,19 +3,19 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { OrganizationSetting, IBasicGitHubAppInstallation, - SystemTeam, -} from '../../business/entities/organizationSettings/organizationSetting'; + SpecialTeam, +} from '../../entities/organizationSettings/organizationSetting'; import { IndividualContext } from '../../business/user'; import { Operations, Organization } from '../../business'; -import GitHubApplication, { isInstallationConfigured } from '../../business/application'; +import GitHubApplication from '../../business/application'; import { ReposAppRequest, IGitHubAppInstallation, @@ -27,7 +27,7 @@ import { router.use( '/:appId', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const providers = getProviders(req); const appId = Number(req.params.appId); const app = providers.operations.getApplicationById(appId); @@ -43,7 +43,7 @@ router.use( router.get( '/:appId', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const githubApplication = req['githubApplication'] as GitHubApplication; const installationIdString = req.query.installation_id; const setupAction = req.query.setup_action; @@ -71,7 +71,7 @@ router.get( router.use( '/:appId/installations/:installationId', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const githubApplication = req['githubApplication'] as GitHubApplication; const installationIdString = req.params.installationId; const { operations, organizationSettingsProvider } = getProviders(req); @@ -101,6 +101,21 @@ router.use( }) ); +function isInstallationConfigured( + settings: OrganizationSetting, + installation: IGitHubAppInstallation +): boolean { + if (!settings || !settings.installations) { + return false; + } + for (const install of settings.installations) { + if (install.installationId === installation.id) { + return true; + } + } + return false; +} + async function getDynamicSettingsFromLegacySettings( operations: Operations, staticSettings: any, @@ -151,7 +166,7 @@ async function getDynamicSettingsFromLegacySettings( router.post( '/:appId/installations/:installationId', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const hasBurnButtonClicked = req.body['burn-org-app']; const hasImportButtonClicked = req.body['adopt-import-settings']; const hasCreateButtonClicked = req.body['adopt-new-org']; @@ -214,9 +229,9 @@ router.post( if (result?.state === OrganizationMembershipState.Pending) { return res.send( `You need to accept the membership now at: https://github.com/${unconfiguredOrganization.name}` - ) as unknown as void; + ); } else { - return res.send('OK. Elevation should be all set.') as unknown as void; + return res.send('OK. Elevation should be all set.'); } } catch (error) { return next(error); @@ -296,25 +311,22 @@ router.post( // explicitly now allowing globalSudo to be set here throw new Error(`Unsupported team type: ${teamType}`); } - let specialTeamType: SystemTeam = null; + let specialTeamType: SpecialTeam = null; switch (teamType) { case 'everyone': - specialTeamType = SystemTeam.Everyone; - break; - case 'openAccess': - specialTeamType = SystemTeam.OpenAccess; + specialTeamType = SpecialTeam.Everyone; break; case 'systemAdmin': - specialTeamType = SystemTeam.SystemAdmin; + specialTeamType = SpecialTeam.SystemAdmin; break; case 'systemWrite': - specialTeamType = SystemTeam.SystemWrite; + specialTeamType = SpecialTeam.SystemWrite; break; case 'systemRead': - specialTeamType = SystemTeam.SystemRead; + specialTeamType = SpecialTeam.SystemRead; break; case 'sudo': - specialTeamType = SystemTeam.Sudo; + specialTeamType = SpecialTeam.Sudo; break; // case 'globalSudo': // specialTeamType = SpecialTeam.GlobalSudo; @@ -363,7 +375,7 @@ router.post( router.get( '/:appId/installations/:installationId', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const githubApplication = req['githubApplication'] as GitHubApplication; const providers = getProviders(req); const individualContext = req.individualContext; diff --git a/routes/administration/apps.ts b/routes/administration/apps.ts index 8221d430d..bec5cb2bc 100644 --- a/routes/administration/apps.ts +++ b/routes/administration/apps.ts @@ -3,22 +3,39 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; -import { sortByCaseInsensitive } from '../../lib/utils'; +import { getProviders } from '../../transitional'; +import { sortByCaseInsensitive } from '../../utils'; import GitHubApplication from '../../business/application'; +import { OrganizationSetting } from '../../entities/organizationSettings/organizationSetting'; import { ReposAppRequest, UserAlertType } from '../../interfaces'; -import { - ManagedOrganizationAppConfigurationsByOrgView, - ManagedOrganizationStatus, -} from '../../api/client/context/administration/types'; + +interface IByOrgViewAppInstallation { + app: GitHubApplication; + installationId?: number; +} + +enum OrgStatus { + Active = 'Active', + Adopted = 'Adopted', + NotAdopted = 'NotAdopted', +} + +interface IByOrgView { + organizationName: string; + status: OrgStatus; + appInstallations: Map; + dynamicSettings: OrganizationSetting; + configuredInstallations: number[]; + id?: number; +} router.post( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const providers = getProviders(req); const { deletesettingsorgname } = req.body; if (!deletesettingsorgname) { @@ -52,20 +69,20 @@ router.post( router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const providers = getProviders(req); const operations = providers.operations; const apps = providers.operations.getApplications(); const individualContext = req.individualContext; const organizationSettingsProvider = providers.organizationSettingsProvider; - const byOrg = new Map(); + const byOrg = new Map(); function getOrg(name: string) { let o = byOrg.get(name); if (!o) { o = { organizationName: name, id: undefined, - status: ManagedOrganizationStatus.NotAdopted, + status: OrgStatus.NotAdopted, appInstallations: new Map(), dynamicSettings: null, configuredInstallations: [], @@ -79,19 +96,19 @@ router.get( } for (const app of apps) { const appInstalls = await app.getInstallations({ maxAgeSeconds: 5 }); - const { valid: validInstallations } = GitHubApplication.filterInstallations(appInstalls); - for (const valid of validInstallations) { - const organizationName = valid.account.login; + const { valid } = GitHubApplication.filterInstallations(appInstalls); + for (const vi of valid) { + const organizationName = vi.account.login; const o = getOrg(organizationName.toLowerCase()); o.appInstallations.set(app.id, { app, - installationId: valid.id, + installationId: vi.id, }); - o.id = Number(valid.target_id); - if (!o.dynamicSettings && valid.target_type === 'Organization') { + o.id = Number(vi.target_id); + if (!o.dynamicSettings && vi.target_type === 'Organization') { try { o.dynamicSettings = await organizationSettingsProvider.getOrganizationSetting( - valid.target_id.toString() + vi.target_id.toString() ); } catch (ignore) { /* ignored */ @@ -100,10 +117,10 @@ router.get( o.configuredInstallations = o.dynamicSettings.installations.map( (install) => install.installationId ); - o.status = ManagedOrganizationStatus.Adopted; + o.status = OrgStatus.Adopted; } if (o.dynamicSettings && o.dynamicSettings.active === true) { - o.status = ManagedOrganizationStatus.Active; + o.status = OrgStatus.Active; } } } diff --git a/routes/administration/index.ts b/routes/administration/index.ts index 605915110..7fcc6c437 100644 --- a/routes/administration/index.ts +++ b/routes/administration/index.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; @@ -20,7 +20,7 @@ import _ from 'lodash'; router.use( '*', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const { corporateAdministrationProfile } = getProviders(req); if (corporateAdministrationProfile && corporateAdministrationProfile.urls) { req.individualContext.setInitialViewProperty('_corpAdminUrls', corporateAdministrationProfile.urls); @@ -41,7 +41,7 @@ try { router.use('/app', RouteApp); router.use('/apps', RouteApps); -router.get('/', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.get('/', (req: ReposAppRequest, res, next) => { const individualContext = req.individualContext; individualContext.webContext.render({ view: 'administration', diff --git a/routes/approvals.ts b/routes/approvals.ts index 15ea37dcf..d00d69b50 100644 --- a/routes/approvals.ts +++ b/routes/approvals.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); router.get('/', (req, res) => { diff --git a/routes/diagnostics.ts b/routes/diagnostics.ts index b3e09342b..9ae9392aa 100644 --- a/routes/diagnostics.ts +++ b/routes/diagnostics.ts @@ -4,11 +4,10 @@ // import { Request, Router } from 'express'; -import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { IAppSession, ReposAppRequest } from '../interfaces'; -import { CreateError, getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; const redacted = '*****'; @@ -97,15 +96,4 @@ router.get('/', (req: IRequestWithSession, res) => { }); }); -router.get( - '/advanced', - asyncHandler(async (req: ReposAppRequest, res, next) => { - if (req.user?.azure?.oid !== 'b9f9877e-1cae-445e-bc28-3c943078c8e7') { - return next(CreateError.NotAuthorized('You are not authorized to view this page.')); - } - const obj: any = Object.assign({}, process.env); - return res.json(obj) as unknown as void; - }) -); - export default router; diff --git a/routes/explore.ts b/routes/explore.ts index efeee696f..b912b71cb 100644 --- a/routes/explore.ts +++ b/routes/explore.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../interfaces'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; router.get('/', (req: ReposAppRequest, res) => { const config = getProviders(req).config; diff --git a/routes/index-authenticated.ts b/routes/index-authenticated.ts index a5ee54b79..688be52f5 100644 --- a/routes/index-authenticated.ts +++ b/routes/index-authenticated.ts @@ -5,11 +5,11 @@ import _ from 'lodash'; -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { hasStaticReactClientApp, getProviders } from '../lib/transitional'; +import { hasStaticReactClientApp, getProviders } from '../transitional'; import { Organization } from '../business/organization'; @@ -27,17 +27,15 @@ import linkRoute from './link'; import linkedUserRoute from './index-linked'; import linkCleanupRoute from './link-cleanup'; -import routeSettings from './settings'; +import SettingsRoute from './settings'; import getCompanySpecificDeployment from '../middleware/companySpecificDeployment'; const hasReactApp = hasStaticReactClientApp(); const reactRoute = hasReactApp ? injectReactClient() : undefined; -import routePlaceholders from './placeholders'; -import routeReleasesSpa from './releasesSpa'; - +import RoutePlaceholders from './placeholders'; +import RouteReleasesSpa from './releasesSpa'; import { ReposAppRequest, UserAlertType } from '../interfaces'; -import { Repository } from '../business'; // - - - Middleware: require that they have a passport - - - router.use(asyncHandler(requireAuthenticatedUserOrSignIn)); @@ -50,10 +48,10 @@ router.use(asyncHandler(AddLinkToRequest)); router.use(asyncHandler(blockEnterpriseManagedUsersAuthentication)); -router.use('/placeholder', routePlaceholders); +router.use('/placeholder', RoutePlaceholders); router.use('/link/cleanup', reactRoute || linkCleanupRoute); router.use('/link', reactRoute || linkRoute); -router.use('/releases', reactRoute || routeReleasesSpa); +router.use('/releases', reactRoute || RouteReleasesSpa); if (reactRoute) { // client-only routes @@ -69,9 +67,9 @@ const dynamicStartupInstance = getCompanySpecificDeployment(); dynamicStartupInstance?.routes?.connectAuthenticatedRoutes && dynamicStartupInstance.routes.connectAuthenticatedRoutes(router, reactRoute); -router.use('/settings', reactRoute || routeSettings); +router.use('/settings', SettingsRoute); -router.get('/news', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.get('/news', (req: ReposAppRequest, res, next) => { const config = getProviders(req).config; if (config && config.news && config.news.all && config.news.all.length) { return req.individualContext.webContext.render({ @@ -83,40 +81,6 @@ router.get('/news', (req: ReposAppRequest, res: Response, next: NextFunction) => } }); -router.use( - '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { - // Helper method to allow pasting a GitHub URL into the app to go to a repo - const { rid, oid, action } = req.query; - const { operations } = getProviders(req); - if (!rid && !oid) { - return next(); - } - const repositoryId = Number(rid); - const organizationId = Number(oid); - let organization: Organization = null; - let repository: Repository = null; - try { - organization = operations.getOrganizationById(organizationId); - } catch (error) { - // no-op continue - return next(); - } - if (organization) { - try { - repository = await organization.getRepositoryById(repositoryId); - return res.redirect( - `/orgs/${organization.name}/repos/${repository.name}${action ? `/${action}` : ''}` - ); - } catch (error) { - // no-op continue - return next(); - } - } - return next(); - }) -); - // Link cleanups and check their signed-in username vs their link router.use(RequireLinkMatchesGitHubSessionExceptPrefixedRoute('/unlink')); @@ -124,7 +88,7 @@ router.use(RequireLinkMatchesGitHubSessionExceptPrefixedRoute('/unlink')); router.get( '/', reactRoute || - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const onboarding = req.query.onboarding !== undefined; const individualContext = req.individualContext; const link = individualContext.link; diff --git a/routes/index-linked.ts b/routes/index-linked.ts index 5c064e058..fef788ced 100644 --- a/routes/index-linked.ts +++ b/routes/index-linked.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { CreateError, hasStaticReactClientApp, getProviders } from '../lib/transitional'; +import { CreateError, hasStaticReactClientApp, getProviders } from '../transitional'; import { IndividualContext } from '../business/user'; -import { storeOriginalUrlAsVariable } from '../lib/utils'; +import { storeOriginalUrlAsVariable } from '../utils'; import { AuthorizeOnlyCorporateAdministrators } from '../middleware/business/corporateAdministrators'; import RouteAdministration from './administration'; @@ -38,7 +38,7 @@ const reactRoute = hasReactApp ? injectReactClient() : undefined; // * only for the traditional app. The React app does not require a link to browse orgs. //----------------------------------------------------------------------------- if (!hasReactApp) { - router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { + router.use(function (req: ReposAppRequest, res, next) { const individualContext = req.individualContext as IndividualContext; const link = individualContext.link; if (link && link.thirdPartyId) { @@ -65,7 +65,7 @@ router.use('/administration', asyncHandler(AuthorizeOnlyCorporateAdministrators) router.use( '/https?*github.com/:org/:repo', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { // Helper method to allow pasting a GitHub URL into the app to go to a repo const { org, repo } = req.params; const { operations } = getProviders(req); diff --git a/routes/index.ts b/routes/index.ts index 16cc579aa..84d7d2fd0 100644 --- a/routes/index.ts +++ b/routes/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import { webContextMiddleware } from '../middleware/business/setContext'; @@ -16,7 +16,7 @@ import ExploreRoute from './explore'; import ApprovalsRoute from './approvals'; import AuthenticatedRoute from './index-authenticated'; -import { hasStaticReactClientApp } from '../lib/transitional'; +import { hasStaticReactClientApp } from '../transitional'; import { injectReactClient } from '../middleware'; router.use('/api/client', clientApiRoute); diff --git a/routes/link-cleanup.ts b/routes/link-cleanup.ts index d8ba92b7e..ff7156a32 100644 --- a/routes/link-cleanup.ts +++ b/routes/link-cleanup.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../interfaces'; @@ -17,7 +17,7 @@ import { ReposAppRequest } from '../interfaces'; // linksForCleanup?: any; // } -router.use((req: ReposAppRequest, res: Response, next: NextFunction) => { +router.use((req: ReposAppRequest, res, next) => { // TODO: revisit implementation return next(); @@ -104,7 +104,7 @@ router.use((req: ReposAppRequest, res: Response, next: NextFunction) => { // renderCleanupPage(req, res, null, null); // }); -// router.post('/', (req: IRequestWithSessionPlus, res: Response, next: NextFunction) => { +// router.post('/', (req: IRequestWithSessionPlus, res, next) => { // let action = 'unlink'; // let id = req.body.unlink; // if (!req.body.unlink && req.session && req.session.enableMultipleAccounts === true && req.body.select) { diff --git a/routes/link.ts b/routes/link.ts index eab59a277..312325395 100644 --- a/routes/link.ts +++ b/routes/link.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); @@ -14,9 +14,9 @@ import { ICorporateLink, LinkOperationSource, } from '../interfaces'; -import { getProviders, splitSemiColonCommas } from '../lib/transitional'; +import { getProviders, splitSemiColonCommas } from '../transitional'; import { IndividualContext } from '../business/user'; -import { isCodespacesAuthenticating, storeOriginalUrlAsReferrer, wrapError } from '../lib/utils'; +import { isCodespacesAuthenticating, storeOriginalUrlAsReferrer, wrapError } from '../utils'; import validator from 'validator'; @@ -31,7 +31,7 @@ interface IRequestHacked extends ReposAppRequest { overrideLinkUserPrincipalName?: any; } -router.use((req: IRequestHacked, res: Response, next: NextFunction) => { +router.use((req: IRequestHacked, res, next) => { const config = getProviders(req).config; if ( config && @@ -50,7 +50,7 @@ router.use((req: IRequestHacked, res: Response, next: NextFunction) => { router.use( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { // Make sure both account types are authenticated before showing the link pg [wi 12690] const individualContext = req.individualContext; if (!individualContext.corporateIdentity || !individualContext.getGitHubIdentity()) { @@ -64,7 +64,7 @@ router.use( // TODO: graph provider non-guest check should be middleware and in the link business process router.use( - asyncHandler(async (req: IRequestHacked, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestHacked, res, next) => { const individualContext = req.individualContext as IndividualContext; const providers = getProviders(req); const insights = providers.insights; @@ -155,7 +155,7 @@ router.use( router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const { config } = getProviders(req); const individualContext = req.individualContext; const link = individualContext.link; @@ -233,7 +233,7 @@ router.get('/enableMultipleAccounts', function (req: IRequestWithSession, res) { router.post( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const individualContext = req.individualContext as IndividualContext; try { await interactiveLinkUser(false, individualContext, req, res, next); @@ -291,7 +291,7 @@ export async function interactiveLinkUser( router.use('/remove', unlinkRoute); -router.get('/reconnect', function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.get('/reconnect', function (req: ReposAppRequest, res, next) { const config = getProviders(req).config; if (config.authentication.scheme !== 'aad') { return next( diff --git a/routes/org/2fa.ts b/routes/org/2fa.ts index b4b1b8ac9..aa1fd3a7a 100644 --- a/routes/org/2fa.ts +++ b/routes/org/2fa.ts @@ -3,18 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import moment from 'moment'; import { NoCacheNoBackground, ReposAppRequest } from '../../interfaces'; -import { wrapError } from '../../lib/utils'; +import { wrapError } from '../../utils'; router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const organization = req.organization; const onboarding = req.query.onboarding; const joining = req.query.joining; diff --git a/routes/org/index.ts b/routes/org/index.ts index d66f45efb..28281c3b1 100644 --- a/routes/org/index.ts +++ b/routes/org/index.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import express, { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { IAggregateUserSummary } from '../../business/user/aggregate'; -import { TeamJoinApprovalEntity } from '../../business/entities/teamJoinApproval/teamJoinApproval'; +import { TeamJoinApprovalEntity } from '../../entities/teamJoinApproval/teamJoinApproval'; import { Team } from '../../business'; import { ReposAppRequest, OrganizationMembershipState } from '../../interfaces'; import { @@ -31,7 +31,7 @@ interface ILocalOrgRequest extends ReposAppRequest { orgPermissions?: IRequestOrganizationPermissions; } -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.use(function (req: ReposAppRequest, res, next) { const onboarding = req.query.onboarding; const organization = req.organization; req.individualContext.webContext.pushBreadcrumb(organization.name, onboarding ? false : undefined); @@ -43,7 +43,7 @@ router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { }); // Campaign-related redirect to take the user to GitHub -router.get('/', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.get('/', (req: ReposAppRequest, res, next) => { const providers = getProviders(req); if (!providers || !providers.campaign) { return next(); @@ -63,7 +63,7 @@ router.use('/teams', RouteTeams); router.use(asyncHandler(AddOrganizationPermissionsToRequest)); router.use( - asyncHandler(async (req: ILocalOrgRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalOrgRequest, res, next) => { const organization = req.organization; const orgPermissions = req.orgPermissions; if (!orgPermissions) { @@ -90,7 +90,7 @@ router.use( router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const providers = getProviders(req); const approvalProvider = providers.approvalProvider; const organization = req.organization; @@ -107,8 +107,9 @@ router.get( pendingApprovals: null as TeamJoinApprovalEntity[], organizationAdmins, }; - results.organizationOverview = - await individualContext.aggregations.getAggregatedOrganizationOverview(organization); + results.organizationOverview = await individualContext.aggregations.getAggregatedOrganizationOverview( + organization + ); // Check for pending approvals const teamsMaintained = results.organizationOverview.teams.maintainer as Team[]; if (teamsMaintained && teamsMaintained.length && teamsMaintained.length > 0) { @@ -146,7 +147,7 @@ router.use('/wizard', RouteNewRepoSpa); router.use( '/:repoName', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const repoName = req.params.repoName; const organization = req.organization; const attemptedRepository = organization.repository(repoName); diff --git a/routes/org/join.ts b/routes/org/join.ts index c136320ea..30c4435d8 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -10,10 +10,9 @@ import asyncHandler from 'express-async-handler'; const router: Router = Router(); import querystring from 'querystring'; - -import { CreateError, getProviders } from '../../lib/transitional'; +import { CreateError, getProviders } from '../../transitional'; import { IndividualContext } from '../../business/user'; -import { sleep, storeOriginalUrlAsReferrer, wrapError } from '../../lib/utils'; +import { sleep, storeOriginalUrlAsReferrer, wrapError } from '../../utils'; import RequireActiveGitHubSession from '../../middleware/github/requireActiveSession'; import { jsonError } from '../../middleware/jsonError'; import { Organization, Team } from '../../business'; @@ -32,8 +31,8 @@ import getCompanySpecificDeployment from '../../middleware/companySpecificDeploy //------------- // Join checks //------------- -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { - const organization = req.organization; +router.use(function (req: ReposAppRequest, res, next) { + const { organization } = req; let err = null; if (organization.locked) { diff --git a/routes/org/leave.ts b/routes/org/leave.ts index 60b3b654f..2ee5b6cff 100644 --- a/routes/org/leave.ts +++ b/routes/org/leave.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; -import { wrapError } from '../../lib/utils'; +import { getProviders } from '../../transitional'; +import { wrapError } from '../../utils'; import { Organization } from '../../business'; import { OrganizationMembershipState, ReposAppRequest, UserAlertType } from '../../interfaces'; @@ -25,7 +25,7 @@ interface ILocalLeaveRequest extends ReposAppRequest { } router.use( - asyncHandler(async (req: ILocalLeaveRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalLeaveRequest, res, next) => { const organization = req.organization as Organization; req.orgLeave = { state: null, @@ -58,7 +58,7 @@ router.get('/', function (req: ILocalLeaveRequest, res) { router.post( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const organization = req.organization; const providers = getProviders(req); const operations = providers.operations; diff --git a/routes/org/membership.ts b/routes/org/membership.ts index 1ab72ab62..1e5614ce6 100644 --- a/routes/org/membership.ts +++ b/routes/org/membership.ts @@ -3,18 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { ReposAppRequest, UserAlertType } from '../../interfaces'; -import { wrapError } from '../../lib/utils'; +import { wrapError } from '../../utils'; import RequireActiveGitHubSession from '../../middleware/github/requireActiveSession'; const router: Router = Router(); router.get( '/', RequireActiveGitHubSession, - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const organization = req.organization; if (!organization) { // TODO: Was this ever a possible situation? What's going on here? Probably was v1 (single-org) @@ -56,7 +56,7 @@ router.get( router.post( '/', RequireActiveGitHubSession, - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const username = req.individualContext.getGitHubIdentity().username; const organization = req.organization; if (!organization) { diff --git a/routes/org/newRepoSpa.ts b/routes/org/newRepoSpa.ts index 715c45aa5..3adafdcb5 100644 --- a/routes/org/newRepoSpa.ts +++ b/routes/org/newRepoSpa.ts @@ -3,14 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { getRepositoryMetadataProvider, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { Organization } from '../../business/organization'; -import NewRepositoryLockdownSystem from '../../business/features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../../features/newRepositories/newRepositoryLockdown'; router.get( '/', diff --git a/routes/org/people.ts b/routes/org/people.ts index ceabce61c..5fefb4fba 100644 --- a/routes/org/people.ts +++ b/routes/org/people.ts @@ -3,14 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../../interfaces'; import RoutePeopleSearch from '../peopleSearch'; -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.use(function (req: ReposAppRequest, res, next) { req.individualContext.webContext.pushBreadcrumb('People'); req.reposContext = { section: 'people', diff --git a/routes/org/profileReview.ts b/routes/org/profileReview.ts index ab65d191f..0faf21174 100644 --- a/routes/org/profileReview.ts +++ b/routes/org/profileReview.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import asyncHandler from 'express-async-handler'; import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; interface IUserProfileWarnings { company?: string; @@ -17,7 +17,7 @@ interface IUserProfileWarnings { router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const organization = req.organization; const { operations } = getProviders(req); const config = operations.config; diff --git a/routes/org/repoAdministrativeLock.ts b/routes/org/repoAdministrativeLock.ts index a0dcd5d5e..94323057d 100644 --- a/routes/org/repoAdministrativeLock.ts +++ b/routes/org/repoAdministrativeLock.ts @@ -4,19 +4,19 @@ // import asyncHandler from 'express-async-handler'; -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { Repository } from '../../business/repository'; -import { RepositoryMetadataEntity } from '../../business/entities/repositoryMetadata/repositoryMetadata'; +import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; import { Organization } from '../../business/organization'; -import NewRepositoryLockdownSystem from '../../business/features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../../features/newRepositories/newRepositoryLockdown'; import { getRepositoryMetadataProvider, ReposAppRequest, UserAlertType } from '../../interfaces'; router.use( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const organization = req.organization as Organization; if (!organization.isNewRepositoryLockdownSystemEnabled()) { return next(new Error('This endpoint is not available as configured')); @@ -27,7 +27,7 @@ router.use( router.use( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const individualContext = req.individualContext; const isPortalAdministrator = await individualContext.isPortalAdministrator(); if (!isPortalAdministrator) { @@ -42,7 +42,7 @@ router.use( router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const repository = req['repository'] as Repository; const repositoryMetadata = req['repositoryMetadata'] as RepositoryMetadataEntity; return renderPage(req, repositoryMetadata, repository); @@ -51,9 +51,9 @@ router.get( router.post( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const providers = getProviders(req); - const { insights, operations } = providers; + const operations = providers.operations; const repository = req['repository'] as Repository; const entity = repository.getEntity(); if (!entity.parent) { @@ -68,7 +68,6 @@ router.post( const repositoryMetadataProvider = getRepositoryMetadataProvider(operations); const organization = repository.organization; const lockdownSystem = new NewRepositoryLockdownSystem({ - insights, operations, organization, repository, diff --git a/routes/org/repoWorkflowEngine.ts b/routes/org/repoWorkflowEngine.ts index 4a79b069d..e1979b26c 100644 --- a/routes/org/repoWorkflowEngine.ts +++ b/routes/org/repoWorkflowEngine.ts @@ -3,14 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; import fs from 'fs'; import path from 'path'; import recursiveReadDirectory from 'recursive-readdir'; -import { wrapError, sleep } from '../../lib/utils'; +import { wrapError, sleep } from '../../utils'; import { Organization } from '../../business'; -import { RepositoryMetadataEntity } from '../../business/entities/repositoryMetadata/repositoryMetadata'; +import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; import { Repository } from '../../business'; import { CreateRepositoryEntrypoint, ICreateRepositoryApiResult } from '../../api/createRepo'; import { @@ -21,14 +20,13 @@ import { IAlternateTokenOption, IOperationsRepositoryMetadataProvider, IProviders, - IReposAppWithTeam, throwIfNotCapable, } from '../../interfaces'; -import { ErrorHelper } from '../../lib/transitional'; +import { ErrorHelper } from '../../transitional'; import { setupRepositoryReadmeSubstring, setupRepositorySubstring, -} from '../../business/features/newRepositories/strings'; +} from '../../features/newRepositories/strings'; export interface IApprovalPackage { id: string; @@ -85,11 +83,7 @@ export class RepoWorkflowEngine { private log: IRepositoryWorkflowOutput[] = []; private repository: Repository; - constructor( - private providers: IProviders, - organization: Organization, - approvalPackage: IApprovalPackage - ) { + constructor(private providers: IProviders, organization: Organization, approvalPackage: IApprovalPackage) { this.request = approvalPackage.repositoryMetadata; // this.user = approvalPackage.requestingUser; this.id = approvalPackage.id; @@ -191,7 +185,7 @@ export class RepoWorkflowEngine { }); } - editPost(req: IReposAppWithTeam, res: Response, next: NextFunction) { + editPost(req, res, next) { const { operations } = this.providers; const ops = throwIfNotCapable( operations, diff --git a/routes/org/repos.ts b/routes/org/repos.ts index c3560ffff..33b06df44 100644 --- a/routes/org/repos.ts +++ b/routes/org/repos.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); @@ -13,13 +13,13 @@ import moment from 'moment'; import lowercaser from '../../middleware/lowercaser'; import routeAdministrativeLock from './repoAdministrativeLock'; -import NewRepositoryLockdownSystem from '../../business/features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../../features/newRepositories/newRepositoryLockdown'; import { IGraphEntry } from '../../lib/graphProvider'; import { IMail } from '../../lib/mailProvider'; import { IndividualContext } from '../../business/user'; import { Repository, Collaborator, TeamPermission, Organization, OrganizationMember } from '../../business'; -import { RepositoryMetadataEntity } from '../../business/entities/repositoryMetadata/repositoryMetadata'; +import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; import { ReposAppRequest, GitHubCollaboratorAffiliationQuery, @@ -35,7 +35,7 @@ import { getContextualRepositoryPermissions, IContextualRepositoryPermissions, } from '../../middleware/github/repoPermissions'; -import { getProviders, CreateError, ErrorHelper } from '../../lib/transitional'; +import { getProviders, CreateError, ErrorHelper } from '../../transitional'; import RouteReposPager from '../reposPager'; @@ -60,7 +60,7 @@ const teamsFilterType = { systemTeamsOnly: 'systemTeamsOnly', }; -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.use(function (req: ReposAppRequest, res, next) { req.individualContext.webContext.pushBreadcrumb('Repositories'); req.reposContext = { section: 'repos', @@ -85,10 +85,10 @@ function sliceCollaboratorsForView(collaborators) { const destination = permission.admin ? collabView.administrators : permission.push - ? collabView.writers - : permission.pull - ? collabView.readers - : null; + ? collabView.writers + : permission.pull + ? collabView.readers + : null; if (destination) { destination.push(collab); } @@ -160,7 +160,7 @@ export async function findRepoCollaboratorsExcludingOwners( router.use( '/:repoName', - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { const repoName = req.params.repoName; const organization = req.organization; const repository = organization.repository(repoName); @@ -175,7 +175,7 @@ router.use('/:repoName/administrativeLock', routeAdministrativeLock); router.use( '/:repoName/delete', - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { const individualContext = req.individualContext; const repository = req.repository; const organization = req.organization; @@ -205,7 +205,7 @@ router.use( router.get( '/:repoName/delete', - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { return req.individualContext.webContext.render({ title: 'Delete the repo you created', view: 'repos/delete', @@ -218,14 +218,13 @@ router.get( router.post( '/:repoName/delete', - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { // NOTE: this code is also duplicated for now in the client/internal/* folder // CONSIDER: de-duplicate - const { insights, operations } = getProviders(req); + const { operations } = getProviders(req); const { organization, repository } = req; const repositoryMetadataProvider = getRepositoryMetadataProvider(operations); const lockdownSystem = new NewRepositoryLockdownSystem({ - insights, operations, organization, repository, @@ -250,34 +249,121 @@ export interface IRenameOutput { } router.post( - '/:repoName', + '/:repoName/defaultBranch', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { - const repoPermissions = req.repoPermissions; - if (!repoPermissions.allowAdministration) { - return next(new Error('You do not have administrative permission on this repository')); - } - // only supporting the 'take public' operation now - const takePublic = req.body['make-repo-public']; - if (!takePublic) { - return next(new Error('Unsupported operation')); + asyncHandler(async function (req: ILocalRequest, res, next) { + try { + const targetBranchName = req.body.targetBranchName || 'main'; + const providers = getProviders(req); + const activeContext = (req.individualContext || req.apiContext) as IndividualContext; + const repoPermissions = getContextualRepositoryPermissions(req); + const repository = req.repository as Repository; + const outcome = await renameRepositoryDefaultBranchEndToEnd( + providers, + activeContext, + repoPermissions, + repository, + targetBranchName, + false + ); + req.individualContext.webContext.render({ + view: 'repos/repoBranchRenamed', + title: outcome.message, + state: { + output: outcome.output, + repository, + }, + }); + } catch (error) { + return next(error); } - const repository = req.repository as Repository; - await repository.editPublicPrivate({ private: false }); - req.individualContext.webContext.saveUserAlert( - `${repository.full_name} is now public.`, - 'Repository publish', - UserAlertType.Success - ); - await repository.getDetails(NoCacheNoBackground); - return res.redirect(`/${repository.organization.name}/repos/${repository.name}?published`); }) ); +export async function renameRepositoryDefaultBranchEndToEnd( + providers: IProviders, + activeContext: IndividualContext, + repoPermissions: IContextualRepositoryPermissions, + repository: Repository, + targetBranchName: string, + waitForRefresh: boolean +): Promise { + const corporateUsername = activeContext.corporateIdentity.username; + if (!corporateUsername) { + throw CreateError.InvalidParameters('no corporate username in the session'); + } + if (!targetBranchName) { + throw CreateError.InvalidParameters('invalid target branch name'); + } + if (!repoPermissions) { + throw CreateError.InvalidParameters('no repo permissions'); + } + if (!repoPermissions.allowAdministration) { + throw CreateError.NotAuthorized('You do not have administrative permission on this repository'); + } + await repository.getDetails(); + function finishUp(): Promise { + return new Promise((resolve) => { + triggerRenameNotification(providers, repository, corporateUsername, targetBranchName, output) + .then((ok) => { + /* ignore */ + }) + .catch((error) => { + console.error(`Notify rename trigger: ${error}`); + }); + repository + .getDetails(NoCacheNoBackground) + .then((ok) => { + return resolve(); + }) + .catch((error) => { + console.error(`Background refresh error: ${error}`); + return resolve(); + }); + }); + } + const output = await repository.renameDefaultBranch(targetBranchName); + if (waitForRefresh) { + await finishUp(); + } else { + process.nextTick(() => { + finishUp() + .then((ok) => { + /* ignore */ + }) + .catch((error) => { + /* ignore */ + }); + }); + } + return { + message: `Branch renamed to ${targetBranchName} for ${repository.name}`, + output, + }; +} + +// Disabling this function as it is high risk: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement +// router.post('/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), asyncHandler(async function (req: ILocalRequest, res, next) { +// const repoPermissions = req.repoPermissions; +// if (!repoPermissions.allowAdministration) { +// return next(new Error('You do not have administrative permission on this repository')); +// } +// // only supporting the 'take public' operation now +// const takePublic = req.body['make-repo-public']; +// if (!takePublic) { +// return next(new Error('Unsupported operation')); +// } +// const repository = req.repository as Repository; +// await repository.editPublicPrivate({ private: false }); +// req.individualContext.webContext.saveUserAlert(`${repository.full_name} is now public.`, 'Repository publish', UserAlertType.Success); +// await repository.getDetails(NoCacheNoBackground); +// return res.redirect(`/${repository.organization.name}/repos/${repository.name}?published`); +// })); + router.get( '/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { const { linkProvider, config, graphProvider } = getProviders(req); const repoPermissions = req.repoPermissions; const referer = req.headers.referer as string; @@ -379,6 +465,38 @@ router.get( }) ); +router.get( + '/:repoName/defaultBranch', + asyncHandler(AddRepositoryPermissionsToRequest), + asyncHandler(async function (req: ILocalRequest, res, next) { + const referer = req.headers.referer as string; + const fromReposPage = referer && (referer.endsWith('repos') || referer.endsWith('repos/')); + const organization = req.organization; + const repoPermissions = req.repoPermissions; + const repository = req.repository; + const repositoryMetadataEntity = req.repositoryMetadata; + await repository.getDetails(); + const title = `${repository.name} - Default Branch Name`; + const details = await repository.organization.getDetails(); + const organizationSupportsUpdatesApp = await organization.supportsUpdatesApp(); + organization.id = details.id; + req.individualContext.webContext.render({ + view: 'repos/defaultBranch', + title, + state: { + organization, + organizationSupportsUpdatesApp, + repo: decorateRepoForView(repository), + reposSubView: 'defaultBranch', + repository, + fromReposPage, + repoPermissions, + repositoryMetadataEntity, + }, + }); + }) +); + export interface IRepositoryPermissionsView {} export async function calculateGroupedPermissionsViewForRepository(repository: Repository): Promise { @@ -388,7 +506,7 @@ export async function calculateGroupedPermissionsViewForRepository(repository: R collaborators, // Collaborator[] outsideCollaborators, // Collaborator[] } = await calculateRepoPermissions(organization, repository); - const systemTeams = combineAllTeams(organization.specialSystemTeams); // number[] + const systemTeams = combineAllTeams(organization.specialRepositoryPermissionTeams); // number[] const teamBasedPermissions = consolidateTeamPermissions(permissions, systemTeams); // busted? const groupedPermissions = slicePermissionsForView( filterSystemTeams(teamsFilterType.systemTeamsExcluded, systemTeams, permissions) @@ -431,7 +549,7 @@ export async function calculateGroupedPermissionsViewForRepository(repository: R router.get( '/:repoName/permissions', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { const referer = req.headers.referer as string; const fromReposPage = referer && (referer.endsWith('repos') || referer.endsWith('repos/')); const organization = req.organization; @@ -445,7 +563,7 @@ router.get( organization, repository ); - const systemTeams = combineAllTeams(organization.specialSystemTeams); + const systemTeams = combineAllTeams(organization.specialRepositoryPermissionTeams); const teamBasedPermissions = consolidateTeamPermissions(permissions, systemTeams); const title = `${repository.name} - Repository`; const details = await repository.organization.getDetails(); @@ -481,7 +599,7 @@ router.get( router.get( '/:repoName/history', - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { const { auditLogRecordProvider } = getProviders(req); const referer = req.headers.referer as string; const fromReposPage = referer && (referer.endsWith('repos') || referer.endsWith('repos/')); @@ -636,7 +754,7 @@ function teamsToSet(teams) { return set; } -// function requireAdministration(req, res: Response, next: NextFunction) { +// function requireAdministration(req, res, next) { // const repoPermissions = req.repoPermissions; // if (!repoPermissions) { // return next(new Error('Not configured for repo permissions')); @@ -647,4 +765,55 @@ function teamsToSet(teams) { // return next(new Error('You are not authorized to administer this repository.')); // } +async function triggerRenameNotification( + providers: IProviders, + repository: Repository, + corporateUsername: string, + targetBranchName: string, + output: ITemporaryCommandOutput[] +): Promise { + const { config, insights, operations, mailAddressProvider, viewServices } = providers; + insights.trackMetric({ name: 'RenameDefaultBranches', value: 1 }); + insights.trackEvent({ + name: 'RenameDefaultBranch', + properties: { + orgName: repository.organization.name, + repoName: repository.name, + targetBranchName, + }, + }); + const mailAddress = await mailAddressProvider.getAddressFromUpn(corporateUsername); + const emailTemplate = 'repoDefaultBranchRenamed'; + const mail: IMail = { + to: [mailAddress], + cc: [operations.getInfrastructureNotificationsMail()], + subject: `${repository.organization.name}/${repository.name} default branch is now ${targetBranchName}`, + content: undefined, + }; + const contentOptions = { + reason: `You are receiving this e-mail as a transaction record from your action to rename the default branch of this repository you administer.`, + headline: `${targetBranchName} branch`, + notification: 'information', + app: config.brand?.companyName ? `${config.brand.companyName} GitHub` : 'GitHub', + output, + repository, + organization: repository.organization, + viewServices, + }; + try { + mail.content = await operations.emailRender(emailTemplate, contentOptions); + await operations.sendMail(mail); + } catch (mailError) { + console.warn(mailError); + insights.trackException({ + exception: mailError, + properties: { + repositoryName: repository.full_name, + organizationName: repository.organization.name, + eventName: 'SendRenameDefaultBranchMail', + }, + }); + } +} + export default router; diff --git a/routes/org/team/approval/index.ts b/routes/org/team/approval/index.ts index 33e06c147..ffe17b298 100644 --- a/routes/org/team/approval/index.ts +++ b/routes/org/team/approval/index.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { ErrorHelper, getProviders } from '../../../../lib/transitional'; +import { ErrorHelper, getProviders } from '../../../../transitional'; import { Team } from '../../../../business'; import { PermissionWorkflowEngine } from '../approvals'; import RenderHtmlMail from '../../../../lib/emailRender'; @@ -62,7 +62,7 @@ router.get('/setNote/:action', function (req: ILocalRequest, res) { router.post( '/', - asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalRequest, res, next) => { const providers = getProviders(req); const { individualContext } = req; const engine = req.approvalEngine as PermissionWorkflowEngine; diff --git a/routes/org/team/approvals.ts b/routes/org/team/approvals.ts index 7420ee162..88108ed18 100644 --- a/routes/org/team/approvals.ts +++ b/routes/org/team/approvals.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import RouteApproval from './approval'; -import { getProviders } from '../../../lib/transitional'; -import { wrapError } from '../../../lib/utils'; +import { getProviders } from '../../../transitional'; +import { wrapError } from '../../../utils'; import { Team } from '../../../business'; -import { TeamJoinApprovalEntity } from '../../../business/entities/teamJoinApproval/teamJoinApproval'; +import { TeamJoinApprovalEntity } from '../../../entities/teamJoinApproval/teamJoinApproval'; import { Account } from '../../../business'; import { ReposAppRequest, IRequestTeams } from '../../../interfaces'; @@ -91,14 +91,14 @@ export class PermissionWorkflowEngine { // Find the request and assign the workflow engine -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.use(function (req: ReposAppRequest, res, next) { req.individualContext.webContext.pushBreadcrumb('Approvals'); next(); }); router.get( '/', - asyncHandler(async (req: IRequestTeams, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestTeams, res, next) => { const team = req.team2 as Team; const approvals = await team.getApprovals(); req.individualContext.webContext.render({ @@ -119,7 +119,7 @@ interface IRequestPlusApprovalEngine extends IRequestTeams { router.use( '/:requestid', - asyncHandler(async function (req: IRequestPlusApprovalEngine, res: Response, next: NextFunction) { + asyncHandler(async function (req: IRequestPlusApprovalEngine, res, next) { const team = req.team2 as Team; const requestid = req.params.requestid; const { approvalProvider, operations } = getProviders(req); diff --git a/routes/org/team/delete.ts b/routes/org/team/delete.ts index 9bd26af19..92b05e2d6 100644 --- a/routes/org/team/delete.ts +++ b/routes/org/team/delete.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import { ReposAppRequest, UserAlertType } from '../../../interfaces'; @@ -14,7 +14,7 @@ interface ILocalRequest extends ReposAppRequest { team2?: any; } -router.post('/', MiddlewareTeamAdminRequired, (req: ILocalRequest, res: Response, next: NextFunction) => { +router.post('/', MiddlewareTeamAdminRequired, (req: ILocalRequest, res, next) => { const organization = req.organization; const team2 = req.team2; team2.delete((error) => { diff --git a/routes/org/team/index-maintainer.ts b/routes/org/team/index-maintainer.ts index ef935c7c9..dba129c53 100644 --- a/routes/org/team/index-maintainer.ts +++ b/routes/org/team/index-maintainer.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import { ReposAppRequest } from '../../../interfaces'; -import { wrapError } from '../../../lib/utils'; +import { wrapError } from '../../../utils'; const router: Router = Router(); import RouteApprovals from './approvals'; @@ -16,7 +16,7 @@ interface ILocalRequest extends ReposAppRequest { teamPermissions?: any; } -router.use(function (req: ILocalRequest, res: Response, next: NextFunction) { +router.use(function (req: ILocalRequest, res, next) { const teamPermissions = req.teamPermissions; if (!teamPermissions.allowAdministration) { const err = wrapError(null, 'You do not have permission to maintain this team.', true); diff --git a/routes/org/team/index.ts b/routes/org/team/index.ts index 2b9def6f5..f96e01ee1 100644 --- a/routes/org/team/index.ts +++ b/routes/org/team/index.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import throat from 'throat'; -import { getProviders } from '../../../lib/transitional'; -import { sortRepositoriesByNameCaseInsensitive, wrapError } from '../../../lib/utils'; -import { TeamJoinApprovalEntity } from '../../../business/entities/teamJoinApproval/teamJoinApproval'; -import SelfServiceTeamMemberToMaintainerUpgrades from '../../../business/features/teamMemberToMaintainerUpgrade'; +import { getProviders } from '../../../transitional'; +import { sortRepositoriesByNameCaseInsensitive, wrapError } from '../../../utils'; +import { TeamJoinApprovalEntity } from '../../../entities/teamJoinApproval/teamJoinApproval'; +import SelfServiceTeamMemberToMaintainerUpgrades from '../../../features/teamMemberToMaintainerUpgrade'; import RouteMembers from './members'; import RouteReposPager from '../../reposPager'; import RouteDelete from './delete'; @@ -65,7 +65,7 @@ interface ILocalRequest extends ReposAppRequest { } router.use( - asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalRequest, res, next) => { const { operations } = getProviders(req); const login = req.individualContext.getGitHubIdentity().username; const team2 = req.team2 as Team; @@ -93,7 +93,7 @@ router.use( ); router.use( - asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalRequest, res, next) => { const { approvalProvider } = getProviders(req); const team2 = req.team2 as Team; if (!approvalProvider) { @@ -113,53 +113,48 @@ router.use( }) ); -router.use( - '/join', - asyncHandler(AddOrganizationPermissionsToRequest), - (req: ILocalRequest, res: Response, next: NextFunction) => { - const organization = req.organization; - const team2 = req.team2; - const orgPermissions = req.orgPermissions; - - // Are they already a team member? - const currentMembershipStatus = req.membershipStatus; - if (currentMembershipStatus) { - return next( - wrapError(null, `You are already a ${currentMembershipStatus} of the ${team2.name} team`, true) - ); - } +router.use('/join', asyncHandler(AddOrganizationPermissionsToRequest), (req: ILocalRequest, res, next) => { + const organization = req.organization; + const team2 = req.team2; + const orgPermissions = req.orgPermissions; - // Have they joined the organization yet? - const membershipStatus = orgPermissions.membershipStatus; - let error = null; - if (membershipStatus !== 'active') { - error = new Error(`You are not a member of the ${organization.name} GitHub organization.`); - error.title = 'Please join the organization before joining this team'; - error.detailed = - membershipStatus === 'pending' - ? 'You have not accepted your membership yet, or do not have two-factor authentication enabled.' - : 'After you join the organization, you can join this team.'; - error.skipOops = true; - error.skipLog = true; - error.fancyLink = { - link: `/${organization.name}`, - title: `Join the ${organization.name} organization`, - }; - } - return next(error); + // Are they already a team member? + const currentMembershipStatus = req.membershipStatus; + if (currentMembershipStatus) { + return next( + wrapError(null, `You are already a ${currentMembershipStatus} of the ${team2.name} team`, true) + ); } -); + + // Have they joined the organization yet? + const membershipStatus = orgPermissions.membershipStatus; + let error = null; + if (membershipStatus !== 'active') { + error = new Error(`You are not a member of the ${organization.name} GitHub organization.`); + error.title = 'Please join the organization before joining this team'; + error.detailed = + membershipStatus === 'pending' + ? 'You have not accepted your membership yet, or do not have two-factor authentication enabled.' + : 'After you join the organization, you can join this team.'; + error.skipOops = true; + error.skipLog = true; + error.fancyLink = { + link: `/${organization.name}`, + title: `Join the ${organization.name} organization`, + }; + } + return next(error); +}); router.get( '/join', - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { const team2 = req.team2 as Team; const organization = req.organization as Organization; - // The broad access "all members" team and any "easy access" teams are - // always open for automatic joining without approval. This short circuit - // is to show that option. - const allowSelfJoinTeams = new Set([...organization.broadAccessTeams, ...organization.openAccessTeams]); - if (allowSelfJoinTeams.has(team2.id)) { + // The broad access "all members" team is always open for automatic joining without + // approval. This short circuit is to show that option. + const broadAccessTeams = new Set(organization.broadAccessTeams); + if (broadAccessTeams.has(team2.id)) { req.individualContext.webContext.render({ view: 'org/team/join', title: `Join ${team2.name}`, @@ -186,7 +181,7 @@ router.get( router.post( '/selfServiceMaintainerUpgrade', - asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalRequest, res, next) => { const { selfServiceTeamMemberToMaintainerUpgrades } = req; if (!selfServiceTeamMemberToMaintainerUpgrades) { throw new Error('System not available'); @@ -219,7 +214,7 @@ export interface ITeamJoinRequestSubmitOutcome { router.post( '/join', - asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalRequest, res, next) => { if (req.existingRequest) { throw new Error('You have already created a team join request that is pending a decision.'); } @@ -256,8 +251,7 @@ export async function submitTeamJoinRequest( ): Promise { const { approvalProvider, config, graphProvider, mailProvider, insights, operations } = providers; const organization = team.organization; - const { broadAccessTeams, openAccessTeams } = organization; - const allowSelfJoinTeams = new Set([...broadAccessTeams, ...openAccessTeams]); + const broadAccessTeams = new Set(organization.broadAccessTeams); if (!approvalProvider) { return { error: new Error('No approval provider available') }; } @@ -265,17 +259,8 @@ export async function submitTeamJoinRequest( if (!username) { return { error: new Error('Active context required') }; } - if (allowSelfJoinTeams.has(team.id)) { + if (broadAccessTeams.has(team.id)) { try { - const eventName = broadAccessTeams.includes(team.id) ? 'JoinBroadAccessTeam' : 'JoinOpenAccessTeam'; - insights?.trackEvent({ - name: eventName, - properties: { - organization: organization.name, - id: team.id, - slug: team.slug, - }, - }); await team.addMembership(username); } catch (error) { insights?.trackEvent({ @@ -517,7 +502,7 @@ export async function submitTeamJoinRequest( router.use(asyncHandler(AddTeamPermissionsToRequest)); // The view uses this information today to show the sudo banner -router.use((req: ILocalRequest, res: Response, next: NextFunction) => { +router.use((req: ILocalRequest, res, next) => { if (req.teamPermissions.sudo === true) { req.sudoMode = true; } @@ -707,18 +692,14 @@ async function basicTeamsView(req: ILocalRequest, display: BasicTeamViewPage) { }); } -router.get( - '/', - asyncHandler(AddOrganizationPermissionsToRequest), - async (req: ILocalRequest, res: Response, next: NextFunction) => { - await basicTeamsView(req, BasicTeamViewPage.Default); - } -); +router.get('/', asyncHandler(AddOrganizationPermissionsToRequest), async (req: ILocalRequest, res, next) => { + await basicTeamsView(req, BasicTeamViewPage.Default); +}); router.get( '/history', asyncHandler(AddOrganizationPermissionsToRequest), - async (req: ILocalRequest, res: Response, next: NextFunction) => { + async (req: ILocalRequest, res, next) => { await basicTeamsView(req, BasicTeamViewPage.History); } ); @@ -726,7 +707,7 @@ router.get( router.get( '/repositories', asyncHandler(AddOrganizationPermissionsToRequest), - async (req: ILocalRequest, res: Response, next: NextFunction) => { + async (req: ILocalRequest, res, next) => { await basicTeamsView(req, BasicTeamViewPage.Repositories); } ); diff --git a/routes/org/team/leave.ts b/routes/org/team/leave.ts index 1b6e20366..2c4f9eb67 100644 --- a/routes/org/team/leave.ts +++ b/routes/org/team/leave.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); @@ -17,7 +17,7 @@ interface ILocalRequest extends ReposAppRequest { router.post( '/', - asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalRequest, res, next) => { const organization = req.organization as Organization; const team2 = req.team2 as Team; const username = req.individualContext.link.thirdPartyUsername; diff --git a/routes/org/team/maintainers.ts b/routes/org/team/maintainers.ts index e4a42e22d..d8ea7ff44 100644 --- a/routes/org/team/maintainers.ts +++ b/routes/org/team/maintainers.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders, validateGitHubLogin } from '../../../lib/transitional'; +import { getProviders, validateGitHubLogin } from '../../../transitional'; import { ReposAppRequest, RequestTeamMemberAddType, @@ -28,7 +28,7 @@ interface ILocalRequest extends ReposAppRequest { } router.use( - asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalRequest, res, next) => { // Get the latest maintainers, forced, with every request const team2 = req.team2 as Team; const maintainers = await refreshMaintainers(team2); @@ -51,7 +51,7 @@ router.get('/refresh', (req: ILocalRequest, res) => { router.post( '/:id/downgrade', MiddlewareTeamAdminRequired, - asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalRequest, res, next) => { const team2 = req.team2 as Team; const id = req.params.id; const verifiedCurrentMaintainers = req.verifiedCurrentMaintainers; @@ -82,7 +82,7 @@ router.post( }) ); -router.use('/add', MiddlewareTeamAdminRequired, (req: ILocalRequest, res: Response, next: NextFunction) => { +router.use('/add', MiddlewareTeamAdminRequired, (req: ILocalRequest, res, next) => { req.team2AddType = RequestTeamMemberAddType.Maintainer; return next(); }); @@ -90,7 +90,7 @@ router.use('/add', MiddlewareTeamAdminRequired, (req: ILocalRequest, res: Respon router.post( '/add', MiddlewareTeamAdminRequired, - asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ILocalRequest, res, next) { const { operations } = getProviders(req); const login = validateGitHubLogin(req.body.username); const team2 = req.team2 as Team; diff --git a/routes/org/team/members.ts b/routes/org/team/members.ts index 68339a928..d9d911ca4 100644 --- a/routes/org/team/members.ts +++ b/routes/org/team/members.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { Team, TeamMember } from '../../../business'; import { ReposAppRequest, RequestTeamMemberAddType, UserAlertType } from '../../../interfaces'; -import { getProviders, validateGitHubLogin } from '../../../lib/transitional'; +import { getProviders, validateGitHubLogin } from '../../../transitional'; import RoutePeopleSearch from '../../peopleSearch'; import MiddlewareTeamAdminRequired from './teamAdminRequired'; @@ -55,7 +55,7 @@ async function refreshMembersAndSummary(team2: Team, when): Promise { } router.use( - asyncHandler(async (req: ILocalTeamRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalTeamRequest, res, next) => { // Always make sure to have a relatively up-to-date membership cache available const team2 = req.team2 as Team; req.refreshedMembers = await refreshMembers( @@ -70,7 +70,7 @@ router.use( router.get( '/refresh', - asyncHandler(async (req: ILocalTeamRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalTeamRequest, res, next) => { // Refresh all the pages and also the cached single-page view shown on the team page const team2 = req.team2 as Team; await refreshMembersAndSummary(team2, 'whenever'); @@ -81,7 +81,7 @@ router.get( // Browse members router.use( '/browse', - (req: ILocalTeamRequest, res: Response, next: NextFunction) => { + (req: ILocalTeamRequest, res, next) => { req.team2RemoveType = 'member'; return next(); }, @@ -92,7 +92,7 @@ router.use( router.use( '/add', MiddlewareTeamAdminRequired, - (req: ILocalTeamRequest, res: Response, next: NextFunction) => { + (req: ILocalTeamRequest, res, next) => { req.team2AddType = RequestTeamMemberAddType.Member; return next(); }, @@ -102,7 +102,7 @@ router.use( router.post( '/remove', MiddlewareTeamAdminRequired, - asyncHandler(async (req: ILocalTeamRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalTeamRequest, res, next) => { const { operations } = getProviders(req); const username = validateGitHubLogin(req.body.username); const team2 = req.team2 as Team; @@ -120,7 +120,7 @@ router.post( router.post( '/add', MiddlewareTeamAdminRequired, - asyncHandler(async (req: ILocalTeamRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ILocalTeamRequest, res, next) => { const { operations } = getProviders(req); const username = validateGitHubLogin(req.body.username); const organization = req.organization; diff --git a/routes/org/team/properties.ts b/routes/org/team/properties.ts index 63f792b36..0843c67ed 100644 --- a/routes/org/team/properties.ts +++ b/routes/org/team/properties.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import { ReposAppRequest, UserAlertType } from '../../../interfaces'; -import { wrapError } from '../../../lib/utils'; +import { wrapError } from '../../../utils'; import MiddlewareTeamAdminRequired from './teamAdminRequired'; @@ -16,56 +16,48 @@ interface IRequestWithTeamAndLegacy extends ReposAppRequest { teamUrl?: string; } -router.get( - '/', - MiddlewareTeamAdminRequired, - (req: IRequestWithTeamAndLegacy, res: Response, next: NextFunction) => { - const team2 = req.team2; - team2.getDetails((error) => { - if (error) { - return next(wrapError(error, 'Had trouble getting the detailed properties for this team.')); - } - req.individualContext.webContext.pushBreadcrumb('Properties'); - req.individualContext.webContext.render({ - view: 'org/team/properties', - title: team2.name + ' - Properties', - state: { - team: team2, - teamUrl: req.teamUrl, - }, - }); +router.get('/', MiddlewareTeamAdminRequired, (req: IRequestWithTeamAndLegacy, res, next) => { + const team2 = req.team2; + team2.getDetails((error) => { + if (error) { + return next(wrapError(error, 'Had trouble getting the detailed properties for this team.')); + } + req.individualContext.webContext.pushBreadcrumb('Properties'); + req.individualContext.webContext.render({ + view: 'org/team/properties', + title: team2.name + ' - Properties', + state: { + team: team2, + teamUrl: req.teamUrl, + }, }); - } -); + }); +}); -router.post( - '/', - MiddlewareTeamAdminRequired, - (req: IRequestWithTeamAndLegacy, res: Response, next: NextFunction) => { - const team2 = req.team2; - const organization = req.organization; - const patch = { - name: req.body.ghname, - description: req.body.description, - }; - team2.edit(patch, (error) => { - if (error) { - return next(error); +router.post('/', MiddlewareTeamAdminRequired, (req: IRequestWithTeamAndLegacy, res, next) => { + const team2 = req.team2; + const organization = req.organization; + const patch = { + name: req.body.ghname, + description: req.body.description, + }; + team2.edit(patch, (error) => { + if (error) { + return next(error); + } + req.individualContext.webContext.saveUserAlert( + 'Team properties updated on GitHub', + 'Properties Saved', + UserAlertType.Success + ); + team2.getDetails((getDetailsError) => { + if (getDetailsError) { + return next(getDetailsError); } - req.individualContext.webContext.saveUserAlert( - 'Team properties updated on GitHub', - 'Properties Saved', - UserAlertType.Success - ); - team2.getDetails((getDetailsError) => { - if (getDetailsError) { - return next(getDetailsError); - } - const slug = team2.slug; - return res.redirect('/' + organization.name + '/teams/' + slug); - }); + const slug = team2.slug; + return res.redirect('/' + organization.name + '/teams/' + slug); }); - } -); + }); +}); export default router; diff --git a/routes/org/team/teamAdminRequired.ts b/routes/org/team/teamAdminRequired.ts index 6c40a9667..748ca8d51 100644 --- a/routes/org/team/teamAdminRequired.ts +++ b/routes/org/team/teamAdminRequired.ts @@ -3,11 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response } from 'express'; - import { IReposError } from '../../../interfaces'; -export default function middlewareTeamAdminRequired(req, res: Response, next: NextFunction) { +export default function middlewareTeamAdminRequired(req, res, next) { const teamPermissions = req.teamPermissions; if (!teamPermissions) { return next(new Error('No team permissions information available')); diff --git a/routes/org/teams.ts b/routes/org/teams.ts index 936e5ae5d..74fc0bfd0 100644 --- a/routes/org/teams.ts +++ b/routes/org/teams.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { ReposAppRequest } from '../../interfaces'; -import { popSessionVariable } from '../../lib/utils'; +import { popSessionVariable } from '../../utils'; import lowercaser from '../../middleware/lowercaser'; import RouteTeam from './team/'; @@ -19,7 +19,7 @@ interface ITeamsRequest extends ReposAppRequest { teamUrl?: any; } -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.use(function (req: ReposAppRequest, res, next) { req.individualContext.webContext.pushBreadcrumb('Teams'); req.reposContext = { section: 'teams', @@ -28,7 +28,7 @@ router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { next(); }); -router.get('/', function (req, res: Response, next: NextFunction) { +router.get('/', function (req, res, next) { const beforeLinkReferrer = popSessionVariable(req, res, 'beforeLinkReferrer'); if (beforeLinkReferrer !== undefined) { return res.redirect(beforeLinkReferrer); @@ -40,7 +40,7 @@ router.get('/', lowercaser(['sort', 'set']), RouteTeamsPager); router.use( '/:teamSlug', - asyncHandler(async (req: ITeamsRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ITeamsRequest, res, next) => { const organization = req.organization; const orgBaseUrl = organization.baseUrl; const slug = req.params.teamSlug as string; diff --git a/routes/orgAdmin.ts b/routes/orgAdmin.ts index 9cc992d03..f947ea224 100644 --- a/routes/orgAdmin.ts +++ b/routes/orgAdmin.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; import { requirePortalAdministrationPermission } from '../middleware/business/administration'; import { PostgresLinkProvider } from '../lib/linkProviders/postgres/postgresLinkProvider'; @@ -16,7 +16,7 @@ import { Organization } from '../business'; import { Account } from '../business'; import { ILinkProvider } from '../lib/linkProviders'; import { ICorporateLink, ReposAppRequest, IProviders, UnlinkPurpose } from '../interfaces'; -import { isCodespacesAuthenticating } from '../lib/utils'; +import { isCodespacesAuthenticating } from '../utils'; // - - - Middleware: require that the user isa portal administrator to continue router.use(requirePortalAdministrationPermission); @@ -25,11 +25,9 @@ router.use(requirePortalAdministrationPermission); // These functions are not pretty. enum OperationsAction { - DestroyLink = 'Destroy link', - MarkAsServiceAccount = 'Mark as service account', - UnmarkServiceAccount = 'Unmark service account', - DestroyCollaboratorGrants = 'Destroy collaborator grants', - Destroy100 = 'Destroy 100', + DestroyLink, + MarkAsServiceAccount, + UnmarkServiceAccount, } enum UserQueryByType { @@ -209,13 +207,10 @@ async function loadInformation( if (queryCache && queryCache.supportsRepositoryCollaborators) { const result = await queryCache.userCollaboratorRepositories(thirdPartyId); const collaboratorRepositories = []; - const hasMany = result.length > 100; for (const { repository } of result) { try { - if (!hasMany) { - await repository.getDetails(); - } - collaboratorRepositories.push(repository.organization.name + '/' + repository.name); + await repository.getDetails(); + collaboratorRepositories.push(repository.full_name); } catch (ignoreError) { console.dir(ignoreError); } @@ -269,7 +264,7 @@ async function getGitHubAccountInformationById(operations: Operations, id: strin return account; } -router.get('/whois/id/:githubid', function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.get('/whois/id/:githubid', function (req: ReposAppRequest, res, next) { const thirdPartyId = req.params.githubid; const providers = getProviders(req); queryByGitHubId(providers, thirdPartyId) @@ -301,7 +296,7 @@ interface IIDValue { router.get( '/whois/link/:linkid', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const linkId = req.params.linkid; const { linkProvider: lp } = getProviders(req); const linkProvider = lp as PostgresLinkProvider; @@ -320,7 +315,7 @@ router.get( router.post( '/whois/link/:linkid', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const { config } = getProviders(req); const linkId = req.params.linkid; const isLinkDelete = req.body['delete-link']; @@ -388,7 +383,7 @@ router.post( router.post( '/whois/link/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const { config, operations } = getProviders(req); const allowAdministratorManualLinking = operations?.config?.features?.allowAdministratorManualLinking; if (!allowAdministratorManualLinking) { @@ -441,17 +436,13 @@ router.post( }) ); -router.post('/whois/id/:githubid', function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.post('/whois/id/:githubid', function (req: ReposAppRequest, res, next) { const thirdPartyId = req.params.githubid; const markAsServiceAccount = req.body['mark-as-service-account']; const unmarkServiceAccount = req.body['unmark-service-account']; - const removeCollaboration = req.body['remove-collaboration'] || req.body['remove-collaboration-100']; - const remove100 = req.body['remove-collaboration-100']; const providers = getProviders(req); let action = OperationsAction.DestroyLink; - if (removeCollaboration) { - action = remove100 ? OperationsAction.Destroy100 : OperationsAction.DestroyCollaboratorGrants; - } else if (markAsServiceAccount) { + if (markAsServiceAccount) { action = OperationsAction.MarkAsServiceAccount; } else if (unmarkServiceAccount) { action = OperationsAction.UnmarkServiceAccount; @@ -467,7 +458,7 @@ router.post('/whois/id/:githubid', function (req: ReposAppRequest, res: Response } req.individualContext.webContext.render({ view: 'organization/whois/drop', - title: `${action} link by ID ${thirdPartyId}`, + title: `Dropped link by ID ${thirdPartyId}`, state, }); }) @@ -476,7 +467,7 @@ router.post('/whois/id/:githubid', function (req: ReposAppRequest, res: Response }); }); -router.get('/whois/aad/:upn', function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.get('/whois/aad/:upn', function (req: ReposAppRequest, res, next) { const upn = req.params.upn; const providers = getProviders(req); queryByCorporateUsername(providers, upn) @@ -497,7 +488,7 @@ router.get('/whois/aad/:upn', function (req: ReposAppRequest, res: Response, nex .catch(next); }); -router.get('/whois/github/:username', function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.get('/whois/github/:username', function (req: ReposAppRequest, res, next) { const login = req.params.username; const providers = getProviders(req); queryByGitHubLogin(providers, login) @@ -516,17 +507,13 @@ router.get('/whois/github/:username', function (req: ReposAppRequest, res: Respo .catch(next); }); -router.post('/whois/github/:username', function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.post('/whois/github/:username', function (req: ReposAppRequest, res, next) { const username = req.params.username; const markAsServiceAccount = req.body['mark-as-service-account']; const unmarkServiceAccount = req.body['unmark-service-account']; - const removeCollaboration = req.body['remove-collaboration'] || req.body['remove-collaboration-100']; - const remove100 = req.body['remove-collaboration-100']; const providers = getProviders(req); let action = OperationsAction.DestroyLink; - if (removeCollaboration) { - action = remove100 ? OperationsAction.Destroy100 : OperationsAction.DestroyCollaboratorGrants; - } else if (markAsServiceAccount) { + if (markAsServiceAccount) { action = OperationsAction.MarkAsServiceAccount; } else if (unmarkServiceAccount) { action = OperationsAction.UnmarkServiceAccount; @@ -643,13 +630,6 @@ async function destructiveLogic( ); } - if (action === OperationsAction.DestroyCollaboratorGrants || action === OperationsAction.Destroy100) { - const account: Account = operations.getAccount(thirdPartyId); - const res = await account.removeCollaboratorPermissions(action === OperationsAction.Destroy100); - state.messages = res.history; - return state; - } - // Account termination if (linkQuery && linkQuery.link && !thirdPartyId) { thirdPartyId = linkQuery.link.thirdPartyId; @@ -692,7 +672,7 @@ router.get('/bulkRepoDelete', (req: ReposAppRequest, res) => { router.post( '/bulkRepoDelete', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const { operations } = getProviders(req); let repositories = req.body.repositories; // TODO: FEATURE FLAG: add a feature flag whether this API is available. @@ -728,7 +708,7 @@ router.post( log.push(`Skipping, does not appear to be a GitHub repo URL: ${repositoryName}`); } } - return res.json(log) as unknown as void; + return res.json(log); }) ); diff --git a/routes/orgs.ts b/routes/orgs.ts index 08e812639..3a0750280 100644 --- a/routes/orgs.ts +++ b/routes/orgs.ts @@ -5,14 +5,14 @@ import querystring from 'querystring'; -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { IReposRequestWithOrganization } from '../interfaces'; import { injectReactClient, TryFallbackToBlob } from '../middleware'; -import { getProviders, hasStaticReactClientApp } from '../lib/transitional'; -import { wrapError } from '../lib/utils'; +import { getProviders, hasStaticReactClientApp } from '../transitional'; +import { wrapError } from '../utils'; import orgRoute from './org/'; @@ -26,11 +26,7 @@ if (hasReactApp) { router.use('/:orgName', asyncHandler(forwardToOrganizationRoutes)); -async function forwardToOrganizationRoutes( - req: IReposRequestWithOrganization, - res: Response, - next: NextFunction -) { +async function forwardToOrganizationRoutes(req: IReposRequestWithOrganization, res, next) { // This middleware contains both the original GitHub operations types // as well as the newer implementation. In time this will peel apart. const orgName = req.params.orgName; diff --git a/routes/people.ts b/routes/people.ts index b2592cadb..1f9e82ce4 100644 --- a/routes/people.ts +++ b/routes/people.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; import { ReposAppRequest } from '../interfaces'; import RoutePeopleSearch from './peopleSearch'; import MiddlewareSystemWidePermissions from '../middleware/github/systemWidePermissions'; -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.use(function (req: ReposAppRequest, res, next) { req.individualContext.webContext.pushBreadcrumb('People'); req.reposContext = { section: 'people', @@ -22,7 +22,7 @@ router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { }); // Campaign-related redirect to take the user to GitHub -router.get('/github/:login', (req: ReposAppRequest, res: Response, next: NextFunction) => { +router.get('/github/:login', (req: ReposAppRequest, res, next) => { const providers = getProviders(req); if (!providers || !providers.campaign) { return next(); diff --git a/routes/peopleSearch.ts b/routes/peopleSearch.ts index 023c08b60..51c2746e7 100644 --- a/routes/peopleSearch.ts +++ b/routes/peopleSearch.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; import { RequestWithSystemwidePermissions, RequestTeamMemberAddType } from '../interfaces'; import { ensureAllLinksInMemory, getAllLinksFromRequest } from '../middleware/business/allLinks'; @@ -75,7 +75,7 @@ async function getPeopleAcrossOrganizations( router.get( '/', lowercaser(['sort']), - asyncHandler(async (req: IPeopleSearchRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: IPeopleSearchRequest, res, next) => { const linksFromMiddleware = getAllLinksFromRequest(req); const { operations } = getProviders(req); const org = req.organization ? req.organization.name : null; diff --git a/routes/placeholders.ts b/routes/placeholders.ts index bb566fa43..cf28a6626 100644 --- a/routes/placeholders.ts +++ b/routes/placeholders.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../interfaces'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; // These are Microsoft-specific, we'll remove these eventually. // TODO: remove from open source version since not helpful having random routes in place diff --git a/routes/releasesSpa.ts b/routes/releasesSpa.ts index a80cee5f5..fb683135f 100644 --- a/routes/releasesSpa.ts +++ b/routes/releasesSpa.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import { ReposAppRequest } from '../interfaces'; const router: Router = Router(); diff --git a/routes/repos.ts b/routes/repos.ts index a8a0f7c2c..8d0daffb5 100644 --- a/routes/repos.ts +++ b/routes/repos.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../interfaces'; @@ -11,7 +11,7 @@ import lowercaser from '../middleware/lowercaser'; import RouteReposPager from './reposPager'; -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.use(function (req: ReposAppRequest, res, next) { req.individualContext.webContext.pushBreadcrumb('Repositories'); req.reposContext = { section: 'repos', diff --git a/routes/reposPager.ts b/routes/reposPager.ts index 17e5c7fb2..a44500fb9 100644 --- a/routes/reposPager.ts +++ b/routes/reposPager.ts @@ -7,7 +7,7 @@ import asyncHandler from 'express-async-handler'; import { NextFunction, Response } from 'express'; import _ from 'lodash'; -import { daysInMilliseconds } from '../lib/utils'; +import { daysInMilliseconds } from '../utils'; import { Repository, IPersonalizedUserAggregateRepositoryPermission, @@ -20,7 +20,7 @@ import { import QueryCache from '../business/queryCache'; import { GitHubRepositoryType, IReposAppWithTeam } from '../interfaces'; import { IRequestTeamPermissions } from '../middleware/github/teamPermissions'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; import { UserContext } from '../business/user/aggregate'; interface IGetReposAndOptionalTeamPermissionsResponse { @@ -213,7 +213,7 @@ export default asyncHandler(async function (req: IReposAppWithTeam, res: Respons await search.search(page, req.query.sort as string); - await Promise.all(search.repos.map(repo => repo.getDetails())); + // await Promise.all(search.repos.map(repo => repo.getDetails())); req.individualContext.webContext.render({ view: 'repos/', diff --git a/routes/settings/approvals.ts b/routes/settings/approvals.ts index e71c73bbc..aa150ee3c 100644 --- a/routes/settings/approvals.ts +++ b/routes/settings/approvals.ts @@ -3,19 +3,19 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { IApprovalProvider } from '../../business/entities/teamJoinApproval/approvalProvider'; -import { TeamJoinApprovalEntity } from '../../business/entities/teamJoinApproval/teamJoinApproval'; -import { safeLocalRedirectUrl } from '../../lib/utils'; +import { IApprovalProvider } from '../../entities/teamJoinApproval/approvalProvider'; +import { TeamJoinApprovalEntity } from '../../entities/teamJoinApproval/teamJoinApproval'; +import { safeLocalRedirectUrl } from '../../utils'; import { Operations } from '../../business'; import { Team } from '../../business'; import { Organization } from '../../business'; import { IAggregateUserTeams } from '../../business/user/aggregate'; import { ReposAppRequest, IReposError, UserAlertType } from '../../interfaces'; -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; export interface ApprovalPair { team: Team; @@ -82,7 +82,7 @@ export async function Approvals_getUserRequests( router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const { approvalProvider, operations } = getProviders(req); if (!approvalProvider) { return next(new Error('No approval provider instance available')); @@ -107,7 +107,7 @@ router.get( }) ); -router.post('/:requestid/cancel', function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.post('/:requestid/cancel', function (req: ReposAppRequest, res, next) { const { approvalProvider } = getProviders(req); if (!approvalProvider) { return next(new Error('No approval provider instance available')); @@ -143,7 +143,7 @@ router.post('/:requestid/cancel', function (req: ReposAppRequest, res: Response, router.get( '/:requestid', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const requestid = req.params.requestid; const { approvalProvider, operations } = getProviders(req); req.individualContext.webContext.pushBreadcrumb('Your Request'); diff --git a/routes/settings/authorizations.ts b/routes/settings/authorizations.ts index 17aae9bec..1cd16c480 100644 --- a/routes/settings/authorizations.ts +++ b/routes/settings/authorizations.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; +import { getProviders } from '../../transitional'; import { Operations } from '../../business'; import { ReposAppRequest, ICorporateLink } from '../../interfaces'; @@ -54,7 +54,7 @@ function createValidator(operations: Operations, link: ICorporateLink, token: st }; } -router.use((req: IRequestWithAuthorizations, res: Response, next: NextFunction) => { +router.use((req: IRequestWithAuthorizations, res, next) => { // This is a lightweight, temporary implementation of authorization management to help clear // stored session tokens for apps like GitHub, VSTS, etc. const { operations } = getProviders(req); @@ -113,7 +113,7 @@ router.get('/', (req: IRequestWithAuthorizations, res) => { router.get( '/validate', - asyncHandler(async (req: IRequestWithAuthorizations, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestWithAuthorizations, res, next) => { const authorizations = req.authorizations; for (const authorization of authorizations) { const validator = authorization.validator; diff --git a/routes/settings/campaigns.ts b/routes/settings/campaigns.ts index f2c8cb7aa..a5c7b5ef3 100644 --- a/routes/settings/campaigns.ts +++ b/routes/settings/campaigns.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { ReposAppRequest, UserAlertType } from '../../interfaces'; -import { CreateError, getProviders } from '../../lib/transitional'; +import { CreateError, getProviders } from '../../transitional'; router.use('/:campaignGroupId', (req: ReposAppRequest, res: any, next) => { const { config } = getProviders(req); @@ -25,21 +25,21 @@ router.use('/:campaignGroupId', (req: ReposAppRequest, res: any, next) => { router.get( '/:campaignGroupId/unsubscribe', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res: any, next) => { return await modifySubscription(true, req, res, next); }) ); router.get( '/:campaignGroupId/subscribe', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res: any, next) => { return await modifySubscription(false, req, res, next); }) ); router.get( '/:campaignGroupId', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res: any, next) => { const { campaignStateProvider } = getProviders(req); if (!campaignStateProvider) { return next(new Error('This app is not configured for campaign management')); @@ -53,7 +53,7 @@ router.get( return next(new Error('Corporate authentication and identity required')); } const currentState = await campaignStateProvider.getState(corporateId, campaignGroupId); - return res.json(currentState) as unknown as void; + return res.json(currentState); }) ); diff --git a/routes/settings/contributionData.ts b/routes/settings/contributionData.ts index c68fc70b4..7e32f98f6 100644 --- a/routes/settings/contributionData.ts +++ b/routes/settings/contributionData.ts @@ -3,17 +3,43 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { ErrorHelper, getProviders } from '../../lib/transitional'; -import { UserSettings } from '../../business/entities/userSettings'; -import { UserAlertType } from '../../interfaces'; -import type { ReposAppRequestWithUserSettings } from '../../interfaces/middleware'; -import { getUserSettings } from '../../middleware/business/userSettings'; +import { ErrorHelper, getProviders } from '../../transitional'; +import { UserSettings } from '../../entities/userSettings'; +import { ReposAppRequest, UserAlertType } from '../../interfaces'; -function view(req: ReposAppRequestWithUserSettings, res) { +export interface IRequestWithUserSettings extends ReposAppRequest { + userSettings?: UserSettings; +} + +async function getSettings(req: IRequestWithUserSettings, res, next) { + const corporateId = req.individualContext.corporateIdentity.id; + const { userSettingsProvider } = getProviders(req); + if (!req.userSettings) { + let settings: UserSettings = null; + try { + settings = await userSettingsProvider.getUserSettings(corporateId); + } catch (notFoundError) { + if (ErrorHelper.IsNotFound(notFoundError)) { + // ignore + } else { + throw notFoundError; + } + } + if (!settings) { + settings = new UserSettings(); + settings.corporateId = corporateId; + await userSettingsProvider.insertUserSettings(settings); + } + req.userSettings = settings; + } + return next(); +} + +function view(req: IRequestWithUserSettings, res) { const userSettings = req.userSettings; req.individualContext.webContext.render({ view: 'settings/contributionData', @@ -24,13 +50,13 @@ function view(req: ReposAppRequestWithUserSettings, res) { }); } -router.use(asyncHandler(getUserSettings)); +router.use(asyncHandler(getSettings)); router.get('/', view); router.post( '/', - asyncHandler(async function (req: ReposAppRequestWithUserSettings, res: Response, next: NextFunction) { + asyncHandler(async function (req: IRequestWithUserSettings, res, next) { const isOptIn = !!(req.body.optIn === '1'); const currentSetting = req.userSettings.contributionShareOptIn; req.userSettings.contributionShareOptIn = isOptIn; diff --git a/routes/settings/index.ts b/routes/settings/index.ts index 8b25be30a..37ea8f92b 100644 --- a/routes/settings/index.ts +++ b/routes/settings/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); diff --git a/routes/settings/personalAccessTokens.ts b/routes/settings/personalAccessTokens.ts index 303345a1a..9aafe0077 100644 --- a/routes/settings/personalAccessTokens.ts +++ b/routes/settings/personalAccessTokens.ts @@ -3,18 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../lib/transitional'; -import { PersonalAccessToken } from '../../business/entities/token/token'; +import { getProviders } from '../../transitional'; +import { PersonalAccessToken } from '../../entities/token/token'; import { ReposAppRequest } from '../../interfaces'; -type ResponseWithNewKey = Response & { - newKey: string; -}; - interface IPersonalAccessTokenForDisplay { active: boolean; expired: boolean; @@ -52,7 +48,7 @@ function translateTableToEntities( }); } -function getPersonalAccessTokens(req: ReposAppRequest, res: Response, next: NextFunction) { +function getPersonalAccessTokens(req: ReposAppRequest, res, next) { const providers = getProviders(req); const tokenProvider = providers.tokenProvider; const corporateId = req.individualContext.corporateIdentity.id; @@ -84,7 +80,7 @@ router.use(getPersonalAccessTokens); router.get('/', view); -function createToken(req: ReposAppRequest, res: ResponseWithNewKey, next: NextFunction) { +function createToken(req: ReposAppRequest, res, next) { const providers = getProviders(req); const tokenProvider = providers.tokenProvider; const insights = req.insights; @@ -140,7 +136,7 @@ router.post('/extension', createToken); router.post( '/delete', - asyncHandler(async (req: IRequestForSettingsPersonalAccessTokens, res: Response, next: NextFunction) => { + asyncHandler(async (req: IRequestForSettingsPersonalAccessTokens, res, next) => { const providers = getProviders(req); const tokenProvider = providers.tokenProvider; const revokeAll = req.body.revokeAll === '1'; diff --git a/routes/teams.ts b/routes/teams.ts index edf5c45ca..c1220135a 100644 --- a/routes/teams.ts +++ b/routes/teams.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; const router: Router = Router(); import lowercaser from '../middleware/lowercaser'; @@ -11,7 +11,7 @@ import { ReposAppRequest } from '../interfaces'; import RouteTeamsPager from './teamsPager'; -router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { +router.use(function (req: ReposAppRequest, res, next) { req.individualContext.webContext.pushBreadcrumb('Teams'); req.reposContext = { section: 'teams', diff --git a/routes/teamsPager.ts b/routes/teamsPager.ts index d4225c2c6..8dc93f1ab 100644 --- a/routes/teamsPager.ts +++ b/routes/teamsPager.ts @@ -7,7 +7,7 @@ import _ from 'lodash'; import asyncHandler from 'express-async-handler'; import { NextFunction, Response } from 'express'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; import { Operations } from '../business'; import { Team } from '../business'; import { UserContext } from '../business/user/aggregate'; diff --git a/routes/thanks.ts b/routes/thanks.ts index ff95bcfe6..04d7df55a 100644 --- a/routes/thanks.ts +++ b/routes/thanks.ts @@ -5,7 +5,7 @@ import { ReposAppRequest } from '../interfaces'; import thisPackage from '../package.json'; -import { getProviders } from '../lib/transitional'; +import { getProviders } from '../transitional'; const express = require('express'); const router = express.Router(); diff --git a/routes/undo.ts b/routes/undo.ts index a08e527ff..f0e61823e 100644 --- a/routes/undo.ts +++ b/routes/undo.ts @@ -3,15 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { Operations, Repository } from '../business'; -import { ErrorHelper, getProviders } from '../lib/transitional'; -import { AuditLogRecord } from '../business/entities/auditLogRecord/auditLogRecord'; -import { daysInMilliseconds } from '../lib/utils'; -import { AuditEvents } from '../business/entities/auditLogRecord'; +import { ErrorHelper, getProviders } from '../transitional'; +import { AuditLogRecord } from '../entities/auditLogRecord/auditLogRecord'; +import { daysInMilliseconds } from '../utils'; +import { AuditEvents } from '../entities/auditLogRecord'; import { IGitHubIdentity, IndividualContext } from '../business/user'; import { IMail } from '../lib/mailProvider'; import { GitHubRepositoryPermission, ReposAppRequest, UserAlertType } from '../interfaces'; @@ -291,7 +291,7 @@ async function undoTeamAdminRepoPermissionAsync( } router.use( - asyncHandler(async function (req: IHaveUndoCandidates, res: Response, next: NextFunction) { + asyncHandler(async function (req: IHaveUndoCandidates, res, next) { const { operations } = getProviders(req); if (!operations.allowUndoSystem) { res.status(404); @@ -322,7 +322,7 @@ router.use( router.post( '/', - asyncHandler(async (req: IHaveUndoCandidates, res: Response, next: NextFunction) => { + asyncHandler(async (req: IHaveUndoCandidates, res, next) => { const { operations } = getProviders(req); const insights = operations.insights; const link = req.individualContext.link; @@ -394,7 +394,7 @@ router.post( router.get( '/', - asyncHandler(async (req: IHaveUndoCandidates, res: Response, next: NextFunction) => { + asyncHandler(async (req: IHaveUndoCandidates, res, next) => { const { operations } = getProviders(req); const insights = operations.insights; insights?.trackMetric({ name: 'UndoPageViews', value: 1 }); diff --git a/routes/unlink.ts b/routes/unlink.ts index 3e79266a6..af5a7e0a6 100644 --- a/routes/unlink.ts +++ b/routes/unlink.ts @@ -3,18 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { NextFunction, Response, Router } from 'express'; +import { Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../lib/transitional'; -import { wrapError } from '../lib/utils'; +import { getProviders } from '../transitional'; +import { wrapError } from '../utils'; import { IndividualContext } from '../business/user'; import { jsonError } from '../middleware'; import { ReposAppRequest, OrganizationMembershipState, UnlinkPurpose } from '../interfaces'; router.use( - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const memberOfOrganizations = []; const { operations } = getProviders(req); const ghi = req.individualContext.getGitHubIdentity(); @@ -44,7 +44,7 @@ router.use( router.get( '/', - asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + asyncHandler(async (req: ReposAppRequest, res, next) => { const link = req.individualContext.link; const id = req.individualContext.getGitHubIdentity().id; const { operations } = getProviders(req); @@ -110,7 +110,7 @@ export async function unlinkInteractive( router.post( '/', - asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { + asyncHandler(async function (req: ReposAppRequest, res, next) { const individualContext = req.individualContext; // TODO: validate return unlinkInteractive(false, individualContext, req, res, next); diff --git a/scripts/configuration.ts b/scripts/configuration.ts index 8225c5164..28f80acdc 100644 --- a/scripts/configuration.ts +++ b/scripts/configuration.ts @@ -3,16 +3,24 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import job from '../job'; +async function go(providers: IProviders): Promise { + const { config } = providers; + for (const key of Object.getOwnPropertyNames(config)) { + console.log(`${key}\n`); + console.dir(config[key]); + console.log(); + } +} -job.run( - async (providers) => { - const { config } = providers; - for (const key of Object.getOwnPropertyNames(config)) { - console.log(`${key}\n`); - console.dir(config[key]); - console.log(); - } +import app from '../app'; +import { IProviders, IReposJob } from '../interfaces'; + +app.runJob( + async function ({ providers }: IReposJob) { + await go(providers); + return {}; }, - { name: 'Script: View configuration' } + { + enableAllGitHubApps: true, + } ); diff --git a/scripts/localEnvironment.ts b/scripts/localEnvironment.ts index 8611726c5..a3fad71cd 100644 --- a/scripts/localEnvironment.ts +++ b/scripts/localEnvironment.ts @@ -3,13 +3,25 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import job from '../job'; +// The local environment script is designed to allow for local debugging, test and +// development scenarios. The go method is called with resolved configuration. -// This script allows for quick inner-loop development. +async function go(providers: IProviders): Promise { + // --------------------------------------------------------------------------- +} -job.run( - async (providers) => { - // +// ----------------------------------------------------------------------------- +// Local script initialization +// ----------------------------------------------------------------------------- +import app from '../app'; +import { IProviders, IReposJob } from '../interfaces'; + +app.runJob( + async function ({ providers }: IReposJob) { + await go(providers); + return {}; }, - { name: 'Local Environment' } + { + enableAllGitHubApps: true, + } ); diff --git a/scripts/migrateLinks/index.ts b/scripts/migrateLinks/index.ts new file mode 100644 index 000000000..6c6856b80 --- /dev/null +++ b/scripts/migrateLinks/index.ts @@ -0,0 +1,11 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import Job from './task'; +import app from '../../app'; + +app.runJob(Job, { + defaultDebugOutput: 'cache,restapi', +}); diff --git a/scripts/migrateLinks.ts b/scripts/migrateLinks/task.ts similarity index 84% rename from scripts/migrateLinks.ts rename to scripts/migrateLinks/task.ts index 316a702af..f7aaa3b02 100644 --- a/scripts/migrateLinks.ts +++ b/scripts/migrateLinks/task.ts @@ -14,17 +14,14 @@ // LINK_MIGRATION_OVERWRITE values : 'overwrite', 'skip' import throat from 'throat'; +import { IReposJob, ICorporateLink } from '../../interfaces'; -import job from '../job'; -import { ICorporateLink, IProviders } from '../interfaces'; -import { createAndInitializeLinkProviderInstance } from '../lib/linkProviders'; -import { getThirdPartyLinkById } from '../lib/transitional'; +import { createAndInitializeLinkProviderInstance, ILinkProvider } from '../../lib/linkProviders'; +import { ErrorHelper } from '../../transitional'; const parallelWorkLimit = 5; -job.run(migration, { name: 'Link migration' }); - -async function migration(providers: IProviders): Promise { +export default async function migration({ providers }: IReposJob): Promise { // const sourceLinkProvider = providers.linkProvider; const config = providers.config; const sourceLinkProviderName = 'table'; @@ -60,7 +57,7 @@ async function migration(providers: IProviders): Promise { await Promise.all( allSourceLinks.map((sourceLink: ICorporateLink) => throttle(async () => { - const existingLink = await getThirdPartyLinkById(destinationLinkProvider, sourceLink.thirdPartyId); + const existingLink = await getThirdPartyLink(destinationLinkProvider, sourceLink.thirdPartyId); if (existingLink && overwriteDestinationLinks) { console.warn('Removing existing destination link...'); await destinationLinkProvider.deleteLink(existingLink); @@ -104,6 +101,17 @@ async function migration(providers: IProviders): Promise { console.log(); } +async function getThirdPartyLink(linkProvider: ILinkProvider, thirdPartyId: string): Promise { + try { + return await linkProvider.getByThirdPartyId(thirdPartyId); + } catch (error) { + if (ErrorHelper.IsNotFound(error)) { + return null; + } + throw error; + } +} + async function getUserIdByUpn(graphProvider, upn: string): Promise { return new Promise((resolve, reject) => { graphProvider.getUserById(upn, (err, info) => { diff --git a/scripts/postgres/setup.ts b/scripts/postgres/setup.ts index 7adb4968c..7bcf5fe3f 100644 --- a/scripts/postgres/setup.ts +++ b/scripts/postgres/setup.ts @@ -12,7 +12,7 @@ import path from 'path'; initialize(); async function setup() { - const sql = fs.readFileSync(path.join(__dirname, '../../data/pg.sql'), 'utf8'); + const sql = fs.readFileSync(path.join(__dirname, '../../../pg.sql'), 'utf8'); const server = await prompt('postgres server: '); const adminUsername = await prompt('admin user: '); diff --git a/lib/transitional.ts b/transitional.ts similarity index 75% rename from lib/transitional.ts rename to transitional.ts index e0806ba54..b2bc2813b 100644 --- a/lib/transitional.ts +++ b/transitional.ts @@ -7,22 +7,19 @@ import crypto from 'crypto'; import githubUsernameRegex from 'github-username-regex'; import { AxiosError } from 'axios'; -import appPackage from '../package.json'; -import type { ICreateRepositoryApiResult } from '../api/createRepo'; -import { Repository } from '../business/repository'; +import appPackage from './package.json'; +import type { ICreateRepositoryApiResult } from './api/createRepo'; +import { Repository } from './business/repository'; import { GitHubRepositoryPermission, - type ICorporateLink, - type IDictionary, - type IFunctionPromise, - type IGitHubCollaboratorPermissions, - type IProviders, - type ISettledValue, - type ReposAppRequest, + IDictionary, + IFunctionPromise, + IProviders, + ISettledValue, + ReposAppRequest, SettledState, -} from '../interfaces'; -import { ITeamRepositoryPermission, Organization } from '../business'; -import { ILinkProvider } from './linkProviders'; +} from './interfaces'; +import { Organization } from './business'; const packageVariableName = 'static-react-package-name'; export function hasStaticReactClientApp() { @@ -56,34 +53,19 @@ export function SettleToStateValue(promise: Promise): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on('data', (data: Buffer | string) => { - chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - }); - readableStream.on('end', () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on('error', reject); - }); + throw new Error(`Unsupported GitHubRepositoryPermission value inside permissions`); } export function isPermissionBetterThan( @@ -93,8 +75,8 @@ export function isPermissionBetterThan( if (!currentBest) { return true; } - const comparison = projectCollaboratorPermissionToGitHubRepositoryPermission(currentBest); - switch (projectCollaboratorPermissionToGitHubRepositoryPermission(newConsideration)) { + const comparison = MassagePermissionsToGitHubRepositoryPermission(currentBest); + switch (MassagePermissionsToGitHubRepositoryPermission(newConsideration)) { case GitHubRepositoryPermission.Admin: return true; case GitHubRepositoryPermission.Maintain: @@ -121,9 +103,7 @@ export function isPermissionBetterThan( return false; } -export function projectCollaboratorPermissionToGitHubRepositoryPermission( - value: string -): GitHubRepositoryPermission { +export function MassagePermissionsToGitHubRepositoryPermission(value: string): GitHubRepositoryPermission { // collaborator level APIs return a more generic read/write value, lead to some bad caches in the past... // TODO: support new collaboration values as they come online for Enterprise Cloud! switch (value) { @@ -140,15 +120,15 @@ export function projectCollaboratorPermissionToGitHubRepositoryPermission( case 'read': return GitHubRepositoryPermission.Pull; default: - throw CreateError.InvalidParameters( - `Invalid ${value} GitHub repository permission [projectCollaboratorPermissionsToGitHubRepositoryPermission]` + throw new Error( + `Invalid ${value} GitHub repository permission [massagePermissionsToGitHubRepositoryPermission]` ); } } export class CreateError { - static CreateStatusCodeError(code: number, message?: string, cause?: Error): Error { - const error = cause ? new Error(message, { cause }) : new Error(message); + static CreateStatusCodeError(code: number, message?: string): Error { + const error = new Error(message); error['status'] = code; return error; } @@ -170,20 +150,16 @@ export class CreateError { return ErrorHelper.SetInnerError(CreateError.CreateStatusCodeError(400, message), innerError); } - static NotAuthenticated(message: string, cause?: Error): Error { - return CreateError.CreateStatusCodeError(401, message, cause); + static NotAuthenticated(message: string): Error { + return CreateError.CreateStatusCodeError(401, message); } - static NotImplemented(message?: string, cause?: Error): Error { - return CreateError.CreateStatusCodeError(500, message || 'This scenario is not yet implemented', cause); + static NotAuthorized(message: string): Error { + return CreateError.CreateStatusCodeError(403, message); } - static NotAuthorized(message: string, cause?: Error): Error { - return CreateError.CreateStatusCodeError(403, message, cause); - } - - static ServerError(message: string, cause?: Error): Error { - return CreateError.CreateStatusCodeError(500, message, cause); + static ServerError(message: string, innerError?: Error): Error { + return ErrorHelper.SetInnerError(CreateError.CreateStatusCodeError(500, message), innerError); } } @@ -217,11 +193,6 @@ export class ErrorHelper { return statusNumber && statusNumber === 404; } - public static IsServerError(error: Error): boolean { - const statusNumber = ErrorHelper.GetStatus(error); - return statusNumber && statusNumber >= 500; - } - public static IsNotAuthorized(error: Error): boolean { const statusNumber = ErrorHelper.GetStatus(error); return statusNumber && statusNumber === 403; @@ -259,6 +230,9 @@ export class ErrorHelper { if (asAny?.statusCode && typeof asAny.statusCode === 'number') { return asAny.statusCode as number; } + if (asAny?.code && typeof asAny.code === 'number') { + return asAny.code as number; + } if (asAny?.status) { const status = asAny.status; const type = typeof status; @@ -271,9 +245,6 @@ export class ErrorHelper { return null; } } - if (asAny?.code && typeof asAny.code === 'number') { - return asAny.code as number; - } return null; } } @@ -301,29 +272,11 @@ export function stripDistFolderName(dirname: string) { return dirname; } -export function getSafeCosmosResourceKey(key: string) { - return key.replace(/[%:\\/?#]/g, ''); -} - export function sha256(str: string) { const hash = crypto.createHash('sha256').update(str).digest('base64'); return hash; } -export async function getThirdPartyLinkById( - linkProvider: ILinkProvider, - thirdPartyId: string | number -): Promise { - try { - return await linkProvider.getByThirdPartyId(String(thirdPartyId)); - } catch (error) { - if (ErrorHelper.IsNotFound(error)) { - return null; - } - throw error; - } -} - export interface ICustomizedNewRepositoryLogic { createContext(req: any): INewRepositoryContext; getAdditionalTelemetryProperties(context: INewRepositoryContext): IDictionary; diff --git a/tsconfig.json b/tsconfig.json index b04ed2bd9..7edc1ea63 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,11 @@ { "compilerOptions": { - "module": "NodeNext", + "module": "commonjs", "sourceMap": true, "outDir": "./dist", "incremental": true, "allowJs": true, - "declaration": true, - "moduleResolution": "nodenext", + "moduleResolution": "node", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, @@ -23,8 +22,8 @@ "./business/**/*", "./config/**/*", "./data/**/*", - "business/entities/**/*", - "business/features/**/*", + "./entities/**/*", + "./features/**/*", "./interfaces/**/*", "./jobs/**/*", "./lib/**/*", @@ -33,6 +32,6 @@ "./routes/**/*", "./scripts/**/*", "./test/**/*", - "business/webhooks/**/*" + "./webhooks/**/*" ] } diff --git a/lib/utils.ts b/utils.ts similarity index 90% rename from lib/utils.ts rename to utils.ts index d1935884c..514b95476 100644 --- a/lib/utils.ts +++ b/utils.ts @@ -8,19 +8,15 @@ import fs from 'fs'; import path from 'path'; import { URL } from 'url'; import zlib from 'zlib'; +import { type Repository } from './business/repository'; -import { type Repository } from '../business/repository'; -import type { ReposAppRequest, IAppSession, IReposError, SiteConfiguration } from '../interfaces'; +import { ReposAppRequest, IAppSession, IReposError, SiteConfiguration } from './interfaces'; import { getProviders } from './transitional'; export function daysInMilliseconds(days: number): number { return 1000 * 60 * 60 * 24 * days; } -export function dateToDateString(date: Date) { - return date.toISOString().substr(0, 10); -} - export function stringOrNumberAsString(value: any) { if (typeof value === 'number') { return (value as number).toString(); @@ -266,12 +262,7 @@ export function writeTextToFile(filename: string, stringContent: string): Promis }); } -export function quitInTenSeconds(successful: boolean, config?: SiteConfiguration) { - // To allow telemetry to flush, we'll wait typically - if (config?.debug?.exitImmediately || process.env.EXIT_IMMEDIATELY === '1') { - console.log(`EXIT_IMMEDIATELY set, exiting... exit code=${successful ? 0 : 1}`); - return process.exit(successful ? 0 : 1); - } +export function quitInTenSeconds(successful: boolean) { console.log(`Quitting process in 10s... exit code=${successful ? 0 : 1}`); return setTimeout(() => { process.exit(successful ? 0 : 1); @@ -363,24 +354,3 @@ export function getDateTimeBasedBlobFolder() { } export const botBracket = '[bot]'; - -const githubAvatarHostnames = [ - 'githubusercontent.com', - 'objects.githubusercontent.com', - 'object.githubusercontent.com', - 'raw.githubusercontent.com', - 'avatars.githubusercontent.com', -]; - -export function getUserIdFromWellFormedAvatar(avatar: string): string { - // https://*.githubusercontent.com/u/userid?v=* - const url = new URL(avatar); - if (githubAvatarHostnames.includes(url.hostname)) { - const { pathname } = url; - const i = pathname.indexOf('/u/'); - if (i >= 0) { - return pathname.substr(i + 3); - } - } - return null; -} diff --git a/views/contributions/eligible.pug b/views/contributions/eligible.pug index 3cad0a75f..e1dd04859 100644 --- a/views/contributions/eligible.pug +++ b/views/contributions/eligible.pug @@ -6,8 +6,10 @@ extends ../layout block content + - var octicon = viewServices.octicon + .container - h5 ADMINISTRATOR ACCESS ONLY + h5 CONFIDENTIAL - ADMINISTRATOR ACCESS ONLY p Currently eligible corporate users to vote in the contribution system are listed below. p diff --git a/views/contributions/popular.pug b/views/contributions/popular.pug index dacadaad8..2ccd9f7c6 100644 --- a/views/contributions/popular.pug +++ b/views/contributions/popular.pug @@ -6,6 +6,8 @@ extends ../layout block content + - var octicon = viewServices.octicon + .container p Popular repos people contribute to. diff --git a/views/contributions/voting/elections.pug b/views/contributions/voting/elections.pug index 5bff6d1fa..0021a5886 100644 --- a/views/contributions/voting/elections.pug +++ b/views/contributions/voting/elections.pug @@ -5,32 +5,22 @@ extends ../../layout -//- @cspell: ignore microsoftfossfund - block content + - var fileSize = viewServices.fileSize + - var moment = viewServices.moment + - var octicon = viewServices.octicon + + //- var startMonthName = moment(start).format('MMMM') + //- var previousMonthName = moment(start).subtract(1, 'months').format('MMMM') + .container - h2 FOSS Fund Rounds - p. - The FOSS Fund is a way for Microsoft employees who contribute to open source - to support open source projects that they use and love. Public information - about this fund is available to be shared at #[a(href='https://aka.ms/microsoftfossfund') aka.ms/microsoftfossfund]. The - fund is distributed to projects based on the votes of Microsoft employees. + h2 Active Elections if activeElections && activeElections.length - - var election1 = activeElections[0] - h3 Most recent funding round - h4: strong: a(href='/contributions/voting/' + election1.slug)= election1.title - p= election1.description - - h3 Past rounds each election in activeElections - if election.slug == election1.slug - //- nothing - else - //-pre= JSON.stringify(election, undefined, 2) - p - a(href='/contributions/voting/' + election.slug)= election.title - br - = election.description + //-pre= JSON.stringify(election, undefined, 2) + h2: a(href='/contributions/voting/' + election.slug)= election.title + p= election.description else - p No voting opportunities. + p No active voting opportunities. + diff --git a/views/contributions/voting/vote.pug b/views/contributions/voting/vote.pug index 546359c0d..1049fa3cc 100644 --- a/views/contributions/voting/vote.pug +++ b/views/contributions/voting/vote.pug @@ -24,7 +24,9 @@ mixin showNominee(election, nominee, iitemp, stripJsSingleQuote) p: small: em= nominee.justification block content + - var fileSize = viewServices.fileSize - var moment = viewServices.moment + - var octicon = viewServices.octicon - var stripJsSingleQuote = viewServices.stripJsSingleQuote //- var startMonthName = moment(start).format('MMMM') diff --git a/views/email/fossfund-vote.pug b/views/email/fossfund-vote.pug index 94f43ceaf..25b0f8987 100644 --- a/views/email/fossfund-vote.pug +++ b/views/email/fossfund-vote.pug @@ -48,16 +48,16 @@ block content p= election.description if userSettings && userSettings.contributionShareOptIn === true - //-h2 Featuring you: the opensource.microsoft.com + //-h2 Launching soon, featuring you: the new opensource.microsoft.com //-p Thanks for opting in to public data sharing. Your GitHub avatar and/or public contributions on GitHub may be featured. We will let you know when the new site launches. //-p: a(href='https://aka.ms/opensource/publicdatasharing') More info at aka.ms/opensource/publicdatasharing else if userSettings && userSettings.contributionShareOptIn === false - //-h2 opensource.microsoft.com site features many of your coworkers + //-h2 The new opensource.microsoft.com site launches this month featuring many of your coworkers //-p You have opted out of participating in the new site at this time. If you change your mind... //-p: a(href='https://aka.ms/opensource/publicdatasharing') More info and ability to opt-in at aka.ms/opensource/publicdatasharing else - h2 Want to be featured on the opensource.microsoft.com site? - p The site features Microsoft employees who contribute to open source, whether part of their job, a hobby, or just something they do. + h2 Want to be featured on the new opensource.microsoft.com site? + p Launched earlier this year, the new site features Microsoft employees who contribute to open source, whether part of their job, a hobby, or just something they do. p If you'd like to have your GitHub avatar appear on the homepage at times, and your contributions to other projects highlighted when they're made as part of the new "ecosystem" page, you can opt-in to sharing that already-public info. p: a(href='https://aka.ms/opensource/publicdatasharing') More info and ability to opt-in at aka.ms/opensource/publicdatasharing @@ -79,20 +79,19 @@ block content p We are trying to drive a change across Microsoft. We'd like to see more Microsofties contributing to open source communities, whether as part of your role, a Day of Learning project, updating project dependencies, hobbies, or pursuing off-hours projects and interests. h2 About the FOSS Fund - p Microsoft's FOSS Fund gives up to $10,000 to the most-voted-for open source software projects. Projects are nominated and selected by those at Microsoft who contribute to communities that are not primarily Microsoft communities. + p Microsoft's FOSS Fund gives $10,000 to the most-voted-for open source software project. Projects are nominated and selected by those at Microsoft who contribute to communities that are not primarily Microsoft communities. p Public information about the fund can be found at #[a(href='https://aka.ms/microsoftfossfund') https://aka.ms/microsoftfossfund], including previous fund winners. h3 Nominated projects p Projects must: ul - li Be used by Microsoft (used in Microsoft products and services) - li Have an #[a(href='https://opensource.org/licenses', target='_new') OSI-approved license] such as MIT, Apache 2.0, GPL, etc. + li Be used by Microsoft + li Have an OSI-approved license such as MIT, Apache 2.0, GPL, etc. li Must have a mechanism for receiving funds (the GitHub Sponsors team may be able to help) li Cannot be a Microsoft employee-led project - li Have a public-facing details of #[a(href='https://aka.ms/fossfundform/#funding', target='_new') who and how project sponsorship is distributed] h3 How to nominate a project for the next fund - p Nominate at any time using this #[a(href='https://aka.ms/fossfundform') form]. + p New FOSS Fund rounds are announced monthly via the #[a(href='https://idwebelements/GroupManagement.aspx?Group=osblast&Operation=join') osblast] discussion list. h3 Selection eligibility p Eligibility requirements: diff --git a/views/includes/corporateRepoMetadata.pug b/views/includes/corporateRepoMetadata.pug index 1b9db91d6..1ecb0cbf3 100644 --- a/views/includes/corporateRepoMetadata.pug +++ b/views/includes/corporateRepoMetadata.pug @@ -7,6 +7,7 @@ //- Optional inputs: createdUserLink //- Services +- var octicon = viewServices ? viewServices.octicon : null - var moment = viewServices ? viewServices.moment : null //- isBootstrap is currently being used to differentiate this include for whether it is diff --git a/views/message.pug b/views/message.pug index d04cb6a70..10feac70c 100644 --- a/views/message.pug +++ b/views/message.pug @@ -6,9 +6,6 @@ extends layout block content - if clearLocalStorage - script. - localStorage.clear(); div.container#top(style='margin-top:60px') div.container#content div.row diff --git a/views/nav.pug b/views/nav.pug index 7e7c068e2..97ce212a6 100644 --- a/views/nav.pug +++ b/views/nav.pug @@ -51,14 +51,14 @@ mixin userAzure div.navbar.navbar-default.second-row-nav div.container div.navbar-header - button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='.nav-collapse') - button.navbar-toggle(type='button', data-toggle='collapse', data-target='.nav-collapse') + //-button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='.nav-collapse') + //-button.navbar-toggle(type='button', data-toggle='collapse', data-target='.nav-collapse') span.sr-only Toggle navigation span.icon-bar span.icon-bar span.icon-bar - a.navbar-brand(href='./')= page.folderMetadata.title - nav.collapse.navbar-collapse.nav-collapse(role='navigation') + //- a.navbar-brand(href='./')= page.folderMetadata.title + //nav.collapse.navbar-collapse.nav-collapse(role='navigation') nav(role='navigation') div.container(style='margin-top:24px;margin-bottom:12px') div.row(style=(user && !error && ossLink) ? 'margin-left:0' : 'margin-left:-30px') diff --git a/views/org/pending.pug b/views/org/pending.pug index 348bbcaa9..0e29de88a 100644 --- a/views/org/pending.pug +++ b/views/org/pending.pug @@ -78,7 +78,20 @@ block content div.row div.col-md-8.col-lg-8 h1 Want to join #{organization.name}? - if hasIncreasedScope && supportsExpressJoinExperience + if organization && organization.pilot_program && organization.pilot_program === 'pilot' + //- Pilot program + //- Due to SAML, auto-invite and accept does not work + p.lead 1ES Engineering Pilot + ul + li An invitation will be sent to your GitHub account. + li You accept the invitation in on GitHub.com. Due to SAML (single Microsoft sign-on), you may need to authenticate again with Microsoft AAD. + li You come back to this site and continue onboarding. + p   + form(method='post') + p + input.btn.btn-primary.btn-lg(type='submit', value='Join ' + organization.name) + + else if hasIncreasedScope && supportsExpressJoinExperience form(method='post') p(style='margin-top:24px') input.btn.btn-primary.btn-huge(type='submit', value='Join ' + organization.name) diff --git a/views/org/team/index.pug b/views/org/team/index.pug index 503250909..f807d7042 100644 --- a/views/org/team/index.pug +++ b/views/org/team/index.pug @@ -87,6 +87,13 @@ mixin membersList(typeOfList, membersList, isAdmin, moreMembersToShow) p.lead.text-primary.text-center: small … and others block content + + //- Services + - var languageColor = viewServices.languageColor + - var octicon = viewServices.octicon + - var fileSize = viewServices.fileSize + - var moment = viewServices.moment + //- Variables - var maximumMembersToShow = (4 * 3) - 1 - var maximumRepositoriesToShow = 5 @@ -94,7 +101,6 @@ block content //- View services - var languageColor = viewServices.languageColor - var octicon = viewServices.octicon - - var moment = viewServices.moment //- Mode variables - var admin = teamPermissions.allowAdministration @@ -337,12 +343,9 @@ block content .repo(id=repo.name, style='padding-bottom:36px;display:block') h3 a(href='/' + localOrgName + '/repos/' + repo.name)= repo.name - if repo.visibility - |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} - if repo.has_pages + if repo.private === true |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages + .label.label-warning.shrink66(title='This is a private repository and not open source.') Private if repoPermissions && specificTeam = ' ' if repoPermissions.admin @@ -358,7 +361,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('dot-fill', 10) + != octicon('primitive-dot', 10) = ' ' + repo.language if repo.stargazers_count li diff --git a/views/organization/whois/result.pug b/views/organization/whois/result.pug index 4a044bab3..adde2067f 100644 --- a/views/organization/whois/result.pug +++ b/views/organization/whois/result.pug @@ -173,12 +173,6 @@ block content p.lead DANGER ZONE - NO CONFIRMATION p input.btn.btn-danger(type='submit', value='Remove link', name='remove-link-only') - if query && query.collaboratorRepositories && query.collaboratorRepositories.length - p - input.btn.btn-danger(type='submit', value='Remove collaborator grants', name='remove-collaboration') - if query && query.collaboratorRepositories && query.collaboratorRepositories.length > 100 - p - input.btn.btn-danger(type='submit', value='Remove 100 collaborator grants', name='remove-collaboration-100') if query && query.collaboratorRepositories && query.collaboratorRepositories.length h2 Active individual Collaborator permissions on repos diff --git a/views/people/index.pug b/views/people/index.pug index edaf41e3d..5266558b8 100644 --- a/views/people/index.pug +++ b/views/people/index.pug @@ -51,7 +51,7 @@ block content //-ul.nav.nav-pills li(class=(search.sort === 'Alphabet' ? 'active' : ''), title='Alphabetically sorted') a(href='?sort=Alphabet&tag=' + (tag ? tag : '') + (query.phrase ? '&q=' + query.phrase : '')) - != octicon('typography', 20) + != octicon('text-size', 20) | Name form.form-horizontal#entitySearch(style='margin-top:24px') diff --git a/views/repos/defaultBranch.pug b/views/repos/defaultBranch.pug new file mode 100644 index 000000000..f05e585db --- /dev/null +++ b/views/repos/defaultBranch.pug @@ -0,0 +1,88 @@ +//- +//- Copyright (c) Microsoft. +//- Licensed under the MIT license. See LICENSE file in the project root for full license information. +//- + +extends ../layout + +block content + + //- Services + - var languageColor = viewServices.languageColor + - var octicon = viewServices.octicon + - var fileSize = viewServices.fileSize + + //- Variables + - var githubUrl = 'https://github.com/' + repo.full_name + - var cloneUrl = repo.clone_url + - var sshUrl = repo.ssh_url + - var admin = repoPermissions && repoPermissions.allowAdministration + + .container + .row: .col-md-12 + if fromReposPage + .nav + ul.pager.zero-pad-bottom + li.previous + a(href='javascript:window.history.back()') + span(aria-hidden=true) ← + = ' Back' + - var hugeHeading = repo.name.length < 33 + h1(class={huge: hugeHeading}) + a(href='https://github.com/' + repo.full_name, target="_blank")= repo.name + if repo.private === true + |   + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) Private + h6= repo.full_name.replace('/' + repo.name, '') + ' organization' + if repo.description + p.lead=repo.description + + include ./pills + + if admin + if !organizationSupportsUpdatesApp + h4 Default branch rename #[span.label.label-muted PREVIEW] + ul.list-inline.list-horizontal-space + li + | Current default branch name + br + strong= repo.default_branch + p. + The #{organization.name} is not configured to allow renames at this time. + else + //- repo.default_branch !== 'main' + h4 Default branch rename #[span.label.label-muted PREVIEW] + ul.list-inline.list-horizontal-space + li + | Current default branch name + br + strong= repo.default_branch + p You have administrative rights to this repo and can choose to rename the default branch. + if repo.default_branch == 'main' + p: strong You're already using the default branch "main", no action required. + p. + Easily convert the default branch of this project. Note that there are + many potential side effects, including impacting deep URL links, continuous + integration and deployment systems, and likely this will require cleanup + work. + p. + This automated default branch rename capability: + ul + li Creates a new branch based off of the current default branch's latest commit + li Reassigns any protected branch settings to the new default branch from the former + li Updates any open pull requests against the current default branch for the new branch + li Updates the default branch to the new branch + li Deletes the current default branch + p The automated operation will halt if a major error is detected, but will not revert the changes completely. It will take 20-120 seconds to process. Please anticipate updating this repo to take some time, and resource for this change. This process may timeout if there are a large number of open pull requests. + + form(method='post', action=repository.baseUrl + 'defaultBranch') + p: strong New default branch name + input.form-control(name='targetBranchName', type='text', placeholder='The new default branch name to use', value='main') + br + input.btn.btn-sm( + type='submit', + name='rename-default-branch' + class='btn-danger', + value='Rename default branch', + onclick='return confirm(\'Are you sure that you want to rename the default branch? Additional work may be required to address any errors or configure systems such as webhooks, continuous integration, etc.\');' + title='Select this operation to begin the default branch rename process automatically') diff --git a/views/repos/delete.pug b/views/repos/delete.pug index 57f420726..f8886d855 100644 --- a/views/repos/delete.pug +++ b/views/repos/delete.pug @@ -7,6 +7,11 @@ extends ../layout block content + //- Services + - var languageColor = viewServices.languageColor + - var octicon = viewServices.octicon + - var fileSize = viewServices.fileSize + //- View constants - var maxReaders = 10 diff --git a/views/repos/history.pug b/views/repos/history.pug index d7100cbf6..2c36be2b5 100644 --- a/views/repos/history.pug +++ b/views/repos/history.pug @@ -8,6 +8,9 @@ extends ../layout block content //- Services + - var languageColor = viewServices.languageColor + - var octicon = viewServices.octicon + - var fileSize = viewServices.fileSize - var moment = viewServices.moment //- Variables diff --git a/views/repos/index.pug b/views/repos/index.pug index 2c657276f..8ffce2683 100644 --- a/views/repos/index.pug +++ b/views/repos/index.pug @@ -81,7 +81,7 @@ block content li(class=(search.sort === 'Alphabet' ? 'active' : ''), title='Sort by repo name') a(href='?sort=Alphabet&tag=' + (specificTeamId ? '&teamRepos=' + specificTeamId : '') + (tag ? tag : '') + (query.tt ? '&tt=' + query.tt : '') + (query.phrase ? '&q=' + query.phrase : '')) //- i.glyphicon.glyphicon-sort-by-alphabet - != octicon('typography', 20) + != octicon('text-size', 20) | Name //-i.glyphicon.glyphicon-triangle-bottom li(class=(search.sort === 'Updated' ? 'active' : '')) @@ -225,12 +225,9 @@ block content if showIds = repo.id + ' ' a(href='/' + localOrgName + '/repos/' + repo.name)= repo.name - if repo.visibility + if repo.private === true |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} - if repo.has_pages - |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages + .label.label-warning.shrink66(title='This is a private repository and not open source.') Private if repo.permissions && specificTeam = ' ' if repo.permissions.admin @@ -251,7 +248,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('dot-fill', 10) + != octicon('primitive-dot', 10) = ' ' + repo.language if repo.stargazers_count li diff --git a/views/repos/permissions.pug b/views/repos/permissions.pug index 5168fc4b3..1cbc9e9de 100644 --- a/views/repos/permissions.pug +++ b/views/repos/permissions.pug @@ -66,7 +66,9 @@ mixin teamsList(teams, hideJoinOption) block content //- Services + - var languageColor = viewServices.languageColor - var octicon = viewServices.octicon + - var fileSize = viewServices.fileSize //- View constants - var maxReaders = 10 diff --git a/views/repos/pills.pug b/views/repos/pills.pug index 9f1e89b86..7800be760 100644 --- a/views/repos/pills.pug +++ b/views/repos/pills.pug @@ -6,5 +6,6 @@ .row: .col-md-12(style='margin-bottom: 32px; margin-top: 16px') ul.nav.nav-tabs li(role='presentation', class={active: !reposSubView || reposSubView === 'default'}): a(href=repository.baseUrl) Overview + li(role='presentation', class={active: reposSubView === 'defaultBranch'}): a(href=repository.baseUrl + 'defaultBranch/') Default Branch Name li(role='presentation', class={active: reposSubView === 'permissions'}): a(href=repository.baseUrl + 'permissions/') Permissions li(role='presentation', class={active: reposSubView === 'history'}): a(href=repository.baseUrl + 'history/') History diff --git a/views/repos/repo.pug b/views/repos/repo.pug index fd3d575a7..da2e35ae1 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -13,6 +13,27 @@ mixin simplePersonView(account) div(style='display:block;vertical-align:middle') h4 a(href='/people?q=' + account.login)= shorthandName + //-ul.list-inline + if shorthandName && shorthandName !== account.login + li + span(title=account.login + ' is the GitHub username for ' + shorthandName)= account.login + if corporateIdentity + if link && !corporate + li.text-warning!= octicon('link', 16) + li + span(title=link.aadoid)= link.aadupn + else + li!= octicon('link', 16) + li + span(title=corporateIdentity + ' is the corporate identity for ' + shorthandName)= corporateIdentity + //- just corporate e-mails here, not user emails + if email + li + a(href='mailto:' + email, title='Send corporate email to ' + email) + != octicon('mail', 16) + if serviceAccount + li!= octicon('hubot', 16) + li Service account mixin teamsList(teams, hideJoinOption) if teams && teams.length > 0 @@ -75,12 +96,9 @@ block content - var hugeHeading = repo.name.length < 33 h1(class={huge: hugeHeading}) a(href='https://github.com/' + repo.full_name, target="_blank")= repo.name - if repo.visibility - |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} - if repo.has_pages + if repo.private === true |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) Private h6= repo.full_name.replace('/' + repo.name, '') + ' organization' if repo.fork h6 @@ -105,7 +123,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('dot-fill', 10) + != octicon('primitive-dot', 10) = ' ' + repo.language if repo.license && repo.license.featured && repo.license.name li @@ -167,6 +185,9 @@ block content | Default branch br strong= repo.default_branch + if repo.default_branch === 'master' && admin + span   + a.btn.btn-sm.btn-muted(href=repository.baseUrl + 'defaultBranch') Rename... if organizationSupportsUpdatesApp && repo.default_branch !== 'main' && admin .alert.alert-gray diff --git a/views/teams/index.pug b/views/teams/index.pug index c1c3b23f5..4f9b585a7 100644 --- a/views/teams/index.pug +++ b/views/teams/index.pug @@ -9,6 +9,7 @@ block append js_doc_ready include ../js/search.js block content + - var languageColor = viewServices.languageColor - var octicon = viewServices.octicon .container diff --git a/business/webhooks/organizationProcessor.ts b/webhooks/organizationProcessor.ts similarity index 88% rename from business/webhooks/organizationProcessor.ts rename to webhooks/organizationProcessor.ts index d20905548..a84150a9a 100644 --- a/business/webhooks/organizationProcessor.ts +++ b/webhooks/organizationProcessor.ts @@ -6,21 +6,18 @@ import crypto from 'crypto'; import secureCompare from 'secure-compare'; -import { Organization } from '..'; +import { Operations } from '../business'; +import { Organization } from '../business'; -import { sleep } from '../../lib/utils'; -import { type IProviders } from '../../interfaces'; - -import defaultWebhookTasks from './tasks'; -import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; +import Tasks from './tasks'; +import { sleep } from '../utils'; +import { type IProviders } from '../interfaces'; interface IValidationError extends Error { statusCode?: number; computedHash?: string; } -let companySpecificWebhookTasks: WebhookProcessor[] = null; - export abstract class WebhookProcessor { abstract filter(data: any): boolean; abstract run(providers: IProviders, organization: Organization, data: any): Promise; @@ -53,14 +50,6 @@ export default async function ProcessOrganizationWebhook( if (!providers) { throw new Error('No providers provided'); } - const companySpecific = getCompanySpecificDeployment(); - if ( - companySpecific?.features?.firehose?.getAdditionalWebhookTasks && - companySpecificWebhookTasks === null - ) { - companySpecificWebhookTasks = - await companySpecific.features.firehose.getAdditionalWebhookTasks(providers); - } const organization = options.organization; const event = options.event; if (!organization || !organization.name) { @@ -121,8 +110,7 @@ export default async function ProcessOrganizationWebhook( options.acknowledgeValidEvent(); } let interestingEvents = 0; - const availableTasks = [...defaultWebhookTasks, ...(companySpecificWebhookTasks || [])]; - const work = availableTasks.filter((task) => task.filter(event)); + const work = Tasks.filter((task) => task.filter(event)); if (work.length > 0) { ++interestingEvents; console.log(`[* interesting event: ${event.properties.event} (${work.length} interested tasks)]`); diff --git a/business/webhooks/tasks/auditLog.ts b/webhooks/tasks/auditLog.ts similarity index 97% rename from business/webhooks/tasks/auditLog.ts rename to webhooks/tasks/auditLog.ts index 8aff9f335..c8c7d37e1 100644 --- a/business/webhooks/tasks/auditLog.ts +++ b/webhooks/tasks/auditLog.ts @@ -9,10 +9,10 @@ // for organizations, and also to import JSON-based audit export files. import { WebhookProcessor } from '../organizationProcessor'; -import { Organization } from '../..'; +import { Organization } from '../../business'; import { AuditLogRecord } from '../../entities/auditLogRecord/auditLogRecord'; import { MapWebhookEventsToAuditEvents, AuditLogSource } from '../../entities/auditLogRecord'; -import type { IProviders } from '../../../interfaces'; +import type { IProviders } from '../../interfaces'; // prettier-ignore const eventTypes = new Set([ @@ -28,7 +28,6 @@ const knownEventTypesToIgnore = new Set([ 'fork', 'watch', 'star', - 'installation_repositories', ]); async function runAsync(providers: IProviders, organization: Organization, data: any) { diff --git a/business/webhooks/tasks/automaticTeams.ts b/webhooks/tasks/automaticTeams.ts similarity index 95% rename from business/webhooks/tasks/automaticTeams.ts rename to webhooks/tasks/automaticTeams.ts index 76df95476..0f93e3416 100644 --- a/business/webhooks/tasks/automaticTeams.ts +++ b/webhooks/tasks/automaticTeams.ts @@ -7,13 +7,13 @@ const teamTypes = ['read', 'write', 'admin']; const defaultLargeAdminTeamSize = 250; import { WebhookProcessor } from '../organizationProcessor'; -import { Operations } from '../..'; -import { Organization } from '../..'; +import { Operations } from '../../business'; +import { Organization } from '../../business'; -import RenderHtmlMail from '../../../lib/emailRender'; -import { IMailProvider } from '../../../lib/mailProvider'; -import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; -import { GitHubRepositoryPermission, IProviders } from '../../../interfaces'; +import RenderHtmlMail from '../../lib/emailRender'; +import { IMailProvider } from '../../lib/mailProvider'; +import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; +import { GitHubRepositoryPermission, IProviders } from '../../interfaces'; interface IAutomaticTeamsMail { to: string; @@ -31,7 +31,7 @@ interface ICustomDataEventName { export default class AutomaticTeamsWebhookProcessor implements WebhookProcessor { processOrgSpecialTeams(organization: Organization) { - const specialTeams = organization.specialSystemTeams; + const specialTeams = organization.specialRepositoryPermissionTeams; const specials = []; const specialTeamIds = new Set(); const specialTeamLevels = new Map(); @@ -362,8 +362,9 @@ async function setTeamPermission( const orgName = organization.name; const repository = organization.repository(repoName, { id: repoId }); if (customizedTeamPermissionsWebhookLogic) { - const shouldSkipEnforcement = - await customizedTeamPermissionsWebhookLogic.shouldSkipEnforcement(repository); + const shouldSkipEnforcement = await customizedTeamPermissionsWebhookLogic.shouldSkipEnforcement( + repository + ); if (shouldSkipEnforcement && necessaryPermission !== GitHubRepositoryPermission.Pull) { console.log( `Customized logic for team permissions: skipping enforcement for repository ${repository.id}` diff --git a/business/webhooks/tasks/index.ts b/webhooks/tasks/index.ts similarity index 100% rename from business/webhooks/tasks/index.ts rename to webhooks/tasks/index.ts diff --git a/business/webhooks/tasks/member.ts b/webhooks/tasks/member.ts similarity index 92% rename from business/webhooks/tasks/member.ts rename to webhooks/tasks/member.ts index f5c49f79b..17941bab8 100644 --- a/business/webhooks/tasks/member.ts +++ b/webhooks/tasks/member.ts @@ -6,9 +6,9 @@ // COLLABORATOR on a repository import { WebhookProcessor } from '../organizationProcessor'; -import { Operations, Organization } from '../..'; -import { IProviders, GitHubCollaboratorType } from '../../../interfaces'; -import { ErrorHelper } from '../../../lib/transitional'; +import { Operations, Organization } from '../../business'; +import { IProviders, GitHubCollaboratorType } from '../../interfaces'; +import { ErrorHelper } from '../../transitional'; export default class MemberWebhookProcessor implements WebhookProcessor { filter(data: any) { @@ -68,7 +68,8 @@ export default class MemberWebhookProcessor implements WebhookProcessor { const repositoryName = event.repository.name; const repository = organization.repository(repositoryName, event.repository); const collaborator = await repository.getCollaborator(event.member.login); - const permission = collaborator.interpretRoleAsDetailedPermission(); + const permission = collaborator.asGitHubRepositoryPermission(); + // TODO: may need to support the new 5 levels vs 3... if (permission) { const isOrganizationMember = await organization.getMembership(userLogin); const collaboratorType = isOrganizationMember diff --git a/business/webhooks/tasks/membership.ts b/webhooks/tasks/membership.ts similarity index 96% rename from business/webhooks/tasks/membership.ts rename to webhooks/tasks/membership.ts index 6a1dca5a2..730bb3645 100644 --- a/business/webhooks/tasks/membership.ts +++ b/webhooks/tasks/membership.ts @@ -4,8 +4,8 @@ // import { WebhookProcessor } from '../organizationProcessor'; -import { Operations, Organization } from '../..'; -import { IProviders, GitHubTeamRole } from '../../../interfaces'; +import { Operations, Organization } from '../../business'; +import { IProviders, GitHubTeamRole } from '../../interfaces'; export default class MembershipWebhookProcessor implements WebhookProcessor { filter(data: any) { diff --git a/business/webhooks/tasks/organization.ts b/webhooks/tasks/organization.ts similarity index 98% rename from business/webhooks/tasks/organization.ts rename to webhooks/tasks/organization.ts index 03b9e2d4d..b2a49039f 100644 --- a/business/webhooks/tasks/organization.ts +++ b/webhooks/tasks/organization.ts @@ -5,13 +5,13 @@ // ORGANIZATION membership and ownership -import { Organization } from '../..'; +import { Organization } from '../../business'; import { OrganizationMembershipRole, type IProviders, NoCacheNoBackground, OrganizationMembershipState, -} from '../../../interfaces'; +} from '../../interfaces'; import { WebhookProcessor } from '../organizationProcessor'; // NOTE: unfortunately role changes from admin->member or member->admin do not fire GitHub hooks diff --git a/business/webhooks/tasks/repository.ts b/webhooks/tasks/repository.ts similarity index 93% rename from business/webhooks/tasks/repository.ts rename to webhooks/tasks/repository.ts index 76a31f571..eda134063 100644 --- a/business/webhooks/tasks/repository.ts +++ b/webhooks/tasks/repository.ts @@ -6,9 +6,9 @@ // REPOSITORY created or updated import { WebhookProcessor } from '../organizationProcessor'; -import { Organization } from '../..'; +import { Organization } from '../../business'; import NewRepositoryLockdownSystem from '../../features/newRepositories/newRepositoryLockdown'; -import { getRepositoryMetadataProvider, RepositoryLockdownState, type IProviders } from '../../../interfaces'; +import { getRepositoryMetadataProvider, RepositoryLockdownState, type IProviders } from '../../interfaces'; export default class RepositoryWebhookProcessor implements WebhookProcessor { filter(data: any) { @@ -17,7 +17,7 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { } async run(providers: IProviders, organization: Organization, data: any): Promise { - const { immutable, insights, operations } = providers; + const { immutable, operations } = providers; const event = data.body; const queryCache = operations.providers.queryCache; let update = false; @@ -26,9 +26,6 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { let transferSourceLogin: string = null; const action = event.action; const organizationId = event.organization.id as number; - const repositoryId = event?.repository?.id as number; - const repositoryIdAsString = String(repositoryId); - const organizationIdAsString = String(organizationId); if (!operations.isOrganizationManagedById(organizationId)) { console.log( `skipping organization ID ${organizationId} which is not directly managed: ${event.organization.login}` @@ -60,6 +57,8 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { } by ${event.sender.login}` ); update = true; + const repositoryIdAsString = event.repository.id.toString(); + const organizationIdAsString = event.organization.id.toString(); try { if ( organizationIdAsString === organization.id.toString() && @@ -89,6 +88,8 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { console.log(`repository event not being intercepted: ${action}`); } if (addOrUpdateRepositoryQueryCache) { + const repositoryIdAsString = event.repository.id.toString(); + const organizationIdAsString = event.organization.id.toString(); try { if ( organizationIdAsString === organization.id.toString() && @@ -131,7 +132,6 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { const repository = organization.repository(event.repository.name, event.repository); const repositoryMetadataProvider = getRepositoryMetadataProvider(organization.operations); const lockdownSystem = new NewRepositoryLockdownSystem({ - insights, operations, organization, repository, diff --git a/business/webhooks/tasks/team.ts b/webhooks/tasks/team.ts similarity index 89% rename from business/webhooks/tasks/team.ts rename to webhooks/tasks/team.ts index bdbfd249f..7f9aedcdb 100644 --- a/business/webhooks/tasks/team.ts +++ b/webhooks/tasks/team.ts @@ -5,15 +5,20 @@ // TEAM changes +import moment from 'moment'; + import { WebhookProcessor } from '../organizationProcessor'; -import { Operations } from '../..'; -import { Organization } from '../..'; -import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../../../lib/transitional'; -import type { IProviders } from '../../../interfaces'; +import { Operations } from '../../business'; +import { Organization } from '../../business'; +import { permissionsObjectToValue } from '../../transitional'; +import type { IProviders } from '../../interfaces'; // When teams are added or removed on GitHub, refresh the organization's list of // teams as well as the cross-organization view of the teams. +// TODO: connect to query cache +// TODO: consider whether to slowly kick off Redis cache updates, too + export default class TeamWebhookProcessor implements WebhookProcessor { filter(data: any) { const eventType = data.properties.event; @@ -27,7 +32,7 @@ export default class TeamWebhookProcessor implements WebhookProcessor { let refresh = false; let expectedAfterRefresh = false; const teamId = event.team.id; - const teamIdAsString = String(teamId); + const teamIdAsString = event.team.id.toString(); const organizationIdAsString = event.organization.id.toString(); let addOrUpdate = false; if (event.action === 'created') { @@ -59,12 +64,10 @@ export default class TeamWebhookProcessor implements WebhookProcessor { queryCache && queryCache.supportsTeamPermissions ) { - const oldRepositoryPermissionLevel = projectCollaboratorPermissionsObjectToGitHubRepositoryPermission( + const oldRepositoryPermissionLevel = permissionsObjectToValue( event.changes.repository.permissions.from ); - const newRepositoryPermissionLevel = projectCollaboratorPermissionsObjectToGitHubRepositoryPermission( - event.repository.permissions - ); + const newRepositoryPermissionLevel = permissionsObjectToValue(event.repository.permissions); console.log( `team ${event.team.name} permission level for repo ${event.repository.name} changed from ${oldRepositoryPermissionLevel} to ${newRepositoryPermissionLevel}` ); @@ -97,7 +100,7 @@ export default class TeamWebhookProcessor implements WebhookProcessor { isPrivate, repoName, event.team.id.toString(), - projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(event.repository.permissions) + permissionsObjectToValue(event.repository.permissions) ); // equiv to event.team.permission as GitHubRepositoryPermission } } @@ -128,6 +131,7 @@ export default class TeamWebhookProcessor implements WebhookProcessor { } if (refresh) { + const startingRefresh = moment(); // organization.getTeams(immediateRefreshOptions, () => { // console.log('refreshing teams list after add or remove operations'); // const now = moment(); From 3ef369389897b9036861cd1b825101abbebe3337 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:09:50 -0400 Subject: [PATCH 180/209] Update staging_nihdevgithubportal.yml --- .github/workflows/staging_nihdevgithubportal.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index ac3ea27d1..67408efbf 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -14,12 +14,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Node.js version - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: "16.x" + node-version: "20.x" - name: npm install, build, and test run: | @@ -42,7 +42,7 @@ jobs: ls -lah - name: Upload artifact for deployment job - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: node-app path: /home/runner/work/github-portal/output.tar.gz @@ -56,7 +56,7 @@ jobs: steps: - name: Download artifact from build job - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: node-app @@ -67,7 +67,7 @@ jobs: - name: "Deploy to Azure Web App" id: deploy-to-webapp - uses: azure/webapps-deploy@v2 + uses: azure/webapps-deploy@v3 with: app-name: "nihdevgithubportal" slot-name: "Production" From 871ecbbb88c0b19e01ff80c7c520673e18c31d3e Mon Sep 17 00:00:00 2001 From: Taher Furniturewala Date: Wed, 31 Jul 2024 19:40:16 -0500 Subject: [PATCH 181/209] Applied the diff.patch created from staging to main --- .../.markdownlint-cli2.jsonc | 3 +- .cspell.json | 71 +- .editorconfig | 1 + .eslintrc.js | 7 +- .github/workflows/ci.yml | 4 +- .github/workflows/codeql-analysis.yml | 8 +- .github/workflows/container.yml | 4 +- .github/workflows/stale.yml | 2 +- .gitignore | 2 + .prettierrc.json | 1 + .secrets.env.example | 1 - .vscode/launch.json | 152 +- Dockerfile | 67 +- api/client/banner.ts | 8 +- api/client/context/administration/app.ts | 74 + .../context/administration/appInstallation.ts | 59 + api/client/context/administration/apps.ts | 128 + api/client/context/administration/index.ts | 25 +- .../administration/organization/index.ts | 9 +- .../administration/organization/settings.ts | 123 +- api/client/context/administration/types.ts | 44 + api/client/context/approvals.ts | 16 +- api/client/context/index.ts | 23 +- api/client/context/organization/index.ts | 54 +- api/client/context/organization/repo.ts | 8 +- .../context/organization/repoForkUnlock.ts | 22 +- api/client/context/organization/repos.ts | 21 +- api/client/context/organization/team.ts | 88 +- api/client/context/organization/teams.ts | 7 +- api/client/context/orgs.ts | 4 +- api/client/context/repos.ts | 7 +- api/client/context/sample.ts | 10 +- api/client/context/settings.ts | 48 + api/client/context/teams.ts | 7 +- api/client/index.ts | 20 +- api/client/linking.ts | 14 +- api/client/newOrgRepo.ts | 43 +- api/client/newRepo.ts | 6 +- api/client/news.ts | 8 +- api/client/organization/annotations.ts | 70 +- api/client/organization/index.ts | 34 +- api/client/organization/newRepoMetadata.ts | 8 +- api/client/organization/people.ts | 8 +- api/client/organization/repo.ts | 140 +- api/client/organization/repoPermissions.ts | 6 +- api/client/organization/repos.ts | 29 +- api/client/organization/team.ts | 33 +- api/client/organization/teams.ts | 16 +- api/client/organizations.ts | 161 +- api/client/people.ts | 24 +- api/client/peopleSearch.ts | 2 +- api/client/person.ts | 16 +- api/client/repos.ts | 8 +- api/client/session.ts | 6 +- api/client/teams.ts | 8 +- api/client/users.ts | 35 + api/createRepo.ts | 20 +- api/extension.ts | 30 +- api/index.ts | 24 +- api/jsonErrorHandler.ts | 5 +- api/people/index.ts | 2 +- api/people/link.ts | 6 +- api/people/links.ts | 67 +- api/people/unlink.ts | 12 +- api/webhook.ts | 8 +- app.ts | 156 - bin/www.ts | 6 +- business/account.ts | 48 +- business/application.ts | 42 +- business/collaborator.ts | 26 +- business/domains.ts | 27 +- business/enterprise.ts | 194 + .../auditLogRecord/auditLogRecord.ts | 16 +- .../auditLogRecord/auditLogRecordProvider.ts | 2 +- .../entities}/auditLogRecord/index.ts | 0 .../entities}/auditLogRecord/type.ts | 2 +- .../entities}/localExtensionKey/index.ts | 2 +- .../localExtensionKey/localExtensionKey.ts | 12 +- .../localExtensionKeyProvider.ts | 4 +- .../entities}/organizationAnnotation.ts | 24 +- .../organizationMemberCache/index.ts | 0 .../organizationMemberCache.ts | 20 +- .../organizationMemberCacheProvider.ts | 2 +- .../entities}/organizationSettings/index.ts | 0 .../organizationSetting.ts | 54 +- .../organizationSettingProvider.ts | 2 +- .../entities}/organizationSettings/type.ts | 2 +- {entities => business/entities}/repository.ts | 27 +- .../entities}/repositoryCache/index.ts | 0 .../repositoryCache/repositoryCache.ts | 18 +- .../repositoryCacheProvider.ts | 2 +- .../repositoryCollaboratorCache/index.ts | 0 .../repositoryCollaboratorCache.ts | 18 +- .../repositoryCollaboratorCacheProvider.ts | 2 +- .../entities}/repositoryMetadata/index.ts | 0 .../repositoryMetadata/repositoryMetadata.ts | 16 +- .../repositoryMetadataProvider.ts | 2 +- .../entities}/repositoryMetadata/type.ts | 2 +- .../entities}/repositoryTeamCache/index.ts | 0 .../repositoryTeamCache.ts | 18 +- .../repositoryTeamCacheProvider.ts | 2 +- .../entities}/teamCache/index.ts | 2 +- .../entities}/teamCache/teamCache.ts | 16 +- .../entities}/teamCache/teamCacheProvider.ts | 2 +- .../teamJoinApproval/approvalProvider.ts | 2 +- .../entities}/teamJoinApproval/index.ts | 7 +- .../teamJoinApproval/teamJoinApproval.ts | 16 +- .../teamJoinApprovalProvider.ts | 2 +- .../entities}/teamMemberCache/index.ts | 7 +- .../teamMemberCache/teamMemberCache.ts | 18 +- .../teamMemberCacheProvider.ts | 2 +- .../entities}/token/index.ts | 2 +- .../entities}/token/token.ts | 32 +- .../entities}/token/tokenGenerator.ts | 0 .../entities}/token/tokenProvider.ts | 4 +- {entities => business/entities}/token/type.ts | 2 +- .../entities}/userSettings.ts | 13 +- {features => business/features}/index.ts | 0 .../newRepositories/actions/createReadme.ts | 4 +- .../newRepositories/actions/deleteFork.ts | 2 +- .../actions/downgradeCollaborator.ts | 4 +- .../actions/dropCollaborator.ts | 2 +- .../newRepositories/actions/dropTeam.ts | 2 +- .../newRepositories/actions/index.ts | 0 .../newRepositories/actions/lockdown.ts | 12 +- .../features}/newRepositories/approve.ts | 6 +- .../newRepositories/initializeMetadata.ts | 21 +- .../features}/newRepositories/interfaces.ts | 12 +- .../features}/newRepositories/lockdownMail.ts | 8 +- .../newRepositories/newRepositoryLockdown.ts | 68 +- .../newRepositories/selfServiceDelete.ts | 6 +- .../newRepositories/staticFunctions.ts | 4 +- .../features}/newRepositories/strings.ts | 0 .../validateSelfServiceDelete.ts | 8 +- .../validateSelfServiceSetup.ts | 4 +- .../features}/publicReposFastFilter.ts | 4 +- {features => business/features}/sudo/index.ts | 11 +- {features => business/features}/sudo/noop.ts | 9 +- .../features}/sudo/portal.ts | 8 +- .../features}/sudo/securityGroup.ts | 6 +- {features => business/features}/sudo/sudo.md | 9 +- {features => business/features}/sudo/teams.ts | 6 +- .../teamMemberToMaintainerUpgrade.ts | 14 +- business/githubApps/index.ts | 151 - business/graphManager.ts | 2 +- business/operations/administration.ts | 2 +- business/operations/core.ts | 99 +- business/operations/index.ts | 328 +- business/operations/link.ts | 2 +- business/operations/unlinkMail.ts | 4 +- business/organization.ts | 301 +- business/organizationCopilot.ts | 126 + business/organizationProperties.ts | 198 + business/project.ts | 27 +- business/projectView.ts | 27 +- business/projects.ts | 27 +- business/queryCache.ts | 36 +- business/repoSearch.ts | 6 +- business/repository.ts | 243 +- business/repositoryActions.ts | 21 +- business/repositoryInvitation.ts | 77 + business/repositoryIssue.ts | 21 +- business/repositoryPermission.ts | 83 +- business/repositoryProject.ts | 22 +- business/repositoryProjectCard.ts | 19 +- business/repositoryProjectColumn.ts | 16 +- business/repositoryProperties.ts | 77 + business/repositoryPullRequest.ts | 21 +- business/team.ts | 42 +- business/teamMember.ts | 8 +- business/teamPermission.ts | 70 +- business/teamRepositoryPermission.ts | 47 +- business/user/aggregate.ts | 8 +- business/user/index.ts | 4 +- .../webhooks}/organizationProcessor.ts | 24 +- .../webhooks}/tasks/auditLog.ts | 5 +- .../webhooks}/tasks/automaticTeams.ts | 19 +- .../webhooks}/tasks/index.ts | 0 .../webhooks}/tasks/member.ts | 9 +- .../webhooks}/tasks/membership.ts | 4 +- .../webhooks}/tasks/organization.ts | 4 +- .../webhooks}/tasks/repository.ts | 14 +- {webhooks => business/webhooks}/tasks/team.ts | 24 +- config/brand.types.ts | 1 - config/continuousDeployment.types.ts | 3 + config/debug.json | 4 +- config/debug.types.ts | 2 + config/github.operations.json | 1 - config/github.organizations.types.ts | 1 + config/npm.publishing.json | 6 - config/npm.publishing.types.ts | 17 - config/npm.types.ts | 4 +- config/webServer.json | 13 +- config/webServer.types.ts | 11 + pg.sql => data/pg.sql | 0 default-assets-package/package-lock.json | 1144 +- default-assets-package/package.json | 2 +- docker-compose.yml | 2 +- docs/api.md | 10 +- docs/configuration.md | 8 +- docs/jobs.md | 20 - docs/scripts.md | 5 - docs/service-dependencies.md | 26 + features/graphTeamSync.ts | 31 - index.ts | 97 + interfaces/app.ts | 51 +- interfaces/companySpecific/administration.ts | 2 +- interfaces/companySpecific/events/index.ts | 12 + interfaces/companySpecific/events/linking.ts | 11 + .../features/augmentApiMetadata.ts | 17 +- .../companySpecific/features/firehose.ts | 5 +- interfaces/companySpecific/features/index.ts | 18 +- .../features/organizationSudo.ts | 2 +- .../companySpecific/features/portalSudo.ts | 2 +- interfaces/companySpecific/index.ts | 1 + interfaces/companySpecific/middleware.ts | 10 +- interfaces/companySpecific/passport.ts | 2 +- .../companySpecific/routes/api/index.ts | 1 + interfaces/companySpecific/routes/index.ts | 2 +- interfaces/github/account.ts | 1 + interfaces/github/collaborators.ts | 5 +- interfaces/github/operations.ts | 35 +- interfaces/github/orgs.ts | 25 +- interfaces/github/repos.ts | 162 +- interfaces/github/rest.ts | 23 +- interfaces/github/teams.ts | 23 + interfaces/index.ts | 17 +- interfaces/middleware.ts | 11 + interfaces/providers.ts | 34 +- interfaces/queryCache.ts | 10 +- interfaces/web.ts | 8 +- job.ts | 182 + .../task.ts => cleanupBlobCache.ts} | 11 +- jobs/cleanupBlobCache/index.ts | 9 - .../task.ts => cleanupInvites.ts} | 45 +- jobs/cleanupInvites/index.ts | 13 - jobs/cleanupKeys/index.ts | 9 - jobs/cleanupKeys/task.ts | 98 - jobs/cleanupTeamRequests.ts | 65 + jobs/cleanupTokens/index.ts | 9 - jobs/cleanupTokens/task.ts | 142 - ...itories.ts => deletedRepositoriesCache.ts} | 25 +- jobs/{firehose/task.ts => firehose.ts} | 54 +- jobs/firehose/index.ts | 13 - jobs/permissions.ts | 214 + jobs/permissions/index.ts | 14 - jobs/permissions/task.ts | 155 - .../task.ts => refreshQueryCache.ts} | 30 +- jobs/refreshQueryCache/index.ts | 15 - .../index.ts => refreshUsernames.ts} | 81 +- jobs/repositories.ts | 339 +- lib/caching/blob.ts | 2 +- lib/caching/cosmosdb.ts | 6 +- lib/caching/redis.ts | 4 +- lib/campaigns.ts | 7 +- lib/config/painlessConfigAsCode.ts | 13 +- lib/cosmosSession/index.ts | 2 +- .../entityMetadataProvider.ts | 6 +- lib/entityMetadataProvider/postgres.ts | 66 +- lib/entityMetadataProvider/query.ts | 2 +- lib/entityMetadataProvider/table.ts | 2 +- lib/github/appPurposes.ts | 277 + .../githubApps => lib/github}/appTokens.ts | 59 +- lib/github/collections.ts | 295 +- lib/github/composite.ts | 36 +- lib/github/core.ts | 107 +- lib/github/crossOrganization.ts | 32 +- lib/github/index.ts | 107 +- lib/github/restApi.ts | 84 +- .../githubApps => lib/github}/tokenManager.ts | 210 +- lib/graphProvider/microsoftGraphProvider.ts | 190 +- lib/linkProviders/table/tableLinkProvider.ts | 2 +- lib/mailProvider/index.ts | 43 + lib/pugViewServices.ts | 2 +- transitional.ts => lib/transitional.ts | 107 +- utils.ts => lib/utils.ts | 36 +- middleware/alternateApps.ts | 6 +- middleware/apiAad.ts | 46 +- middleware/apiReposAuth.ts | 7 +- middleware/apiVstsAuth.ts | 7 +- middleware/appInsights.ts | 26 +- middleware/business/administration.ts | 13 +- middleware/business/allLinks.ts | 8 +- middleware/business/authentication.ts | 28 +- .../business/corporateAdministrators.ts | 18 +- middleware/business/corporateAlias.ts | 2 +- middleware/business/corporateHierarchy.ts | 2 +- middleware/business/corporateMail.ts | 25 +- middleware/business/employeesOnly.ts | 8 +- .../{links/index.ts => business/links.ts} | 16 +- middleware/business/organization.ts | 45 +- middleware/business/repository.ts | 34 + middleware/business/setContext.ts | 8 +- middleware/business/userSettings.ts | 41 + middleware/campaign.ts | 6 +- middleware/codespaces.ts | 4 +- middleware/companySpecificDeployment.ts | 6 +- middleware/corporateViews.ts | 2 +- middleware/correlationId.ts | 7 +- middleware/errorHandler.ts | 36 +- .../{error-routes.ts => errorRoutes.ts} | 15 +- .../github/blockEnterpriseManagedUsers.ts | 10 +- .../github/ensureOrganizationProfile.ts | 57 + middleware/github/orgPermissions.ts | 10 +- middleware/github/repoPermissions.ts | 51 +- middleware/github/requireActiveSession.ts | 7 +- middleware/github/systemWidePermissions.ts | 8 +- middleware/github/teamPermissions.ts | 14 +- middleware/healthCheck.ts | 25 +- middleware/index.ts | 22 +- middleware/initialize.ts | 236 +- middleware/jsonError.ts | 11 +- middleware/keyVault.ts | 2 +- middleware/locals.ts | 7 +- middleware/logger.ts | 2 +- middleware/lowercaser.ts | 6 +- middleware/officeHyperlinks.ts | 5 +- middleware/onboarding.ts | 4 +- middleware/passport-routes.ts | 9 +- middleware/passport/aadRoutes.ts | 12 +- middleware/passport/aadStrategy.ts | 83 +- middleware/passport/encryptionSerializer.ts | 2 +- middleware/passport/githubRoutes.ts | 13 +- middleware/passport/githubStrategy.ts | 27 +- .../{passport-config.ts => passportConfig.ts} | 4 +- middleware/rawBodyParser.ts | 5 +- middleware/react.ts | 44 +- middleware/scrubbedUrl.ts | 7 +- middleware/sslify.ts | 1 + middleware/staticClientApp.ts | 5 +- middleware/staticClientApp2.ts | 9 +- middleware/staticSiteAssets.ts | 2 +- middleware/supportMultipleAuthProviders.ts | 6 +- .../index.ts => middleware/types.ts | 9 +- package-lock.json | 17896 +++++++--------- package.json | 139 +- routes/administration/app.ts | 54 +- routes/administration/apps.ts | 57 +- routes/administration/index.ts | 8 +- routes/approvals.ts | 2 +- routes/diagnostics.ts | 14 +- routes/explore.ts | 4 +- routes/index-authenticated.ts | 56 +- routes/index-linked.ts | 10 +- routes/index.ts | 4 +- routes/link-cleanup.ts | 6 +- routes/link.ts | 18 +- routes/org/2fa.ts | 6 +- routes/org/index.ts | 21 +- routes/org/join.ts | 9 +- routes/org/leave.ts | 10 +- routes/org/membership.ts | 8 +- routes/org/newRepoSpa.ts | 6 +- routes/org/people.ts | 4 +- routes/org/profileReview.ts | 6 +- routes/org/repoAdministrativeLock.ts | 19 +- routes/org/repoWorkflowEngine.ts | 18 +- routes/org/repos.ts | 249 +- routes/org/team/approval/index.ts | 6 +- routes/org/team/approvals.ts | 14 +- routes/org/team/delete.ts | 4 +- routes/org/team/index-maintainer.ts | 6 +- routes/org/team/index.ts | 123 +- routes/org/team/leave.ts | 4 +- routes/org/team/maintainers.ts | 12 +- routes/org/team/members.ts | 16 +- routes/org/team/properties.ts | 90 +- routes/org/team/teamAdminRequired.ts | 4 +- routes/org/teams.ts | 10 +- routes/orgAdmin.ts | 62 +- routes/orgs.ts | 12 +- routes/people.ts | 8 +- routes/peopleSearch.ts | 6 +- routes/placeholders.ts | 4 +- routes/releasesSpa.ts | 2 +- routes/repos.ts | 4 +- routes/reposPager.ts | 6 +- routes/settings/approvals.ts | 16 +- routes/settings/authorizations.ts | 8 +- routes/settings/campaigns.ts | 12 +- routes/settings/contributionData.ts | 44 +- routes/settings/index.ts | 2 +- routes/settings/personalAccessTokens.ts | 16 +- routes/teams.ts | 4 +- routes/teamsPager.ts | 2 +- routes/thanks.ts | 2 +- routes/undo.ts | 16 +- routes/unlink.ts | 12 +- scripts/configuration.ts | 28 +- scripts/localEnvironment.ts | 24 +- .../{migrateLinks/task.ts => migrateLinks.ts} | 24 +- scripts/postgres/setup.ts | 2 +- jest.config.ts => test/jest.config.ts | 5 + tsconfig.json | 11 +- views/contributions/eligible.pug | 4 +- views/contributions/popular.pug | 2 - views/contributions/voting/elections.pug | 36 +- views/contributions/voting/vote.pug | 2 - views/email/fossfund-vote.pug | 17 +- views/includes/corporateRepoMetadata.pug | 1 - views/message.pug | 3 + views/nav.pug | 8 +- views/org/pending.pug | 15 +- views/org/team/index.pug | 17 +- views/organization/whois/result.pug | 6 + views/people/index.pug | 2 +- views/repos/defaultBranch.pug | 88 - views/repos/delete.pug | 5 - views/repos/history.pug | 3 - views/repos/index.pug | 11 +- views/repos/permissions.pug | 2 - views/repos/pills.pug | 1 - views/repos/repo.pug | 33 +- views/teams/index.pug | 1 - 414 files changed, 15256 insertions(+), 15795 deletions(-) rename .markdownlint-cli2.jsonc => .config/.markdownlint-cli2.jsonc (59%) create mode 100644 api/client/context/administration/app.ts create mode 100644 api/client/context/administration/appInstallation.ts create mode 100644 api/client/context/administration/apps.ts create mode 100644 api/client/context/administration/types.ts create mode 100644 api/client/context/settings.ts create mode 100644 api/client/users.ts delete mode 100644 app.ts create mode 100644 business/enterprise.ts rename {entities => business/entities}/auditLogRecord/auditLogRecord.ts (94%) rename {entities => business/entities}/auditLogRecord/auditLogRecordProvider.ts (98%) rename {entities => business/entities}/auditLogRecord/index.ts (100%) rename {entities => business/entities}/auditLogRecord/type.ts (69%) rename {entities => business/entities}/localExtensionKey/index.ts (91%) rename {entities => business/entities}/localExtensionKey/localExtensionKey.ts (90%) rename {entities => business/entities}/localExtensionKey/localExtensionKeyProvider.ts (94%) rename {entities => business/entities}/organizationAnnotation.ts (90%) rename {entities => business/entities}/organizationMemberCache/index.ts (100%) rename {entities => business/entities}/organizationMemberCache/organizationMemberCache.ts (93%) rename {entities => business/entities}/organizationMemberCache/organizationMemberCacheProvider.ts (98%) rename {entities => business/entities}/organizationSettings/index.ts (100%) rename {entities => business/entities}/organizationSettings/organizationSetting.ts (89%) rename {entities => business/entities}/organizationSettings/organizationSettingProvider.ts (97%) rename {entities => business/entities}/organizationSettings/type.ts (69%) rename {entities => business/entities}/repository.ts (92%) rename {entities => business/entities}/repositoryCache/index.ts (100%) rename {entities => business/entities}/repositoryCache/repositoryCache.ts (91%) rename {entities => business/entities}/repositoryCache/repositoryCacheProvider.ts (98%) rename {entities => business/entities}/repositoryCollaboratorCache/index.ts (100%) rename {entities => business/entities}/repositoryCollaboratorCache/repositoryCollaboratorCache.ts (94%) rename {entities => business/entities}/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts (99%) rename {entities => business/entities}/repositoryMetadata/index.ts (100%) rename {entities => business/entities}/repositoryMetadata/repositoryMetadata.ts (95%) rename {entities => business/entities}/repositoryMetadata/repositoryMetadataProvider.ts (98%) rename {entities => business/entities}/repositoryMetadata/type.ts (68%) rename {entities => business/entities}/repositoryTeamCache/index.ts (100%) rename {entities => business/entities}/repositoryTeamCache/repositoryTeamCache.ts (93%) rename {entities => business/entities}/repositoryTeamCache/repositoryTeamCacheProvider.ts (98%) rename {entities => business/entities}/teamCache/index.ts (97%) rename {entities => business/entities}/teamCache/teamCache.ts (89%) rename {entities => business/entities}/teamCache/teamCacheProvider.ts (98%) rename {entities => business/entities}/teamJoinApproval/approvalProvider.ts (90%) rename {entities => business/entities}/teamJoinApproval/index.ts (63%) rename {entities => business/entities}/teamJoinApproval/teamJoinApproval.ts (96%) rename {entities => business/entities}/teamJoinApproval/teamJoinApprovalProvider.ts (98%) rename {entities => business/entities}/teamMemberCache/index.ts (95%) rename {entities => business/entities}/teamMemberCache/teamMemberCache.ts (91%) rename {entities => business/entities}/teamMemberCache/teamMemberCacheProvider.ts (99%) rename {entities => business/entities}/token/index.ts (90%) rename {entities => business/entities}/token/token.ts (92%) rename {entities => business/entities}/token/tokenGenerator.ts (100%) rename {entities => business/entities}/token/tokenProvider.ts (95%) rename {entities => business/entities}/token/type.ts (68%) rename {entities => business/entities}/userSettings.ts (92%) rename {features => business/features}/index.ts (100%) rename {features => business/features}/newRepositories/actions/createReadme.ts (93%) rename {features => business/features}/newRepositories/actions/deleteFork.ts (93%) rename {features => business/features}/newRepositories/actions/downgradeCollaborator.ts (87%) rename {features => business/features}/newRepositories/actions/dropCollaborator.ts (93%) rename {features => business/features}/newRepositories/actions/dropTeam.ts (93%) rename {features => business/features}/newRepositories/actions/index.ts (100%) rename {features => business/features}/newRepositories/actions/lockdown.ts (84%) rename {features => business/features}/newRepositories/approve.ts (97%) rename {features => business/features}/newRepositories/initializeMetadata.ts (84%) rename {features => business/features}/newRepositories/interfaces.ts (86%) rename {features => business/features}/newRepositories/lockdownMail.ts (97%) rename {features => business/features}/newRepositories/newRepositoryLockdown.ts (85%) rename {features => business/features}/newRepositories/selfServiceDelete.ts (97%) rename {features => business/features}/newRepositories/staticFunctions.ts (90%) rename {features => business/features}/newRepositories/strings.ts (100%) rename {features => business/features}/newRepositories/validateSelfServiceDelete.ts (90%) rename {features => business/features}/newRepositories/validateSelfServiceSetup.ts (94%) rename {features => business/features}/publicReposFastFilter.ts (94%) rename {features => business/features}/sudo/index.ts (90%) rename {features => business/features}/sudo/noop.ts (65%) rename {features => business/features}/sudo/portal.ts (94%) rename {features => business/features}/sudo/securityGroup.ts (93%) rename {features => business/features}/sudo/sudo.md (90%) rename {features => business/features}/sudo/teams.ts (91%) rename {features => business/features}/teamMemberToMaintainerUpgrade.ts (96%) delete mode 100644 business/githubApps/index.ts create mode 100644 business/organizationCopilot.ts create mode 100644 business/organizationProperties.ts create mode 100644 business/repositoryInvitation.ts create mode 100644 business/repositoryProperties.ts rename {webhooks => business/webhooks}/organizationProcessor.ts (88%) rename {webhooks => business/webhooks}/tasks/auditLog.ts (97%) rename {webhooks => business/webhooks}/tasks/automaticTeams.ts (95%) rename {webhooks => business/webhooks}/tasks/index.ts (100%) rename {webhooks => business/webhooks}/tasks/member.ts (92%) rename {webhooks => business/webhooks}/tasks/membership.ts (96%) rename {webhooks => business/webhooks}/tasks/organization.ts (98%) rename {webhooks => business/webhooks}/tasks/repository.ts (93%) rename {webhooks => business/webhooks}/tasks/team.ts (89%) delete mode 100644 config/npm.publishing.json delete mode 100644 config/npm.publishing.types.ts rename pg.sql => data/pg.sql (100%) delete mode 100644 docs/jobs.md delete mode 100644 docs/scripts.md create mode 100644 docs/service-dependencies.md delete mode 100644 features/graphTeamSync.ts create mode 100644 index.ts create mode 100644 interfaces/companySpecific/events/index.ts create mode 100644 interfaces/companySpecific/events/linking.ts create mode 100644 interfaces/middleware.ts create mode 100644 job.ts rename jobs/{cleanupBlobCache/task.ts => cleanupBlobCache.ts} (81%) delete mode 100644 jobs/cleanupBlobCache/index.ts rename jobs/{cleanupInvites/task.ts => cleanupInvites.ts} (71%) delete mode 100644 jobs/cleanupInvites/index.ts delete mode 100644 jobs/cleanupKeys/index.ts delete mode 100644 jobs/cleanupKeys/task.ts create mode 100644 jobs/cleanupTeamRequests.ts delete mode 100644 jobs/cleanupTokens/index.ts delete mode 100644 jobs/cleanupTokens/task.ts rename jobs/{refreshQueryCache/deletedRepositories.ts => deletedRepositoriesCache.ts} (91%) rename jobs/{firehose/task.ts => firehose.ts} (89%) delete mode 100644 jobs/firehose/index.ts create mode 100644 jobs/permissions.ts delete mode 100644 jobs/permissions/index.ts delete mode 100644 jobs/permissions/task.ts rename jobs/{refreshQueryCache/task.ts => refreshQueryCache.ts} (97%) delete mode 100644 jobs/refreshQueryCache/index.ts rename jobs/{refreshUsernames/index.ts => refreshUsernames.ts} (67%) create mode 100644 lib/github/appPurposes.ts rename {business/githubApps => lib/github}/appTokens.ts (76%) rename {business/githubApps => lib/github}/tokenManager.ts (65%) rename transitional.ts => lib/transitional.ts (75%) rename utils.ts => lib/utils.ts (90%) rename middleware/{links/index.ts => business/links.ts} (90%) create mode 100644 middleware/business/repository.ts create mode 100644 middleware/business/userSettings.ts rename middleware/{error-routes.ts => errorRoutes.ts} (74%) create mode 100644 middleware/github/ensureOrganizationProfile.ts rename middleware/{passport-config.ts => passportConfig.ts} (96%) rename scripts/migrateLinks/index.ts => middleware/types.ts (50%) rename scripts/{migrateLinks/task.ts => migrateLinks.ts} (84%) rename jest.config.ts => test/jest.config.ts (66%) delete mode 100644 views/repos/defaultBranch.pug diff --git a/.markdownlint-cli2.jsonc b/.config/.markdownlint-cli2.jsonc similarity index 59% rename from .markdownlint-cli2.jsonc rename to .config/.markdownlint-cli2.jsonc index 7c3b70235..92bfbc2e7 100644 --- a/.markdownlint-cli2.jsonc +++ b/.config/.markdownlint-cli2.jsonc @@ -5,7 +5,8 @@ "MD024": { "allow_different_nesting": true }, - "MD026": false + "MD026": false, + "MD033": false // no inline HTML: we use inline HTML for expandable details sections }, "ignores": ["**/node_modules/**"] } diff --git a/.cspell.json b/.cspell.json index 22e5b16fe..83a11efe1 100644 --- a/.cspell.json +++ b/.cspell.json @@ -5,6 +5,7 @@ ".git/", ".environment/**", "**/jitStaticConfiguration.json", + "**/*Accounts.json", "**/sentiment/**", "**/thirdparty/**", "**/vendor/**", @@ -13,22 +14,26 @@ "default-assets-package/resources/repos-css/oss.css", "**/commonKnownExternalCollaborators.json", "jobs/reports/exemptRepositories.json", - "**/hotfixRepos.json", "**/demo/team.json", "**/demo/user.json", "**/*_html.ts", "**/*.ignore_data.ts", "package*.json", - ".devcontainer/nih/**" + ".devcontainer/nih/**", + "**/assets/*.xlsx", + "**/known.csv" ], "enableGlobDot": true, "useGitignore": true, "words": [ + "1es", + "1escopilot", "aadgraph", "aadid", "aadname", "aadoid", "aadupn", + "accesslevel", "accountinfo", "accountinformation", "actionperms", @@ -39,6 +44,7 @@ "actionsplatforms", "actionsupdated", "actionsused", + "actionsworkflowcount", "actorid", "adal", "additionals", @@ -56,6 +62,7 @@ "agreementversion", "alladmins", "allowunlock", + "alreadyrestored", "aosp", "apikey", "APPDIR", @@ -89,6 +96,7 @@ "blockui", "bootswatch", "bootup", + "branchname", "breakingchangereviewrequired", "browserconfig", "builddir", @@ -107,12 +115,17 @@ "CELA", "champscount", "champstatus", + "checkmarks", + "chromedriver", + "citus", + "citusdata", "classificationdelegated", "classificationnative", "classificationnativechecked", "classificationupdated", "classificationupdatedby", "classname", + "classpath", "cleanupblobs", "cleanupinvites", "cleanupkeys", @@ -134,6 +147,7 @@ "codespace", "codespaces", "collab", + "collaboratorid", "collabs", "columnbreak", "commitcomment", @@ -152,8 +166,10 @@ "contributionshareoptin", "copilotaccess", "copilotagreement", + "copilotprod", "copilotrequest", "Copybara", + "corpnet", "corporatealias", "corporatecount", "corporatedev", @@ -164,6 +180,7 @@ "corporatename", "corporateprod", "corporateusername", + "countuse", "createdat", "creategithubaccount", "creds", @@ -179,12 +196,14 @@ "DATETIME", "dbaeumer", "dcount", + "deadcode", "decisionmaker", "Decisionmaker", "Decisionmakers", "deepmerge", "defaultbranch", "deferreason", + "definitelytyped", "deislabs", "deletedetected", "deletesettingsorgname", @@ -199,6 +218,8 @@ "devstaging", "directoryname", "directowners", + "disablewave", + "distributeonly", "distro", "divisionid", "dnfmit", @@ -211,6 +232,7 @@ "dropup", "DSRE", "eastus", + "Ecosyste", "edgecase", "electionid", "eligibilityend", @@ -245,6 +267,7 @@ "enterprisevisited", "entityid", "entitytype", + "entra", "esbody", "esemail", "eshead", @@ -252,6 +275,7 @@ "eventid", "eventrecord", "eventtype", + "exceljs", "existingrepoid", "existingreponame", "fakeaccesstoken", @@ -263,9 +287,11 @@ "firstconfigured", "FIRSTRUNFILE", "flipgrid", + "fontawesome", "fontname", "forceopen", "forkscount", + "fortawesome", "FOSS", "FOSSFUND", "fossfundabout", @@ -287,8 +313,8 @@ "GHID", "GHMP", "ghname", - "ghowners", "ghossapis", + "ghowners", "GHPI", "ghpimigrationphase", "ghrp", @@ -323,9 +349,12 @@ "haswiki", "hierarchynames", "hierarchytext", + "highcharts", "hsts", "Hsts", "HSTS", + "hubber", + "hubbers", "hubot", "IAAD", "ictext", @@ -363,15 +392,18 @@ "issuecomment", "issuesopened", "istest", + "jabberpl", "jeffwilcox", "jitgrants", "joblog", "jobname", + "json", "jsoncontribution", "jsoncreated", "jwilcox", "jwks", "JWTs", + "keybytes", "keyout", "keyvault", "KEYVAULT", @@ -386,6 +418,7 @@ "leftouter", "legalcontact", "legalentities", + "libsodium", "lightup", "linkid", "linkmanager", @@ -448,6 +481,8 @@ "monthlycontributionactivity", "msapplication", "msecnd", + "MSEULA", + "MSFTEULA", "MSFTIES", "msftmetadata", "msrc", @@ -468,6 +503,8 @@ "newrepolockremoved", "nihgithubportal", "nihdevgithubportal", + "Newtonsoft", + "NOASSERTION", "nodeapp", "nodenext", "noemail", @@ -479,8 +516,10 @@ "notifiedissueid", "npminitignore", "npminstallignore", + "npmjs", "npmrc", "nums", + "Nunit", "octicon", "odata", "offboard", @@ -511,6 +550,7 @@ "opensourcedocsprod", "opensourceprod", "opensourcepulls", + "opensourcerepoowners", "opensourcereposdev", "opensourcereposprod", "opensourcesite", @@ -539,6 +579,7 @@ "organizationlogin", "organizationmembercache", "organizationname", + "organizationrunners", "organizationsetting", "organizationsettings", "orgid", @@ -593,6 +634,7 @@ "pmownerid", "popd", "portaldescription", + "portaldev", "portalppe", "portalprod", "portalwestus", @@ -642,6 +684,8 @@ "removeothergithubaccount", "REPLYTO", "repocount", + "repodisablebranchprotections", + "repodisableoutsidecollaborators", "repoid", "repoidifyouhaveit", "repolockdown", @@ -679,6 +723,8 @@ "revokedbycorporateid", "rootdir", "rubygem", + "rubygems", + "RUNNERDATA", "runtimes", "samplescollaboratorusername", "samplescontact", @@ -690,6 +736,8 @@ "scansummary", "SCIM", "scorecardreprocessrequest", + "secretbox", + "secretless", "secretscanningonpush", "secscandata", "securityevents", @@ -726,6 +774,7 @@ "shortcutting", "shouldrestore", "showids", + "shuf", "Sida", "signin", "signoff", @@ -738,13 +787,11 @@ "specialteams", "SSIRP", "sslify", - "Sslify", "standardsredirect", "stargazerscount", "startclean", - "StartClean", + "startofday", "startright", - "StartRight", "startswith", "statechecked", "steelblue", @@ -784,6 +831,8 @@ "timezoneoffset", "tlink", "tolower", + "Toolset", + "toscalar", "totalcount", "touchedtime", "toupper", @@ -803,6 +852,7 @@ "unadopted", "unarchived", "Unauthoritative", + "Uncommited", "unconfigured", "Unconfigured", "unconfirmedorganizationname", @@ -850,21 +900,22 @@ "Wcag", "webapps", "webcontext", + "webfonts", "webhoooks", "welcomeemailsent", "whois", "Whois", "withmaintainers", "withservicetree", - "workboard", - "Workboard", - "workboarding", + "withsource", + "wixtoolset", "xamarinhq", "Xcache", "xlink", "XSTORE", "xtable", - "yamls" + "yamls", + "yml" ], "maxNumberOfProblems": 1000 } diff --git a/.editorconfig b/.editorconfig index d7ce5c432..6375e1c4c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,3 +9,4 @@ indent_size = 2 trim_trailing_whitespace = true charset = utf-8 end_of_line = lf +tabCompletion = on diff --git a/.eslintrc.js b/.eslintrc.js index cf1525756..3c5d9899b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,5 +41,10 @@ module.exports = { }, }, ], - ignorePatterns: ['default-assets-package/thirdparty/**/*.js', 'dist/**/*.js', '**/vendor/**'], + ignorePatterns: [ + 'default-assets-package/thirdparty/**/*.js', + 'dist/**/*.js', + 'dist/**/*.d.ts', + '**/vendor/**', + ], }; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27cb497a5..44beab153 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,10 +13,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: cache: npm diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index be69f6ca4..2eb6669f6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -15,11 +15,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java @@ -27,7 +27,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # โ„น๏ธ Command-line programs to run using the OS shell. # ๐Ÿ“š https://git.io/JvXDl @@ -41,4 +41,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index 179b287a5..c1dd30444 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout ๐Ÿ›’ - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Packages ๐Ÿ“ฆ run: | @@ -36,7 +36,7 @@ jobs: environment: name: development steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 #- uses: docker/build-push-action@v3 - name: Azure OpenID Connect โœจ diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 350edfea4..65f5bbf4e 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,7 +13,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: stale-issue-message: This issue has been identified as stale because it has gone 30 days with no activity. diff --git a/.gitignore b/.gitignore index d83fe8f0b..d7f45ffdf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ dist/ node_modules/ .DS_Store +reports/ # Potential local development environment scripts app.yaml @@ -13,3 +14,4 @@ feedscan feedscan* ..prettierignore.swp scripts/localCodespace.ts +junit.xml diff --git a/.prettierrc.json b/.prettierrc.json index 32e9fdbd7..f7aa09f41 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,4 +1,5 @@ { "singleQuote": true, + "trailingComma": "es5", "printWidth": 110 } diff --git a/.secrets.env.example b/.secrets.env.example index a81c4a1ee..896300ed7 100644 --- a/.secrets.env.example +++ b/.secrets.env.example @@ -1,4 +1,3 @@ -GITHUB_CENTRAL_OPERATIONS_TOKEN= GITHUB_CLIENT_ID= GITHUB_CLIENT_SECRET= GITHUB_CALLBACK_URL=http://localhost:3000/auth/github/callback diff --git a/.vscode/launch.json b/.vscode/launch.json index d1caa8213..491b43343 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ { "type": "node", "request": "launch", - "name": "Launch site 3000", + "name": "Launch site :4000 sudo", "program": "${workspaceFolder}/dist/bin/www.js", "cwd": "${workspaceFolder}/dist", "preLaunchTask": "tsbuild", @@ -12,26 +12,32 @@ "console": "integratedTerminal", "env": { "NODE_ENV": "development", - "DEBUG": "startup,g:server,context,github:tokens", - "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org,health" + "PORT": "4000", + "DEBUG_GITHUB_PORTAL_SUDO_FORCE": "1", + "DEBUG": "startup,cosmosdb,g:server,context,*simple-oauth2*,appinsights,insights", + "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org" } }, { "type": "node", "request": "launch", - "name": "Jest Tests", - "program": "${workspaceRoot}/node_modules/jest/bin/jest.js", - "args": ["-i"], + "name": "Launch site :4000 as-is", + "program": "${workspaceFolder}/dist/bin/www.js", + "cwd": "${workspaceFolder}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, - "internalConsoleOptions": "openOnSessionStart", - "console": "externalTerminal", - "outFiles": ["${workspaceRoot}/dist/**/*"] + "console": "integratedTerminal", + "env": { + "NODE_ENV": "development", + "PORT": "4000", + "DEBUG": "startup,g:server,context,*simple-oauth2*,appinsights,insights,appinsights", + "_DEBUG": "cosmosdb,cache" + } }, { "type": "node", "request": "launch", - "name": "Launch site 4000 sudo", + "name": "Launch site :4000 sudo OFF", "program": "${workspaceFolder}/dist/bin/www.js", "cwd": "${workspaceFolder}/dist", "preLaunchTask": "tsbuild", @@ -40,15 +46,16 @@ "env": { "NODE_ENV": "development", "PORT": "4000", - "DEBUG_GITHUB_PORTAL_SUDO_FORCE": "1", - "DEBUG": "startup,cosmosdb,g:server,context,*simple-oauth2*,appinsights,insights", + "DEBUG": "startup,cosmosdb,g:server,context", + "DEBUG_GITHUB_PORTAL_SUDO_OFF": "1", + "DEBUG_GITHUB_ORG_SUDO_OFF": "1", "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org" } }, { "type": "node", "request": "launch", - "name": "Launch site 4000 sudo OFF", + "name": "Launch server-rendered legacy site :3000", "program": "${workspaceFolder}/dist/bin/www.js", "cwd": "${workspaceFolder}/dist", "preLaunchTask": "tsbuild", @@ -56,18 +63,15 @@ "console": "integratedTerminal", "env": { "NODE_ENV": "development", - "PORT": "4000", - "DEBUG": "startup,cosmosdb,g:server,context", - "DEBUG_GITHUB_PORTAL_SUDO_OFF": "1", - "DEBUG_GITHUB_ORG_SUDO_OFF": "1", - "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org" + "DEBUG": "startup,g:server,context", + "MORE_DEBUG": "appinsights,cache,restapi,pg,querycache,user,redis-cross-org,health,github:tokens" } }, { "type": "node", "request": "launch", - "name": "Background Job: Firehose", - "program": "${workspaceRoot}/dist/jobs/firehose/index.js", + "name": "Background Job: Event firehose", + "program": "${workspaceRoot}/dist/jobs/firehose.js", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", @@ -77,6 +81,18 @@ "DEBUG": "startup,querycache" } }, + { + "type": "node", + "request": "launch", + "name": "Jest Tests", + "program": "${workspaceRoot}/node_modules/jest/bin/jest.js", + "args": ["-i"], + "preLaunchTask": "tsbuild", + "sourceMaps": true, + "internalConsoleOptions": "openOnSessionStart", + "console": "externalTerminal", + "outFiles": ["${workspaceRoot}/dist/**/*"] + }, { "type": "node", "request": "launch", @@ -118,7 +134,7 @@ "sourceMaps": true, "env": { "NODE_ENV": "development", - "DEBUG": "appinsights,restapi,startup,redis-cross-org,appinsights", + "DEBUG": "appinsights,startup", "DEBUG_GITHUB_PORTAL_SUDO_OFF": "1", "DEBUG_GITHUB_ORG_SUDO_OFF": "1" } @@ -134,42 +150,30 @@ "console": "integratedTerminal", "env": { "NODE_ENV": "localhost", - "DEBUG": "startup" + "DEBUG": "startup", + "EXIT_IMMEDIATELY": "1" } }, { "type": "node", "request": "launch", - "name": "Job: Cleanup invitations", - "program": "${workspaceRoot}/dist/jobs/cleanupInvites/index.js", - "cwd": "${workspaceRoot}/dist", - "preLaunchTask": "tsbuild", - "sourceMaps": true, - "console": "integratedTerminal", - "env": { - "NODE_ENV": "development", - "DEBUG": "redis,restapi,startup,appinsights" - } - }, - { - "type": "node", - "request": "launch", - "name": "Job: Cleanup blob cache", - "program": "${workspaceRoot}/dist/jobs/cleanupBlobCache/index.js", + "name": "66: Order 66 Terminations", + "program": "${workspaceRoot}/dist/microsoft/jobs/terminations.js", + "args": ["all"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", "env": { "NODE_ENV": "development", - "DEBUG": "startup" + "DEBUG": "startup,appinsights" } }, { "type": "node", "request": "launch", "name": "Job: Backfill aliases (3)", - "program": "${workspaceRoot}/dist/jobs/refreshUsernames/index.js", + "program": "${workspaceRoot}/dist/jobs/refreshUsernames.js", "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, @@ -184,21 +188,21 @@ "type": "node", "request": "launch", "name": "Job: User attributes hygiene (4)", - "program": "${workspaceRoot}/dist/jobs/refreshUsernames/index.js", + "program": "${workspaceRoot}/dist/jobs/refreshUsernames.js", "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", "env": { "NODE_ENV": "development", - "DEBUG": "redis,restapi,startup,appinsights,cache" + "DEBUG": "startup,appinsights" } }, { "type": "node", "request": "launch", "name": "Job: Consistency: All (6)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", "args": ["all"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -213,7 +217,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Deleted repos (7)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/deletedRepositories.js", + "program": "${workspaceRoot}/dist/jobs/deletedRepositoriesCache.js", "args": [], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -228,7 +232,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Teams (8)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", "args": ["teams"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -243,7 +247,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Org members (9)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", "args": ["organizations"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -258,7 +262,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Repo collaborators (10)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", "args": ["collaborators"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -273,7 +277,7 @@ "type": "node", "request": "launch", "name": "Job: Consistency: Team permissions (11)", - "program": "${workspaceRoot}/dist/jobs/refreshQueryCache/index.js", + "program": "${workspaceRoot}/dist/jobs/refreshQueryCache.js", "args": ["permissions"], "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", @@ -301,8 +305,8 @@ { "type": "node", "request": "launch", - "name": "Job: Migrate links", - "program": "${workspaceRoot}/dist/jobs/migrateLinks/index.js", + "name": "Job: Migrate links (14)", + "program": "${workspaceRoot}/dist/jobs/migrateLinks.js", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", @@ -315,8 +319,8 @@ { "type": "node", "request": "launch", - "name": "Job: System Team Permissions", - "program": "${workspaceRoot}/dist/jobs/permissions/index.js", + "name": "Job: System Team Permissions (15)", + "program": "${workspaceRoot}/dist/jobs/permissions.js", "cwd": "${workspaceRoot}/dist", "preLaunchTask": "tsbuild", "sourceMaps": true, @@ -326,6 +330,48 @@ "DEBUG": "startup,appinsights" } }, + { + "type": "node", + "request": "launch", + "name": "Job: Cleanup invitations (16)", + "program": "${workspaceRoot}/dist/jobs/cleanupInvites.js", + "cwd": "${workspaceRoot}/dist", + "preLaunchTask": "tsbuild", + "sourceMaps": true, + "console": "integratedTerminal", + "env": { + "NODE_ENV": "development", + "DEBUG": "redis,restapi,startup,appinsights" + } + }, + { + "type": "node", + "request": "launch", + "name": "Job: Cleanup blob cache (17)", + "program": "${workspaceRoot}/dist/jobs/cleanupBlobCache.js", + "cwd": "${workspaceRoot}/dist", + "preLaunchTask": "tsbuild", + "sourceMaps": true, + "console": "integratedTerminal", + "env": { + "NODE_ENV": "development", + "DEBUG": "startup" + } + }, + { + "type": "node", + "request": "launch", + "name": "Job: Cleanup team requests (18)", + "program": "${workspaceRoot}/dist/jobs/cleanupTeamRequests.js", + "cwd": "${workspaceRoot}/dist", + "preLaunchTask": "tsbuild", + "sourceMaps": true, + "console": "integratedTerminal", + "env": { + "NODE_ENV": "development", + "DEBUG": "startup" + } + }, { "type": "node", "request": "launch", @@ -345,7 +391,7 @@ "type": "node", "request": "launch", "name": "Script: Import audit CSV", - "program": "${workspaceRoot}/dist/jobs/importAuditLog/index.js", + "program": "${workspaceRoot}/dist/jobs/importAuditLog.js", "preLaunchTask": "tsbuild", "sourceMaps": true, "console": "integratedTerminal", diff --git a/Dockerfile b/Dockerfile index 9daba8526..a3f30f081 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,40 +1,35 @@ -ARG IMAGE_NAME=node:16-alpine +# +# Copyright (c) Microsoft. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. +# + +ARG IMAGE_NAME=mcr.microsoft.com/cbl-mariner/base/nodejs:18 FROM $IMAGE_NAME AS build ARG NPM_TOKEN -# Make Git available for NPM and rsync in the build image -RUN apk add --update git && rm -rf /var/cache/apk/* - -WORKDIR /build -COPY package.json . -COPY package-lock.json . +RUN tdnf -y update --quiet -# Only if needed, copy .npmrc files into the container -# COPY Dockerfile.npmrc /build/.npmrc +# We used to also make Git available for NPM and rsync in build +# tdnf clean all --quiet && \ +# tdnf -y install ca-certificates git --quiet && \ -# If you are doing local development and OK with your private tokens in the contains (CAREFUL): -# DO NOT RECOMMEND: -# COPY .npmrc /build/.npmrc - -# RUN npm install --production --verbose && mv node_modules production_node_modules -RUN npm install --production && mv node_modules production_node_modules +WORKDIR /build COPY . . -# Only if needed, copy .npmrc files into the container, again... -# COPY Dockerfile.npmrc /build/.npmrc +# Only if needed, copy file with NPM_TOKEN arg +# COPY .npmrc.arg /build/.npmrc -# Dev dependencies -# RUN npm install --verbose && rm -rf .npmrc -RUN npm install && rm -rf .npmrc - -# TypeScript build +RUN npm install --ignore-scripts --production --verbose +RUN npm ci RUN npm run-script build +RUN mv node_modules production_node_modules +RUN rm -f .npmrc # The open source project build needs: build the site assets sub-project -RUN cd default-assets-package && npm install && npm run build +RUN cd default-assets-package && npm ci && npm run build FROM $IMAGE_NAME AS run @@ -47,24 +42,26 @@ EXPOSE 3000 WORKDIR /usr/src/repos -RUN addgroup oss && adduser -D -G oss oss && chown -R oss:oss . - # Production Node.js modules -COPY --from=build --chown=oss:oss /build/production_node_modules ./node_modules +COPY --from=build /build/production_node_modules ./node_modules # People not using painless config may need -COPY --from=build --chown=oss:oss /build/data ./data +COPY --from=build /build/data ./data # Copy built assets, app, config map -COPY --from=build --chown=oss:oss /build/dist ./ +COPY --from=build /build/dist ./ # The open source project build needs: default assets should be placed -COPY --from=build --chown=oss:oss /build/default-assets-package ./default-assets-package +COPY --from=build /build/default-assets-package ./default-assets-package + +COPY --from=build /build/config ./config +COPY --from=build /build/views ./views +COPY --from=build /build/package.json ./package.json + +# Only if needed, copy our environment +# COPY --from=build /build/.environment ./.environment -COPY --from=build --chown=oss:oss /build/config ./config -COPY --from=build --chown=oss:oss /build/views ./views -COPY --from=build --chown=oss:oss /build/package.json ./package.json +# Only if needed, binary resources +# COPY --from=build /build/microsoft/assets ./microsoft/assets -# Host the app -USER oss -ENTRYPOINT ["npm", "run-script", "start-in-container"] \ No newline at end of file +ENTRYPOINT ["npm", "run-script", "start-in-container"] diff --git a/api/client/banner.ts b/api/client/banner.ts index 732a5cc68..a4ccd0f88 100644 --- a/api/client/banner.ts +++ b/api/client/banner.ts @@ -3,17 +3,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import { ReposAppRequest } from '../../interfaces'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; const router: Router = Router(); // TODO: move to modern w/administration experience, optionally -router.get('/', (req: ReposAppRequest, res, next) => { +router.get('/', (req: ReposAppRequest, res: Response, next: NextFunction) => { const { config } = getProviders(req); const text = config?.serviceMessage?.banner || null; const link = config.serviceMessage?.link; @@ -22,7 +22,7 @@ router.get('/', (req: ReposAppRequest, res, next) => { return res.json({ banner }); }); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available within this banner route', 404)); }); diff --git a/api/client/context/administration/app.ts b/api/client/context/administration/app.ts new file mode 100644 index 000000000..0734a4385 --- /dev/null +++ b/api/client/context/administration/app.ts @@ -0,0 +1,74 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { NextFunction, Response, Router } from 'express'; +import asyncHandler from 'express-async-handler'; + +import { ReposAppRequest } from '../../../../interfaces'; +import { CreateError, getProviders } from '../../../../lib/transitional'; + +import routeIndividualApp from './app'; +import GitHubApplication from '../../../../business/application'; +import { OrganizationSetting } from '../../../../business/entities/organizationSettings/organizationSetting'; +import { sortByCaseInsensitive } from '../../../../lib/utils'; +import routeApplicationInstallation from './appInstallation'; +import { ApiRequestWithGitHubApplication, RequestWithInstallation } from './types'; + +const router: Router = Router(); + +router.get( + '/', + asyncHandler(async function (req: ApiRequestWithGitHubApplication, res: Response, next: NextFunction) { + const { gitHubApplication } = req; + const installationIdString = req.query.installation_id; + const setupAction = req.query.setup_action; + // if (installationIdString && setupAction) { + // return res.redirect( + // `./${githubApplication.id}/installations/${installationIdString}?setup_action=${setupAction}` + // ); + // } + // const individualContext = req.individualContext; + const allInstalls = await gitHubApplication.getInstallations({ maxAgeSeconds: 5 }); + const { valid, invalid } = GitHubApplication.filterInstallations(allInstalls); + return res.json({ + state: { + installations: { + valid, + invalid, + }, + app: gitHubApplication.asClientJson(), + }, + }) as unknown as void; + }) +); + +router.use( + '/installations/:installationId', + asyncHandler(async function (req: RequestWithInstallation, res, next) { + // const installationIdString = req.query.installation_id; + // const setupAction = req.query.setup_action; + const { gitHubApplication } = req; + const { installationId: installationIdAsString } = req.params; + const installationId = Number(installationIdAsString); + const installation = await gitHubApplication.getInstallation(installationId); + if (!installation) { + return next( + CreateError.NotFound( + `The GitHub app installation ${installationIdAsString} could not be found for app ${gitHubApplication.id}` + ) + ); + } + req.installation = installation; + return next(); + }) +); + +router.use('/installations/:installationId', routeApplicationInstallation); + +router.use('*', (req, res: Response, next: NextFunction) => { + return next(CreateError.NotFound('no API or function available: context/administration/apps/...')); +}); + +export default router; diff --git a/api/client/context/administration/appInstallation.ts b/api/client/context/administration/appInstallation.ts new file mode 100644 index 000000000..b05c906a1 --- /dev/null +++ b/api/client/context/administration/appInstallation.ts @@ -0,0 +1,59 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { NextFunction, Response, Router } from 'express'; +import asyncHandler from 'express-async-handler'; + +import { CreateError, getProviders } from '../../../../lib/transitional'; +import { OrganizationSetting } from '../../../../business/entities/organizationSettings/organizationSetting'; +import { AdministrativeGitHubAppInstallationResponse, RequestWithInstallation } from './types'; + +const router: Router = Router(); + +router.use( + asyncHandler(async function (req: RequestWithInstallation, res: Response, next: NextFunction) { + const { operations, organizationSettingsProvider } = getProviders(req); + + const { installation } = req; + const organizationId = installation.account.id; + const organizationName = installation.account.login; + let settings: OrganizationSetting = null; + try { + settings = await organizationSettingsProvider.getOrganizationSetting(organizationId.toString()); + } catch (notFound) { + /* ignored */ + } + req.organizationDynamicSettings = settings; + + const staticSettings = operations.getOrganizationSettings(organizationName); + req.organizationStaticSettings = staticSettings; + + return next(); + }) +); + +router.get( + '/', + asyncHandler(async (req: RequestWithInstallation, res: Response, next: NextFunction) => { + const { gitHubApplication, installation, organizationDynamicSettings, organizationStaticSettings } = req; + const response: AdministrativeGitHubAppInstallationResponse = { + app: gitHubApplication.asClientJson(), + // installation, + installationId: installation.id, + dynamicSettings: organizationDynamicSettings, + }; + return res.json(response) as unknown as void; + }) +); + +router.use('*', (req, res: Response, next: NextFunction) => { + return next( + CreateError.NotFound( + 'no API or function available: context/administration/apps/:appId/installations/:installationId' + ) + ); +}); + +export default router; diff --git a/api/client/context/administration/apps.ts b/api/client/context/administration/apps.ts new file mode 100644 index 000000000..f9f6e3db0 --- /dev/null +++ b/api/client/context/administration/apps.ts @@ -0,0 +1,128 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { NextFunction, Response, Router } from 'express'; +import asyncHandler from 'express-async-handler'; + +import { ReposAppRequest } from '../../../../interfaces'; +import { CreateError, getProviders } from '../../../../lib/transitional'; + +import routeIndividualApp from './app'; +import GitHubApplication from '../../../../business/application'; +import { sortByCaseInsensitive } from '../../../../lib/utils'; +import { + ApiRequestWithGitHubApplication, + ManagedOrganizationAppConfigurationsByOrgView, + ManagedOrganizationStatus, +} from './types'; + +const router: Router = Router(); + +router.get( + '/', + asyncHandler(async (req: ReposAppRequest, res: Response) => { + const { operations, organizationSettingsProvider } = getProviders(req); + const apps = operations.getApplications(); + const byOrg = new Map(); + function getOrg(name: string) { + let o = byOrg.get(name); + if (!o) { + o = { + organizationName: name, + id: undefined, + status: ManagedOrganizationStatus.NotAdopted, + appInstallations: new Map(), + dynamicSettings: null, + configuredInstallations: [], + }; + for (const app of apps) { + o.appInstallations.set(app.id, null); + } + byOrg.set(name, o); + } + return o; + } + for (const app of apps) { + const appInstalls = await app.getInstallations({ maxAgeSeconds: 5 }); + const { valid: validInstallations } = GitHubApplication.filterInstallations(appInstalls); + for (const valid of validInstallations) { + const organizationName = valid.account.login; + const o = getOrg(organizationName.toLowerCase()); + o.appInstallations.set(app.id, { + app, + installationId: valid.id, + }); + o.id = Number(valid.target_id); + if (!o.dynamicSettings && valid.target_type === 'Organization') { + try { + o.dynamicSettings = await organizationSettingsProvider.getOrganizationSetting( + valid.target_id.toString() + ); + } catch (ignore) { + /* ignored */ + } + if (o.dynamicSettings) { + o.configuredInstallations = o.dynamicSettings.installations.map( + (install) => install.installationId + ); + o.status = ManagedOrganizationStatus.Adopted; + } + if (o.dynamicSettings && o.dynamicSettings.active === true) { + o.status = ManagedOrganizationStatus.Active; + } + } + } + } + for (const organization of operations.organizations.values()) { + const anOrg = getOrg(organization.name.toLowerCase()); + anOrg.id = organization.id; + } + const orgNames = Array.from(byOrg.keys()).sort(sortByCaseInsensitive); + return res.json({ + apps: apps.map((app) => app.asClientJson()), + orgNames, + orgs: Array.from(byOrg.values()).map((data) => { + return { + name: data.organizationName, + status: data.status, + id: data.id, + configuredInstallations: data.configuredInstallations, + hasDynamicSettings: !!data.dynamicSettings, + appInstallations: Array.from(data.appInstallations.keys()) + .filter((a) => a) + .map((appIdKey) => { + const install = data.appInstallations.get(appIdKey); + return { + installationId: install?.installationId, + appId: install?.app?.id, + }; + }), + }; + }), + }) as unknown as void; + }) +); + +router.use( + '/:appId', + asyncHandler(async function (req: ApiRequestWithGitHubApplication, res: Response, next: NextFunction) { + const { operations } = getProviders(req); + const appId = Number(req.params.appId); + const app = operations.getApplicationById(appId); + if (app) { + req.gitHubApplication = app; + return next(); + } + return next(CreateError.NotFound('no app available with that ID')); + }) +); + +router.use('/:appId', routeIndividualApp); + +router.use('*', (req, res: Response, next: NextFunction) => { + return next(CreateError.NotFound('no API or function available: context/administration/apps')); +}); + +export default router; diff --git a/api/client/context/administration/index.ts b/api/client/context/administration/index.ts index 12889f5aa..cb3e3aab5 100644 --- a/api/client/context/administration/index.ts +++ b/api/client/context/administration/index.ts @@ -3,15 +3,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; + import { Organization } from '../../../../business/organization'; import { ReposAppRequest } from '../../../../interfaces'; import { getIsCorporateAdministrator, jsonError } from '../../../../middleware'; import getCompanySpecificDeployment from '../../../../middleware/companySpecificDeployment'; -import { ErrorHelper, getProviders } from '../../../../transitional'; +import { ErrorHelper, getProviders } from '../../../../lib/transitional'; import routeIndividualOrganization from './organization'; +import routeApps from './apps'; const router: Router = Router(); @@ -20,7 +22,7 @@ interface IRequestWithAdministration extends ReposAppRequest { } router.use( - asyncHandler(async (req: IRequestWithAdministration, res, next) => { + asyncHandler(async (req: IRequestWithAdministration, res: Response, next: NextFunction) => { req.isSystemAdministrator = await getIsCorporateAdministrator(req); return next(); }) @@ -28,29 +30,31 @@ router.use( router.get( '/', - asyncHandler(async (req: IRequestWithAdministration, res, next) => { + asyncHandler(async (req: IRequestWithAdministration, res: Response) => { const { operations } = getProviders(req); const isAdministrator = req.isSystemAdministrator; if (!isAdministrator) { return res.json({ isAdministrator, - }); + }) as unknown as void; } const organizations = operations.getOrganizations().map((org) => org.asClientJson()); return res.json({ isAdministrator, organizations, - }); + }) as unknown as void; }) ); -router.use((req: IRequestWithAdministration, res, next) => { +router.use((req: IRequestWithAdministration, res: Response, next: NextFunction) => { return req.isSystemAdministrator ? next() : next(jsonError('Not authorized', 403)); }); +router.use('/apps', routeApps); + router.use( '/organization/:orgName', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { orgName } = req.params; const { operations } = getProviders(req); let organization: Organization = null; @@ -61,7 +65,8 @@ router.use( } catch (noOrgError) { if (ErrorHelper.IsNotFound(noOrgError)) { res.status(404); - return res.end(); + res.end(); + return; } return next(jsonError(noOrgError, 500)); } @@ -74,7 +79,7 @@ const deployment = getCompanySpecificDeployment(); deployment?.routes?.api?.context?.administration?.index && deployment?.routes?.api?.context.administration.index(router); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available: context/administration', 404)); }); diff --git a/api/client/context/administration/organization/index.ts b/api/client/context/administration/organization/index.ts index 45db6953e..5ed533872 100644 --- a/api/client/context/administration/organization/index.ts +++ b/api/client/context/administration/organization/index.ts @@ -3,8 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; + import { ReposAppRequest } from '../../../../../interfaces'; import { jsonError } from '../../../../../middleware'; @@ -16,15 +17,15 @@ router.use('/settings', routeSettings); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; return res.json({ organization: organization.asClientJson(), - }); + }) as unknown as void; }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available in administration - organization', 404)); }); diff --git a/api/client/context/administration/organization/settings.ts b/api/client/context/administration/organization/settings.ts index a1c805df2..4c3201fa1 100644 --- a/api/client/context/administration/organization/settings.ts +++ b/api/client/context/administration/organization/settings.ts @@ -3,12 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; -import { OrganizationSetting } from '../../../../../entities/organizationSettings/organizationSetting'; + +import { OrganizationSetting } from '../../../../../business/entities/organizationSettings/organizationSetting'; import { ReposAppRequest } from '../../../../../interfaces'; import { jsonError } from '../../../../../middleware'; -import { ErrorHelper, getProviders } from '../../../../../transitional'; +import { CreateError, ErrorHelper, getProviders } from '../../../../../lib/transitional'; const router: Router = Router(); @@ -17,7 +18,7 @@ interface IOrganizationSettings extends ReposAppRequest { } router.use( - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { organization } = req; const { organizationSettingsProvider } = getProviders(req); try { @@ -34,11 +35,32 @@ router.use( router.get( '/', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { dynamicSettings } = req; return res.json({ dynamicSettings, - }); + }) as unknown as void; + }) +); + +router.delete( + '/', + asyncHandler(async function (req: IOrganizationSettings, res: Response) { + const { dynamicSettings } = req; + const { organizationId } = dynamicSettings; + const { organizationSettingsProvider, queryCache } = getProviders(req); + const orgName = req.query.deleteOrganizationConfiguration as string; + if (orgName?.toLowerCase() !== dynamicSettings.organizationName.toLowerCase()) { + throw CreateError.InvalidParameters( + 'The organization name provided does not match the organization name in the configuration.' + ); + } + await organizationSettingsProvider.deleteOrganizationSetting(dynamicSettings); + res.status(204); + if (queryCache) { + queryCache.removeOrganizationById(String(organizationId)); + } + return res.end() as unknown as void; }) ); @@ -46,49 +68,61 @@ router.get( router.get( '/features', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { dynamicSettings, organization } = req; const { features } = dynamicSettings; return res.json({ features, organizationName: organization.name, - }); + }) as unknown as void; }) ); router.get( '/feature/:flag', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { dynamicSettings, organization } = req; const flag = req.params.flag as string; return res.json({ flag, value: dynamicSettings.features.includes(flag) ? flag : null, organizationName: organization.name, - }); + }) as unknown as void; }) ); router.put( '/feature/:flag', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { dynamicSettings, organization } = req; const { insights, organizationSettingsProvider } = getProviders(req); const { features } = dynamicSettings; const flag = req.params.flag as string; + const restart = req.query.restart === '1'; insights?.trackEvent({ name: 'AddOrganizationFeatureFlag', properties: { flag, + restart, currentFeatureFlags: features.join(', '), }, }); - if (features.includes(flag)) { - return next(jsonError(`flag "${flag}" is already set`, 400)); + // special case + if (flag === 'active') { + if (dynamicSettings.active) { + return next(CreateError.InvalidParameters('The organization is already active.')); + } + dynamicSettings.active = true; + } else { + if (features.includes(flag)) { + return next(jsonError(`flag "${flag}" is already set`, 400)); + } + dynamicSettings.features.push(flag); } - dynamicSettings.features.push(flag); try { - dynamicSettings.updated = new Date(); + if (restart) { + dynamicSettings.updated = new Date(); + } await organizationSettingsProvider.updateOrganizationSetting(dynamicSettings); } catch (error) { return next(jsonError(`error adding flag "${flag}": ${error}`, ErrorHelper.GetStatus(error) || 400)); @@ -96,31 +130,43 @@ router.put( return res.json({ flag, value: dynamicSettings.features.includes(flag) ? flag : null, + restart, organizationName: organization.name, - }); + }) as unknown as void; }) ); router.delete( '/feature/:flag', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { organization, dynamicSettings } = req; const { organizationSettingsProvider, insights } = getProviders(req); const { features } = dynamicSettings; const flag = req.params.flag as string; + const restart = req.query.restart === '1'; insights?.trackEvent({ name: 'RemoveOrganizationFeatureFlag', properties: { flag, + restart, currentFeatureFlags: features.join(', '), }, }); - if (!features.includes(flag)) { - return next(jsonError(`flag "${flag}" is not set`, 400)); + if (flag === 'active') { + if (!dynamicSettings.active) { + return next(CreateError.InvalidParameters('The organization is already inactive.')); + } + dynamicSettings.active = false; + } else { + if (!features.includes(flag)) { + return next(jsonError(`flag "${flag}" is not set`, 400)); + } + dynamicSettings.features = dynamicSettings.features.filter((flagEntry) => flagEntry !== flag); } - dynamicSettings.features = dynamicSettings.features.filter((flagEntry) => flagEntry !== flag); try { - dynamicSettings.updated = new Date(); + if (restart) { + dynamicSettings.updated = new Date(); + } await organizationSettingsProvider.updateOrganizationSetting(dynamicSettings); } catch (error) { return next(jsonError(`error removing flag "${flag}": ${error}`, ErrorHelper.GetStatus(error) || 400)); @@ -128,8 +174,9 @@ router.delete( return res.json({ flag, value: dynamicSettings.features.includes(flag) ? flag : null, + restart, organizationName: organization.name, - }); + }) as unknown as void; }) ); @@ -137,19 +184,19 @@ router.delete( router.get( '/properties', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { dynamicSettings, organization } = req; const { properties } = dynamicSettings; return res.json({ properties, organizationName: organization.name, - }); + }) as unknown as void; }) ); router.get( '/property/:flag', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { dynamicSettings, organization } = req; const propertyName = req.params.propertyName as string; const { properties } = dynamicSettings; @@ -157,17 +204,18 @@ router.get( property: propertyName, value: properties[propertyName] || null, organizationName: organization.name, - }); + }) as unknown as void; }) ); router.put( '/property/:propertyName', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { organization, dynamicSettings } = req; const { insights, organizationSettingsProvider } = getProviders(req); const { properties } = dynamicSettings; const newValue = req.body.value as string; + const restart = req.query.restart === '1'; if (!newValue) { return next(jsonError('body.value required', 400)); } @@ -180,6 +228,7 @@ router.put( name: 'SetOrganizationSettingProperty', properties: { propertyName, + restart, currentProperties: JSON.stringify(properties), currentPropertyValue, }, @@ -187,7 +236,9 @@ router.put( const updateDescription = `Changing property ${propertyName} value from "${currentPropertyValue}" to "${newValue}"`; dynamicSettings.properties[propertyName] = newValue; try { - dynamicSettings.updated = new Date(); + if (restart) { + dynamicSettings.updated = new Date(); + } await organizationSettingsProvider.updateOrganizationSetting(dynamicSettings); } catch (error) { return next( @@ -202,25 +253,28 @@ router.put( value: properties[propertyName] || null, organizationName: organization.name, dynamicSettings, + restart, updateDescription, - }); + }) as unknown as void; }) ); router.delete( '/property/:propertyName', - asyncHandler(async (req: IOrganizationSettings, res, next) => { + asyncHandler(async (req: IOrganizationSettings, res: Response, next: NextFunction) => { const { organization, dynamicSettings } = req; const { organizationSettingsProvider, insights } = getProviders(req); const { properties } = dynamicSettings; const propertyName = req.params.propertyName as string; const currentPropertyValue = properties[propertyName] || null; + const restart = req.query.restart === '1'; insights?.trackEvent({ name: 'RemoveOrganizationSettingProperty', properties: { propertyName, currentProperties: JSON.stringify(properties), currentPropertyValue, + restart, }, }); if (properties[propertyName] === undefined) { @@ -228,7 +282,9 @@ router.delete( } delete dynamicSettings.properties[propertyName]; try { - dynamicSettings.updated = new Date(); + if (restart) { + dynamicSettings.updated = new Date(); + } await organizationSettingsProvider.updateOrganizationSetting(dynamicSettings); } catch (error) { return next( @@ -239,13 +295,14 @@ router.delete( property: propertyName, value: properties[propertyName] || null, organizationName: organization.name, - }); + restart, + }) as unknown as void; }) ); // -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available in administration - organization', 404)); }); diff --git a/api/client/context/administration/types.ts b/api/client/context/administration/types.ts new file mode 100644 index 000000000..710a2a63b --- /dev/null +++ b/api/client/context/administration/types.ts @@ -0,0 +1,44 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import GitHubApplication, { type GitHubAppDefinition } from '../../../../business/application'; +import { OrganizationSetting } from '../../../../business/entities/organizationSettings/organizationSetting'; +import type { IGitHubAppInstallation, ReposAppRequest } from '../../../../interfaces'; + +export type ApiRequestWithGitHubApplication = ReposAppRequest & { + gitHubApplication: GitHubApplication; +}; + +export enum ManagedOrganizationStatus { + Active = 'Active', + Adopted = 'Adopted', + NotAdopted = 'NotAdopted', +} + +export type ManagedOrganizationAppConfigurationsByOrgView = { + organizationName: string; + status: ManagedOrganizationStatus; + appInstallations: Map; + dynamicSettings: OrganizationSetting; + configuredInstallations: number[]; + id?: number; +}; + +export interface IByOrgViewAppInstallation { + app: GitHubApplication; + installationId?: number; +} + +export type RequestWithInstallation = ApiRequestWithGitHubApplication & { + installation: IGitHubAppInstallation; + organizationDynamicSettings: OrganizationSetting; + organizationStaticSettings: OrganizationSetting; +}; + +export type AdministrativeGitHubAppInstallationResponse = { + app: GitHubAppDefinition; + installationId: number; + dynamicSettings: OrganizationSetting; +}; diff --git a/api/client/context/approvals.ts b/api/client/context/approvals.ts index 3e21e398b..4d7a5b817 100644 --- a/api/client/context/approvals.ts +++ b/api/client/context/approvals.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Team, Organization } from '../../../business'; -import { TeamJoinApprovalEntity } from '../../../entities/teamJoinApproval/teamJoinApproval'; +import { TeamJoinApprovalEntity } from '../../../business/entities/teamJoinApproval/teamJoinApproval'; import { TeamJsonFormat, ReposAppRequest } from '../../../interfaces'; import { jsonError } from '../../../middleware'; import { @@ -16,7 +16,7 @@ import { Approvals_getUserRequests, closeOldRequest, } from '../../../routes/settings/approvals'; -import { getProviders } from '../../../transitional'; +import { getProviders } from '../../../lib/transitional'; import { IndividualContext } from '../../../business/user'; const router: Router = Router(); @@ -30,7 +30,7 @@ const approvalPairToJson = (pair: ApprovalPair) => { router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { approvalProvider, operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { @@ -38,7 +38,7 @@ router.get( teamResponsibilities: [], usersRequests: [], isLinked: false, - }); + }) as unknown as void; } try { // const username = activeContext.getGitHubIdentity().username; @@ -54,7 +54,7 @@ router.get( teamResponsibilities: teamResponsibilities.map(approvalPairToJson), usersRequests: usersRequests.map(approvalPairToJson), }; - return res.json(state); + return res.json(state) as unknown as void; } catch (error) { return next(jsonError(error)); } @@ -65,7 +65,7 @@ router.get( router.get( '/:approvalId', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const approvalId = req.params.approvalId; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { @@ -112,7 +112,7 @@ router.get( }) ); -router.use('*', (req: ReposAppRequest, res, next) => { +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { return next(jsonError('Contextual API or route not found within approvals', 404)); }); diff --git a/api/client/context/index.ts b/api/client/context/index.ts index efc9530a7..775716054 100644 --- a/api/client/context/index.ts +++ b/api/client/context/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Organization } from '../../../business'; @@ -11,7 +11,7 @@ import { IProviders, ReposAppRequest } from '../../../interfaces'; import { jsonError } from '../../../middleware'; import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; -import { ErrorHelper, getProviders } from '../../../transitional'; +import { ErrorHelper, getProviders } from '../../../lib/transitional'; import { IndividualContext } from '../../../business/user'; import routeApprovals from './approvals'; @@ -21,6 +21,7 @@ import routeRepos from './repos'; import routeTeams from './teams'; import routeAdministration from './administration'; import routeSample from './sample'; +import routeSettings from './settings'; const router: Router = Router(); @@ -48,7 +49,7 @@ router.get('/', (req: ReposAppRequest, res) => { router.get( '/specialized/multipleLinkGitHubIdentities', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const links = (activeContext?.link ? [activeContext.link, ...activeContext.additionalLinks] : []).map( @@ -73,13 +74,13 @@ router.get( response.deletedOrChangedUsernames.push(username); } } - return res.json(response); + return res.json(response) as unknown as void; }) ); router.get( '/accountDetails', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; try { @@ -104,10 +105,11 @@ router.get('/orgs', routeOrgs); router.get('/repos', routeRepos); router.get('/teams', routeTeams); router.use('/sample', routeSample); +router.use('/settings', routeSettings); router.use( '/orgs/:orgName', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { orgName } = req.params; const providers = getProviders(req); const { operations } = providers; @@ -123,12 +125,15 @@ router.use( return next(); } catch (noOrgError) { if (ErrorHelper.IsNotFound(noOrgError)) { + // Could be either the org truly does not exist, OR, it's uncontrolled. if (await isUnmanagedOrganization(providers, orgName)) { res.status(204); - return res.end(); + res.end(); + return; } res.status(404); - return res.end(); + res.end(); + return; } return next(jsonError(noOrgError, 500)); } @@ -151,7 +156,7 @@ async function isUnmanagedOrganization(providers: IProviders, orgName: string): router.use('/orgs/:orgName', routeIndividualContextualOrganization); -router.use('*', (req: ReposAppRequest, res, next) => { +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { return next(jsonError('Contextual API or route not found', 404)); }); diff --git a/api/client/context/organization/index.ts b/api/client/context/organization/index.ts index 6bb56a540..323e6f483 100644 --- a/api/client/context/organization/index.ts +++ b/api/client/context/organization/index.ts @@ -3,8 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; + import { Organization, Team } from '../../../../business'; import { ReposAppRequest, @@ -16,55 +17,56 @@ import { jsonError } from '../../../../middleware'; import getCompanySpecificDeployment from '../../../../middleware/companySpecificDeployment'; import { IndividualContext } from '../../../../business/user'; -import RouteRepos from './repos'; -import RouteTeams from './teams'; +import routeRepos from './repos'; +import routeTeams from './teams'; +import { CreateError } from '../../../../lib/transitional'; const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return res.json(false); + return res.json(false) as unknown as void; } const membership = await organization.getOperationalMembership( activeContext.getGitHubIdentity().username ); if (!membership) { - return res.json(false); + return res.json(false) as unknown as void; } return res.json({ user: toSanitizedUser(membership.user), organization: toSanitizedOrg(membership.organization), role: membership.role, state: membership.state, - }); + }) as unknown as void; }) ); router.get( '/sudo', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return res.json({ isSudoer: false }); + return res.json({ isSudoer: false }) as unknown as void; } return res.json({ isSudoer: await organization.isSudoer(activeContext.getGitHubIdentity().username, activeContext.link), - }); + }) as unknown as void; }) ); router.get( '/isOwner', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return res.json({ isOrganizationOwner: false }); + return res.json({ isOrganizationOwner: false }) as unknown as void; } try { const username = activeContext.getGitHubIdentity().username; @@ -72,21 +74,21 @@ router.get( const isOrganizationOwner = membership?.role === OrganizationMembershipRole.Admin; return res.json({ isOrganizationOwner, - }); + }) as unknown as void; } catch (error) { - return jsonError(error, 400); + return next(CreateError.InvalidParameters(error)); } }) ); router.delete( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { // "Leave" / remove my context const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return next(jsonError('You are not linked', 400)); + return next(CreateError.InvalidParameters('You are not linked')); } const login = activeContext.getGitHubIdentity().username; const id = activeContext.getGitHubIdentity().id; @@ -94,26 +96,25 @@ router.delete( await organization.removeMember(login, id); return res.json({ message: `Your ${login} account has been removed from ${organization.name}.`, - }); + }) as unknown as void; } catch (error) { console.warn(error); - return next(jsonError(error, 400)); + return next(CreateError.InvalidParameters(error)); } }) ); router.get( '/personalizedTeams', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { try { const organization = req.organization as Organization; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { - return res.json({ personalizedTeams: [] }); + return res.json({ personalizedTeams: [] }) as unknown as void; } const userAggregateContext = activeContext.aggregations; const maintainedTeams = new Set(); - const broadTeams = new Set(req.organization.broadAccessTeams); const userTeams = userAggregateContext.reduceOrganizationTeams( organization, await userAggregateContext.teams() @@ -131,21 +132,21 @@ router.get( }); return res.json({ personalizedTeams, - }); + }) as unknown as void; } catch (error) { - return next(jsonError(error, 400)); + return next(CreateError.InvalidParameters(error)); } }) ); -router.use('/repos', RouteRepos); -router.use('/teams', RouteTeams); +router.use('/repos', routeRepos); +router.use('/teams', routeTeams); const deployment = getCompanySpecificDeployment(); deployment?.routes?.api?.context?.organization?.index && deployment?.routes?.api?.context?.organization?.index(router); -router.use('*', (req, res, next) => { +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { return next(jsonError('no API or function available: client>organization', 404)); }); @@ -159,6 +160,7 @@ const toSanitizedUser = (user) => { avatar_url: user.avatar_url, }; }; + const toSanitizedOrg = (org) => { if (!org || !org.login) { return undefined; diff --git a/api/client/context/organization/repo.ts b/api/client/context/organization/repo.ts index e995886f8..14c337022 100644 --- a/api/client/context/organization/repo.ts +++ b/api/client/context/organization/repo.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { @@ -21,9 +21,9 @@ const router: Router = Router(); router.get( '/permissions', AddRepositoryPermissionsToRequest, - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const permissions = getContextualRepositoryPermissions(req); - return res.json(permissions); + return res.json(permissions) as unknown as void; }) ); @@ -33,7 +33,7 @@ const deployment = getCompanySpecificDeployment(); deployment?.routes?.api?.context?.organization?.repo && deployment?.routes?.api?.context?.organization?.repo(router); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError(`no API or ${req.method} function available for repo`, 404)); }); diff --git a/api/client/context/organization/repoForkUnlock.ts b/api/client/context/organization/repoForkUnlock.ts index 55fa0935e..1b7aadd81 100644 --- a/api/client/context/organization/repoForkUnlock.ts +++ b/api/client/context/organization/repoForkUnlock.ts @@ -3,24 +3,21 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../../middleware'; import { getRepositoryMetadataProvider, ReposAppRequest } from '../../../../interfaces'; import { Organization } from '../../../../business'; -import { - getContextualRepository, - getContextualRepositoryPermissions, -} from '../../../../middleware/github/repoPermissions'; +import { getContextualRepository } from '../../../../middleware/github/repoPermissions'; import { IndividualContext } from '../../../../business/user'; -import { ErrorHelper, getProviders } from '../../../../transitional'; -import NewRepositoryLockdownSystem from '../../../../features/newRepositories/newRepositoryLockdown'; +import { ErrorHelper, getProviders } from '../../../../lib/transitional'; +import NewRepositoryLockdownSystem from '../../../../business/features/newRepositories/newRepositoryLockdown'; const router: Router = Router(); router.use( - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const organization = req.organization as Organization; if (!organization.isNewRepositoryLockdownSystemEnabled()) { return next(jsonError('This endpoint is not available as configured for the organization', 400)); @@ -42,12 +39,13 @@ router.use( router.post( '/approve', - asyncHandler(async (req: ReposAppRequest, res, next) => { - const { operations } = getProviders(req); + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + const { insights, operations } = getProviders(req); const repository = getContextualRepository(req); const repositoryMetadataProvider = getRepositoryMetadataProvider(operations); const organization = repository.organization; const lockdownSystem = new NewRepositoryLockdownSystem({ + insights, operations, organization, repository, @@ -58,7 +56,7 @@ router.post( return res.json({ message: `Unlocked the ${repository.name} repo in the ${organization.name} org`, unlocked: true, - }); + }) as unknown as void; } catch (error) { return next( jsonError( @@ -70,7 +68,7 @@ router.post( }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError(`no API or ${req.method} function available for repo fork unlock`, 404)); }); diff --git a/api/client/context/organization/repos.ts b/api/client/context/organization/repos.ts index 851aa48c2..c124647a3 100644 --- a/api/client/context/organization/repos.ts +++ b/api/client/context/organization/repos.ts @@ -3,21 +3,22 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; + import { Repository } from '../../../../business'; import { jsonError } from '../../../../middleware'; import { setContextualRepository } from '../../../../middleware/github/repoPermissions'; -import { OrganizationMembershipState, ReposAppRequest } from '../../../../interfaces'; +import { OrganizationMembershipState, ReposAppRequest, VoidedExpressRoute } from '../../../../interfaces'; import { IndividualContext } from '../../../../business/user'; import { createRepositoryFromClient } from '../../newOrgRepo'; -import RouteContextualRepo from './repo'; +import routeContextualRepo from './repo'; const router: Router = Router(); -async function validateActiveMembership(req: ReposAppRequest, res, next) { +async function validateActiveMembership(req: ReposAppRequest, res: Response, next: NextFunction) { const { organization } = req; const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { @@ -33,11 +34,15 @@ async function validateActiveMembership(req: ReposAppRequest, res, next) { return next(); } -router.post('/', asyncHandler(validateActiveMembership), asyncHandler(createRepositoryFromClient)); +router.post( + '/', + asyncHandler(validateActiveMembership), + asyncHandler(createRepositoryFromClient as VoidedExpressRoute) +); router.use( '/:repoName', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const { repoName } = req.params; let repository: Repository = null; @@ -47,9 +52,9 @@ router.use( }) ); -router.use('/:repoName', RouteContextualRepo); +router.use('/:repoName', routeContextualRepo); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available for repos', 404)); }); diff --git a/api/client/context/organization/team.ts b/api/client/context/organization/team.ts index 8574d37fb..649de7635 100644 --- a/api/client/context/organization/team.ts +++ b/api/client/context/organization/team.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; -import { TeamJoinApprovalEntity } from '../../../../entities/teamJoinApproval/teamJoinApproval'; +import { TeamJoinApprovalEntity } from '../../../../business/entities/teamJoinApproval/teamJoinApproval'; import { ReposAppRequest, OrganizationMembershipState, @@ -24,8 +24,9 @@ import { import { submitTeamJoinRequest } from '../../../../routes/org/team'; import { postActionDecision, TeamApprovalDecision } from '../../../../routes/org/team/approval'; import { PermissionWorkflowEngine } from '../../../../routes/org/team/approvals'; -import { getProviders } from '../../../../transitional'; +import { CreateError, getProviders } from '../../../../lib/transitional'; import { IndividualContext } from '../../../../business/user'; +import getCompanySpecificDeployment from '../../../../middleware/companySpecificDeployment'; const router: Router = Router(); @@ -42,16 +43,16 @@ router.get( '/permissions', asyncHandler(AddTeamPermissionsToRequest), asyncHandler(AddTeamMembershipToRequest), - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const membership = getTeamMembershipFromRequest(req); const permissions = getTeamPermissionsFromRequest(req); - return res.json({ permissions, membership }); + return res.json({ permissions, membership }) as unknown as void; }) ); router.get( '/join/request', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { approvalProvider } = getProviders(req); const team = getContextualTeam(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; @@ -63,32 +64,49 @@ router.get( request = approvals.length > 0 ? approvals[0] : null; } const response: ITeamRequestJsonResponse = { request }; - return res.json(response); + return res.json(response) as unknown as void; }) ); router.post( '/join', asyncHandler(AddTeamMembershipToRequest), - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { try { const providers = getProviders(req); const { approvalProvider } = providers; const membership = getTeamMembershipFromRequest(req); if (!membership.isLinked) { - return res.json({ error: 'You have not linked your GitHub account to your corporate identity yet' }); + return res.json({ + error: 'You have not linked your GitHub account to your corporate identity yet', + }) as unknown as void; } if (membership.membershipState === OrganizationMembershipState.Active) { - return res.json({ error: 'You already have an active team membership' }); + return res.json({ error: 'You already have an active team membership' }) as unknown as void; } const team = getContextualTeam(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; + const companySpecific = getCompanySpecificDeployment(); + if (companySpecific?.middleware?.teamPermissions.beforeJoinRequest) { + try { + const optionalOutcome = await companySpecific.middleware.teamPermissions.beforeJoinRequest( + providers, + activeContext, + team + ); + if (optionalOutcome) { + return res.json(optionalOutcome) as unknown as void; + } + } catch (error) { + return next(error); + } + } // no point query currently implemented let approvals = await approvalProvider.queryPendingApprovalsForTeam(String(team.id)); approvals = approvals.filter((approval) => approval.corporateId === activeContext.corporateIdentity.id); const request = approvals.length > 0 ? approvals[0] : null; if (request) { - return res.json({ error: 'You already have a pending team join request' }); + return res.json({ error: 'You already have a pending team join request' }) as unknown as void; } // const justification = (req.body.justification || '') as string; @@ -102,7 +120,7 @@ router.post( correlationId, hostname ); - return res.json(outcome); + return res.json(outcome) as unknown as void; } catch (error) { return next(jsonError(error)); } @@ -112,21 +130,21 @@ router.post( router.post( '/join/approvals/:approvalId', asyncHandler(AddTeamPermissionsToRequest), - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { approvalId: id } = req.params; if (!id) { - return next(jsonError('invalid approval', 400)); + return next(CreateError.InvalidParameters('invalid approval')); } const permissions = getTeamPermissionsFromRequest(req); if (!permissions.allowAdministration) { - return next(jsonError('you do not have permission to administer this team', 401)); + return next(CreateError.NotAuthorized('you do not have permission to administer this team')); } const providers = getProviders(req); const { approvalProvider, operations } = providers; const team = getContextualTeam(req); const request = await approvalProvider.getApprovalEntity(id); if (String(request.teamId) !== String(team.id)) { - return next(jsonError('mismatch on team', 400)); + return next(CreateError.InvalidParameters('mismatch on team')); } const requestingUser = await operations.getAccountWithDetailsAndLink(request.thirdPartyId); const approvalPackage = { request, requestingUser, id }; @@ -146,7 +164,7 @@ router.post( decision = TeamApprovalDecision.Reopen; break; default: - return next(jsonError('invalid or no decision type', 400)); + return next(CreateError.InvalidParameters('invalid or no decision type')); } const teamBaseUrl = `/orgs/${team.organization.name}/teams/${team.slug}/`; // trailing? try { @@ -154,9 +172,9 @@ router.post( if (outcome.error) { throw outcome.error; } - return res.json(outcome); + return res.json(outcome) as unknown as void; } catch (outcomeError) { - return next(jsonError(outcomeError, 500)); + return next(CreateError.ServerError(outcomeError)); } }) ); @@ -164,21 +182,21 @@ router.post( router.get( '/join/approvals/:approvalId', asyncHandler(AddTeamPermissionsToRequest), - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { approvalId: id } = req.params; if (!id) { - return next(jsonError('invalid approval', 400)); + return next(CreateError.InvalidParameters('invalid approval')); } const permissions = getTeamPermissionsFromRequest(req); if (!permissions.allowAdministration) { - return next(jsonError('you do not have permission to administer this team', 401)); + return next(CreateError.NotAuthorized('you do not have permission to administer this team')); } const providers = getProviders(req); const { approvalProvider, graphProvider } = providers; const team = getContextualTeam(req); const request = await approvalProvider.getApprovalEntity(id); if (String(request.teamId) !== String(team.id)) { - return next(jsonError('mismatch on team', 400)); + return next(CreateError.InvalidParameters('mismatch on team')); } let management: IGraphEntry[] = null; if (request?.corporateId) { @@ -188,14 +206,14 @@ router.get( // we ignore any failure here, this is an optional value-add for now } } - return res.json({ approval: request, management }); + return res.json({ approval: request, management }) as unknown as void; }) ); router.get( '/join/approvals', asyncHandler(AddTeamPermissionsToRequest), - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { approvalProvider } = getProviders(req); const team = getContextualTeam(req); const permissions = getTeamPermissionsFromRequest(req); @@ -206,22 +224,22 @@ router.get( response.allowAdministration = permissions.allowAdministration; response.approvals = await approvalProvider.queryPendingApprovalsForTeam(String(team.id)); } - return res.json(response); + return res.json(response) as unknown as void; }) ); router.post( '/role/:login', asyncHandler(AddTeamPermissionsToRequest), - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { role } = req.body; const { login } = req.params; if (!login) { - return next(jsonError('invalid login', 400)); + return next(CreateError.InvalidParameters('invalid login')); } const permissions = getTeamPermissionsFromRequest(req); if (!permissions.allowAdministration) { - return next(jsonError('you do not have permission to administer this team', 401)); + return next(CreateError.NotAuthorized('you do not have permission to administer this team')); } const team = getContextualTeam(req); try { @@ -230,17 +248,21 @@ router.post( !currentRole || (currentRole as ITeamMembershipRoleState).state !== OrganizationMembershipState.Active ) { - return next(jsonError(`${login} is not currently a member of the team`, 400)); + return next(CreateError.InvalidParameters(`${login} is not currently a member of the team`)); } const response = await team.addMembership(login, { role }); - return res.json(response); + return res.json(response) as unknown as void; } catch (outcomeError) { - return next(jsonError(outcomeError, 500)); + return next(CreateError.ServerError(outcomeError)); } }) ); -router.use('*', (req, res, next) => { +const deployment = getCompanySpecificDeployment(); +deployment?.routes?.api?.context?.organization?.team && + deployment?.routes?.api?.context?.organization?.team(router); + +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available for contextual team', 404)); }); diff --git a/api/client/context/organization/teams.ts b/api/client/context/organization/teams.ts index 99781f31b..3cb9ffeea 100644 --- a/api/client/context/organization/teams.ts +++ b/api/client/context/organization/teams.ts @@ -3,8 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; + import { Team } from '../../../../business'; import { jsonError } from '../../../../middleware'; import { setContextualTeam } from '../../../../middleware/github/teamPermissions'; @@ -18,7 +19,7 @@ const router: Router = Router(); router.use( '/:teamSlug', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const { teamSlug } = req.params; let team: Team = null; @@ -35,7 +36,7 @@ router.use( router.use('/:teamSlug', RouteTeam); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available for repos', 404)); }); diff --git a/api/client/context/orgs.ts b/api/client/context/orgs.ts index fd242331f..962e43f44 100644 --- a/api/client/context/orgs.ts +++ b/api/client/context/orgs.ts @@ -15,7 +15,7 @@ export default asyncHandler(async (req: ReposAppRequest, res) => { member: [], admin: [], isLinked: false, - }); + }) as unknown as void; } const orgs = await activeContext.aggregations.getQueryCacheOrganizations(); const data = { @@ -33,5 +33,5 @@ export default asyncHandler(async (req: ReposAppRequest, res) => { }; }), }; - return res.json(data); + return res.json(data) as unknown as void; }); diff --git a/api/client/context/repos.ts b/api/client/context/repos.ts index e446dbda3..2af5ab598 100644 --- a/api/client/context/repos.ts +++ b/api/client/context/repos.ts @@ -3,19 +3,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; import asyncHandler from 'express-async-handler'; import { GitHubRepositoryPermission, ReposAppRequest } from '../../../interfaces'; import { IndividualContext } from '../../../business/user'; -export default asyncHandler(async (req: ReposAppRequest, res, next) => { +export default asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { try { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { return res.json({ isLinked: false, repositories: [], - }); + }) as unknown as void; } let permissions = await activeContext.aggregations.getQueryCacheRepositoryPermissions(); permissions = permissions.filter((perm) => { @@ -47,7 +48,7 @@ export default asyncHandler(async (req: ReposAppRequest, res, next) => { // TODO: would be nice for team permission for repos to also store the team slug in the query cache! }; }), - }); + }) as unknown as void; } catch (error) { return next(error); } diff --git a/api/client/context/sample.ts b/api/client/context/sample.ts index e957ab121..687377ea7 100644 --- a/api/client/context/sample.ts +++ b/api/client/context/sample.ts @@ -3,20 +3,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { sendLinkedAccountMail } from '../../../business/operations/link'; import { ReposAppRequest } from '../../../interfaces'; import { jsonError } from '../../../middleware'; -import { CreateError, getProviders } from '../../../transitional'; +import { CreateError, getProviders } from '../../../lib/transitional'; import { IndividualContext } from '../../../business/user'; const router: Router = Router(); router.get( '/:templateName', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const templateName = req.params.templateName as string; @@ -39,11 +39,11 @@ router.get( } catch (error) { return next(error); } - return res.json({ templateName }); + return res.json({ templateName }) as unknown as void; }) ); -router.use('*', (req: ReposAppRequest, res, next) => { +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { return next(jsonError('Contextual API or route not found within samples', 404)); }); diff --git a/api/client/context/settings.ts b/api/client/context/settings.ts new file mode 100644 index 000000000..86a72a256 --- /dev/null +++ b/api/client/context/settings.ts @@ -0,0 +1,48 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { NextFunction, Response, Router } from 'express'; +import asyncHandler from 'express-async-handler'; + +import { ReposAppRequest } from '../../../interfaces'; +import { CreateError, getProviders } from '../../../lib/transitional'; +import { getUserSettings } from '../../../middleware/business/userSettings'; + +import type { ReposAppRequestWithUserSettings } from '../../../interfaces/middleware'; + +const router: Router = Router(); + +router.use(asyncHandler(getUserSettings)); + +router.get( + '/', + asyncHandler(async (req: ReposAppRequestWithUserSettings, res: Response, next: NextFunction) => { + const { userSettings } = req; + return res.json(userSettings || {}) as unknown as any; + }) +); + +async function setPublicDataSharingValue( + sharingOptOn: boolean, + req: ReposAppRequestWithUserSettings, + res: Response, + next: NextFunction +) { + const { userSettings } = req; + const { userSettingsProvider } = getProviders(req); + userSettings.contributionShareOptIn = sharingOptOn; + await userSettingsProvider.updateUserSettings(userSettings); + return res.status(201).json(userSettings || {}) as unknown as any; +} + +// Actions as separate posts to keep the API simple +router.post('/publicDataSharing/optIn', asyncHandler(setPublicDataSharingValue.bind(null, true))); +router.post('/publicDataSharing/optOut', asyncHandler(setPublicDataSharingValue.bind(null, false))); + +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { + return next(CreateError.NotFound('Contextual API route not found: /settings')); +}); + +export default router; diff --git a/api/client/context/teams.ts b/api/client/context/teams.ts index 4ffc3405e..ad45b7a43 100644 --- a/api/client/context/teams.ts +++ b/api/client/context/teams.ts @@ -4,23 +4,24 @@ // import asyncHandler from 'express-async-handler'; +import { NextFunction, Response } from 'express'; import { ReposAppRequest, TeamJsonFormat } from '../../../interfaces'; import { IndividualContext } from '../../../business/user'; -export default asyncHandler(async (req: ReposAppRequest, res, next) => { +export default asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext.link) { return res.json({ isLinked: false, member: [], maintainer: [], - }); + }) as unknown as void; } const permissions = await activeContext.aggregations.getQueryCacheTeams(); return res.json({ isLinked: true, member: permissions.member.map((t) => t.asJson(TeamJsonFormat.Augmented)), maintainer: permissions.maintainer.map((t) => t.asJson(TeamJsonFormat.Augmented)), - }); + }) as unknown as void; }); diff --git a/api/client/index.ts b/api/client/index.ts index e1b4538b3..db0e86073 100644 --- a/api/client/index.ts +++ b/api/client/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { @@ -12,8 +12,9 @@ import { requireAccessTokenClient, setIdentity, jsonError, + requireAuthenticatedUserOrSignIn, } from '../../middleware'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; @@ -30,13 +31,19 @@ import routeNews from './news'; import routeCrossOrganizationPeople from './people'; import routeCrossOrganizationRepos from './repos'; import routeCrossOrganizationTeams from './teams'; +import routeUsers from './users'; const router: Router = Router(); -router.use((req: ReposAppRequest, res, next) => { +router.use((req: ReposAppRequest, res: Response, next: NextFunction) => { const { config } = getProviders(req); if (config?.features?.allowApiClient) { - return req.isAuthenticated() ? next() : next(jsonError('Session is not authenticated', 401)); + if (req.isAuthenticated()) { + return next(); + } else if (req.query.authenticate === 'session') { + return requireAuthenticatedUserOrSignIn(req, res, next); + } + return next(jsonError('Session is not authenticated', 401)); } return next(jsonError('Client API features unavailable', 403)); }); @@ -57,6 +64,7 @@ router.use('/signout', routeSession); router.use('/people', routeCrossOrganizationPeople); router.use('/repos', routeCrossOrganizationRepos); router.use('/teams', routeCrossOrganizationTeams); +router.use('/users', routeUsers); router.use('/news', routeNews); const dynamicStartupInstance = getCompanySpecificDeployment(); @@ -81,7 +89,7 @@ router.get('/', (req: ReposAppRequest, res) => { appService: config?.webServer?.appService?.name ? { name: config?.webServer?.appService?.name, - slot: config?.webServer?.appService?.slot, + slot: config?.webServer?.appService?.advanced?.slotType || config?.webServer?.appService?.slot, region: config?.webServer?.appService?.region, } : undefined, @@ -120,7 +128,7 @@ router.get('/', (req: ReposAppRequest, res) => { return res.send(JSON.stringify(data, null, 2)); }); -router.use((req, res, next) => { +router.use((req, res: Response, next: NextFunction) => { return next(jsonError('The resource or endpoint you are looking for is not there', 404)); }); diff --git a/api/client/linking.ts b/api/client/linking.ts index 918af1e7d..c3188b951 100644 --- a/api/client/linking.ts +++ b/api/client/linking.ts @@ -3,19 +3,19 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { IndividualContext } from '../../business/user'; import { jsonError } from '../../middleware'; -import { ErrorHelper, getProviders } from '../../transitional'; +import { ErrorHelper, getProviders } from '../../lib/transitional'; import { unlinkInteractive } from '../../routes/unlink'; import { interactiveLinkUser } from '../../routes/link'; import { ReposAppRequest } from '../../interfaces'; const router: Router = Router(); -async function validateLinkOk(req: ReposAppRequest, res, next) { +async function validateLinkOk(req: ReposAppRequest, res: Response, next: NextFunction) { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const providers = getProviders(req); const insights = providers.insights; @@ -91,7 +91,7 @@ async function validateLinkOk(req: ReposAppRequest, res, next) { } } -router.get('/banner', (req: ReposAppRequest, res, next) => { +router.get('/banner', (req: ReposAppRequest, res: Response, next: NextFunction) => { const { config } = getProviders(req); const offline = config?.github?.links?.provider?.linkingOfflineMessage; return res.json({ offline }); @@ -99,7 +99,7 @@ router.get('/banner', (req: ReposAppRequest, res, next) => { router.delete( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; return unlinkInteractive(true, activeContext, req, res, next); }) @@ -108,13 +108,13 @@ router.delete( router.post( '/', validateLinkOk, - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; return interactiveLinkUser(true, activeContext, req, res, next); }) ); -router.use('*', (req: ReposAppRequest, res, next) => { +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { return next(jsonError('API or route not found', 404)); }); diff --git a/api/client/newOrgRepo.ts b/api/client/newOrgRepo.ts index 280dd8879..0984312b3 100644 --- a/api/client/newOrgRepo.ts +++ b/api/client/newOrgRepo.ts @@ -3,19 +3,24 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import _ from 'lodash'; + +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import _ from 'lodash'; - -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { jsonError } from '../../middleware/jsonError'; import { IndividualContext } from '../../business/user'; import { Organization } from '../../business/organization'; import { CreateRepository, ICreateRepositoryApiResult, CreateRepositoryEntrypoint } from '../createRepo'; import { Team } from '../../business/team'; -import { GitHubRepositoryVisibility, GitHubTeamRole, ReposAppRequest } from '../../interfaces'; +import { + GitHubRepositoryVisibility, + GitHubTeamRole, + ReposAppRequest, + VoidedExpressRoute, +} from '../../interfaces'; // This file supports the client apps for creating repos. @@ -25,7 +30,7 @@ interface ILocalApiRequest extends ReposAppRequest { knownRequesterMailAddress?: string; } -router.get('/metadata', (req: ILocalApiRequest, res, next) => { +router.get('/metadata', (req: ILocalApiRequest, res: Response, next: NextFunction) => { try { const options = { projectType: req.query.projectType, @@ -40,12 +45,13 @@ router.get('/metadata', (req: ILocalApiRequest, res, next) => { router.get( '/personalizedTeams', - asyncHandler(async (req: ILocalApiRequest, res, next) => { + asyncHandler(async (req: ILocalApiRequest, res: Response, next: NextFunction) => { try { const organization = req.organization as Organization; const userAggregateContext = req.apiContext.aggregations; const maintainedTeams = new Set(); const broadTeams = new Set(req.organization.broadAccessTeams); + const openAccessTeams = new Set(req.organization.openAccessTeams); const userTeams = userAggregateContext.reduceOrganizationTeams( organization, await userAggregateContext.teams() @@ -57,6 +63,7 @@ router.get( const personalizedTeams = Array.from(combinedTeams.values()).map((combinedTeam) => { return { broad: broadTeams.has(Number(combinedTeam.id)), + isOpenAccessTeam: openAccessTeams.has(Number(combinedTeam.id)), description: combinedTeam.description, id: Number(combinedTeam.id), name: combinedTeam.name, @@ -67,7 +74,7 @@ router.get( }); return res.json({ personalizedTeams, - }); + }) as unknown as void; } catch (error) { return next(jsonError(error, 400)); } @@ -76,11 +83,12 @@ router.get( router.get( '/teams', - asyncHandler(async (req: ILocalApiRequest, res, next) => { + asyncHandler(async (req: ILocalApiRequest, res: Response, next: NextFunction) => { const providers = getProviders(req); const queryCache = providers.queryCache; const organization = req.organization as Organization; const broadTeams = new Set(organization.broadAccessTeams); + const openAccessTeams = new Set(req.organization.openAccessTeams); if (req.query.refresh === undefined && queryCache && queryCache.supportsTeams) { // Use the newer method in this case... const organizationTeams = await queryCache.organizationTeams(organization.id.toString()); @@ -91,9 +99,12 @@ router.get( if (broadTeams.has(Number(t.id))) { t['broad'] = true; } + if (openAccessTeams.has(Number(t.id))) { + t['openAccess'] = true; + } return t; }), - }); + }) as unknown as void; } // By default, allow a 30-second old list of teams. If the cached @@ -154,7 +165,7 @@ router.get( }) ); -export async function discoverUserIdentities(req: ReposAppRequest, res, next) { +export async function discoverUserIdentities(req: ReposAppRequest, res: Response, next: NextFunction) { const apiContext = req.apiContext as IndividualContext; const providers = getProviders(req); const mailAddressProvider = providers.mailAddressProvider; @@ -175,12 +186,16 @@ export async function discoverUserIdentities(req: ReposAppRequest, res, next) { return next(); } -router.post('/repo/:repo', asyncHandler(discoverUserIdentities), asyncHandler(createRepositoryFromClient)); +router.post( + '/repo/:repo', + asyncHandler(discoverUserIdentities), + asyncHandler(createRepositoryFromClient as VoidedExpressRoute) +); -export async function createRepositoryFromClient(req: ILocalApiRequest, res, next) { +export async function createRepositoryFromClient(req: ILocalApiRequest, res: Response, next: NextFunction) { const providers = getProviders(req); const { insights, diagnosticsDrop, customizedNewRepositoryLogic, graphProvider } = providers; - const individualContext = req.individualContext || req.apiContext; + const individualContext = req.watchdogContextOverride || req.individualContext || req.apiContext; const config = getProviders(req).config; const organization = (req.organization || (req as any).aeOrganization) as Organization; const existingRepoId = req.body.existingrepoid; diff --git a/api/client/newRepo.ts b/api/client/newRepo.ts index 26aca31e6..8d28cae1c 100644 --- a/api/client/newRepo.ts +++ b/api/client/newRepo.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { jsonError } from '../../middleware/jsonError'; import newOrgRepo from './newOrgRepo'; import { ReposAppRequest } from '../../interfaces'; -router.use('/org/:org', (req: ReposAppRequest, res, next) => { +router.use('/org/:org', (req: ReposAppRequest, res: Response, next: NextFunction) => { const orgName = req.params.org; const { operations } = getProviders(req); try { diff --git a/api/client/news.ts b/api/client/news.ts index b33739fa7..24cb920a0 100644 --- a/api/client/news.ts +++ b/api/client/news.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { ReposAppRequest } from '../../interfaces'; const router: Router = Router(); @@ -16,11 +16,11 @@ router.get( '/', asyncHandler(async (req: ReposAppRequest, res) => { const { config } = getProviders(req); - return res.json({ articles: config?.news?.all || [] }); + return res.json({ articles: config?.news?.all || [] }) as unknown as void; }) ); -router.use('*', (req: ReposAppRequest, res, next) => { +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { return next(jsonError('API or route not found within news', 404)); }); diff --git a/api/client/organization/annotations.ts b/api/client/organization/annotations.ts index 834e2c130..764ac8b63 100644 --- a/api/client/organization/annotations.ts +++ b/api/client/organization/annotations.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware/jsonError'; @@ -19,10 +19,12 @@ import { import { IOrganizationAnnotationChange, OrganizationAnnotation, -} from '../../../entities/organizationAnnotation'; -import { ErrorHelper, getProviders } from '../../../transitional'; + getOrganizationAnnotationRestrictedPropertyNames, +} from '../../../business/entities/organizationAnnotation'; +import { CreateError, ErrorHelper, getProviders } from '../../../lib/transitional'; import { IndividualContext } from '../../../business/user'; import { IProviders } from '../../../interfaces'; +import { ensureOrganizationProfileMiddleware } from '../../../middleware/github/ensureOrganizationProfile'; const router: Router = Router(); @@ -33,7 +35,7 @@ type IRequestWithOrganizationAnnotations = IReposAppRequestWithOrganizationManag router.use( '/', checkIsCorporateAdministrator, - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { const { organizationAnnotationsProvider } = getProviders(req); const { organization, organizationManagementType, organizationProfile } = req; const organizationId = @@ -53,24 +55,28 @@ router.use( router.get( '/', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { const { annotations } = req; // Limited redaction + const annotation = { ...annotations }; const isSystemAdministrator = await getIsCorporateAdministrator(req); - if (!isSystemAdministrator && annotations.administratorNotes) { - annotations.administratorNotes = '*****'; - } - if (!isSystemAdministrator && annotations?.history?.length > 0) { - delete annotations.history; + for (const propertyToRedact of getOrganizationAnnotationRestrictedPropertyNames(isSystemAdministrator)) { + delete annotation[propertyToRedact]; } return res.json({ isSystemAdministrator, - annotations, - }); + annotations: annotation, + }) as unknown as void; }) ); -async function ensureAnnotations(req: IRequestWithOrganizationAnnotations, res, next) { +router.use(ensureOrganizationProfileMiddleware); + +async function ensureAnnotations( + req: IRequestWithOrganizationAnnotations, + res: Response, + next: NextFunction +) { if (!req.annotations) { const { organizationAnnotationsProvider } = getProviders(req); try { @@ -80,7 +86,7 @@ async function ensureAnnotations(req: IRequestWithOrganizationAnnotations, res, await organizationAnnotationsProvider.insertAnnotations(annotations); req.annotations = annotations; } catch (error) { - return next(error); + return next(jsonError(error)); } } return next(); @@ -91,11 +97,11 @@ router.put('*', AuthorizeOnlyCorporateAdministrators, ensureAnnotations); router.put( '/', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { // No-op mostly, since ensureAnnotations precedes return res.json({ annotations: req.annotations, - }); + }) as unknown as void; }) ); @@ -127,17 +133,17 @@ function addChangeNote( router.put( '/property/:propertyName', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const changes: IOrganizationAnnotationChange[] = []; const newValue = req.body.value as string; if (!newValue) { - return next(jsonError('body.value required', 400)); + return next(CreateError.InvalidParameters('body.value required')); } if (typeof newValue !== 'string') { - return next(jsonError('body.value must be a string value', 400)); + return next(CreateError.InvalidParameters('body.value must be a string value')); } const propertyName = req.params.propertyName as string; const currentPropertyValue = annotations.properties[propertyName] || null; @@ -148,13 +154,13 @@ router.put( return res.json({ annotations, updated, - }); + }) as unknown as void; }) ); router.delete( '/property/:propertyName', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; @@ -162,7 +168,7 @@ router.delete( const propertyName = req.params.propertyName as string; const currentPropertyValue = annotations.properties[propertyName] || null; if (annotations.properties[propertyName] === undefined) { - return next(jsonError(`property ${propertyName} is not set`, 400)); + return next(CreateError.InvalidParameters(`property ${propertyName} is not set`)); } delete annotations.properties[propertyName]; addChangeNote( @@ -177,7 +183,7 @@ router.delete( return res.json({ annotations, updated, - }); + }) as unknown as void; }) ); @@ -185,14 +191,14 @@ router.delete( router.put( '/feature/:flag', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const changes: IOrganizationAnnotationChange[] = []; const flag = req.params.flag as string; if (annotations.features.includes(flag)) { - return next(jsonError(`The feature flag ${flag} is already present`, 400)); + return next(CreateError.InvalidParameters(`The feature flag ${flag} is already present`)); } annotations.features.push(flag); addChangeNote( @@ -207,20 +213,20 @@ router.put( return res.json({ annotations, updated, - }); + }) as unknown as void; }) ); router.delete( '/feature/:flag', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const changes: IOrganizationAnnotationChange[] = []; const flag = req.params.flag as string; if (!annotations.features.includes(flag)) { - return next(jsonError(`The feature flag ${flag} is not set`, 400)); + return next(CreateError.InvalidParameters(`The feature flag ${flag} is not set`)); } annotations.features = annotations.features.filter((f) => f !== flag); addChangeNote( @@ -235,7 +241,7 @@ router.delete( return res.json({ annotations, updated, - }); + }) as unknown as void; }) ); @@ -243,7 +249,7 @@ router.delete( router.patch( '/', - asyncHandler(async (req: IRequestWithOrganizationAnnotations, res, next) => { + asyncHandler(async (req: IRequestWithOrganizationAnnotations, res: Response, next: NextFunction) => { const { annotations } = req; const providers = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; @@ -267,7 +273,7 @@ router.patch( return res.json({ annotations, updated, - }); + }) as unknown as void; }) ); @@ -290,7 +296,7 @@ async function applyPatch( // features, properties // flag -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available within the organization annotations route', 404)); }); diff --git a/api/client/organization/index.ts b/api/client/organization/index.ts index 3acf46701..6cc49a116 100644 --- a/api/client/organization/index.ts +++ b/api/client/organization/index.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { ReposAppRequest } from '../../../interfaces'; import { jsonError } from '../../../middleware'; import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; -import { getProviders } from '../../../transitional'; +import { getProviders } from '../../../lib/transitional'; import { blockIfUnmanagedOrganization, IReposAppRequestWithOrganizationManagementType, @@ -32,14 +32,14 @@ router.get( asyncHandler(async (req: IReposAppRequestWithOrganizationManagementType, res) => { const { organization, organizationProfile, organizationManagementType } = req; if (organizationManagementType === OrganizationManagementType.Unmanaged) { - return res.json(organizationProfile); + return res.json(organizationProfile) as unknown as void; } const entity = organization.getEntity(); if (entity) { - return res.json(entity); + return res.json(entity) as unknown as void; } const details = await organization.getDetails(); - return res.json(details); + return res.json(details) as unknown as void; }) ); @@ -63,19 +63,21 @@ asClientJson() { */ router.get( '/', - asyncHandler(async (req: IReposAppRequestWithOrganizationManagementType, res, next) => { - const { organization, organizationProfile, organizationManagementType } = req; - if (organizationManagementType === OrganizationManagementType.Unmanaged) { + asyncHandler( + async (req: IReposAppRequestWithOrganizationManagementType, res: Response, next: NextFunction) => { + const { organization, organizationProfile, organizationManagementType } = req; + if (organizationManagementType === OrganizationManagementType.Unmanaged) { + return res.json({ + managementType: req.organizationManagementType, + id: organizationProfile.id, + }) as unknown as void; + } return res.json({ managementType: req.organizationManagementType, - id: organizationProfile.id, - }); + ...organization.asClientJson(), + }) as unknown as void; } - return res.json({ - managementType: req.organizationManagementType, - ...organization.asClientJson(), - }); - }) + ) ); router.use('/annotations', routeAnnotations); @@ -93,7 +95,7 @@ router.get('/newRepoBanner', (req: ReposAppRequest, res) => { return res.json({ newRepositoriesOffline }); }); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available', 404)); }); diff --git a/api/client/organization/newRepoMetadata.ts b/api/client/organization/newRepoMetadata.ts index 4761fbb8e..4133cb2b5 100644 --- a/api/client/organization/newRepoMetadata.ts +++ b/api/client/organization/newRepoMetadata.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware/jsonError'; @@ -13,7 +13,7 @@ const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const metadata = organization.getRepositoryCreateMetadata(); res.json(metadata); @@ -22,7 +22,7 @@ router.get( router.get( '/byProjectReleaseType', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const options = { projectType: req.query.projectType, @@ -32,7 +32,7 @@ router.get( }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available within this path', 404)); }); diff --git a/api/client/organization/people.ts b/api/client/organization/people.ts index f8f39743a..5d75ab5c4 100644 --- a/api/client/organization/people.ts +++ b/api/client/organization/people.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware'; -import { getProviders } from '../../../transitional'; +import { getProviders } from '../../../lib/transitional'; import LeakyLocalCache, { getLinksLightCache } from '../leakyLocalCache'; import JsonPager from '../jsonPager'; import { @@ -118,7 +118,7 @@ export async function equivalentLegacyPeopleSearch(req: ReposAppRequest, options router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const pager = new JsonPager(req, res); try { const searcher = await equivalentLegacyPeopleSearch(req); @@ -142,7 +142,7 @@ router.get( }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available within this people list', 404)); }); diff --git a/api/client/organization/repo.ts b/api/client/organization/repo.ts index 4ad38e634..635105e2d 100644 --- a/api/client/organization/repo.ts +++ b/api/client/organization/repo.ts @@ -3,36 +3,32 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware'; -import { ErrorHelper, getProviders } from '../../../transitional'; -import { Repository } from '../../../business'; +import { CreateError, ErrorHelper, getProviders } from '../../../lib/transitional'; import { IndividualContext } from '../../../business/user'; -import NewRepositoryLockdownSystem from '../../../features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../../../business/features/newRepositories/newRepositoryLockdown'; import { AddRepositoryPermissionsToRequest, getContextualRepositoryPermissions, } from '../../../middleware/github/repoPermissions'; -import { renameRepositoryDefaultBranchEndToEnd } from '../../../routes/org/repos'; import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; import RouteRepoPermissions from './repoPermissions'; import { - ReposAppRequest, LocalApiRepoAction, getRepositoryMetadataProvider, NoCacheNoBackground, + GitHubRepositoryVisibility, } from '../../../interfaces'; +import { RequestWithRepo } from '../../../middleware/business/repository'; -type RequestWithRepo = ReposAppRequest & { - repository: Repository; -}; - -enum ArchivalAction { +enum RepositoryChangeAction { Archive, UnArchive, + Privatize, } const router: Router = Router(); @@ -44,15 +40,15 @@ router.use('/permissions', RouteRepoPermissions); router.get( '/', - asyncHandler(async (req: RequestWithRepo, res, next) => { + asyncHandler(async (req: RequestWithRepo, res: Response, next: NextFunction) => { const { repository } = req; try { await repository.getDetails({ backgroundRefresh: false }); const clone = Object.assign({}, repository.getEntity()); - delete clone.temp_clone_token; // never share this back - delete clone.cost; + delete (clone as any).temp_clone_token; // never share this back + delete (clone as any).cost; - return res.json(repository.getEntity()); + return res.json(repository.getEntity()) as unknown as void; } catch (repoError) { if (ErrorHelper.IsNotFound(repoError)) { // // Attempt fallback by ID (?) @@ -64,7 +60,7 @@ router.get( router.get( '/exists', - asyncHandler(async (req: RequestWithRepo, res, next) => { + asyncHandler(async (req: RequestWithRepo, res: Response, next: NextFunction) => { let exists = false; let name: string = undefined; const { repository } = req; @@ -81,58 +77,85 @@ router.get( } } } catch (repoError) {} - return res.json({ exists, name }); + return res.json({ exists, name }) as unknown as void; }) ); -router.patch( - '/renameDefaultBranch', - asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: RequestWithRepo, res, next) { - const providers = getProviders(req); - const activeContext = (req.individualContext || req.apiContext) as IndividualContext; - const repoPermissions = getContextualRepositoryPermissions(req); - const targetBranchName = req.body.default_branch; +router.get( + '/archived', + asyncHandler(async (req: RequestWithRepo, res: Response, next: NextFunction) => { const { repository } = req; try { - const result = await renameRepositoryDefaultBranchEndToEnd( - providers, - activeContext, - repoPermissions, - repository, - targetBranchName, - true /* wait for refresh before sending response */ - ); - return res.json(result); + await repository.getDetails(); + const data = { + archivedAt: null, + }; + if (repository?.archived) { + const archivedAt = await repository.getArchivedAt(); + if (archivedAt) { + data.archivedAt = archivedAt.toISOString(); + } + } + return res.json(data) as unknown as void; } catch (error) { - return next(jsonError(error)); + return next(error); } }) ); +router.post( + '/privatize', + asyncHandler(AddRepositoryPermissionsToRequest), + asyncHandler(RepositoryStateChangeHandler.bind(null, RepositoryChangeAction.Privatize)) +); router.post( '/archive', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(archiveUnArchiveRepositoryHandler.bind(null, ArchivalAction.Archive)) + asyncHandler(RepositoryStateChangeHandler.bind(null, RepositoryChangeAction.Archive)) ); router.post( '/unarchive', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(archiveUnArchiveRepositoryHandler.bind(null, ArchivalAction.UnArchive)) + asyncHandler(RepositoryStateChangeHandler.bind(null, RepositoryChangeAction.UnArchive)) ); -async function archiveUnArchiveRepositoryHandler(action: ArchivalAction, req: RequestWithRepo, res, next) { +async function RepositoryStateChangeHandler( + action: RepositoryChangeAction, + req: RequestWithRepo, + res: Response, + next: NextFunction +) { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const providers = getProviders(req); const { insights } = providers; const repoPermissions = getContextualRepositoryPermissions(req); - const phrase = action === ArchivalAction.Archive ? 'archive' : 'unarchive'; + let phrase: string = null; + let insightsPrefix: string = null; + let localAction: LocalApiRepoAction = null; + switch (action) { + case RepositoryChangeAction.Archive: + phrase = 'archive'; + insightsPrefix = 'ArchiveRepo'; + localAction = LocalApiRepoAction.Archive; + break; + case RepositoryChangeAction.UnArchive: + phrase = 'unarchive'; + insightsPrefix = 'UnArchiveRepo'; + localAction = LocalApiRepoAction.UnArchive; + break; + case RepositoryChangeAction.Privatize: + phrase = 'privatize'; + insightsPrefix = 'PrivatizeRepo'; + localAction = LocalApiRepoAction.Privatize; + break; + default: + return next(jsonError('Invalid action', 400)); + } const completedPhrase = `${phrase}d`; if (!repoPermissions.allowAdministration) { return next(jsonError(`You do not have permission to ${phrase} this repo`, 403)); } - const insightsPrefix = `${action === ArchivalAction.UnArchive ? 'Un' : ''}ArchiveRepo`; const { repository } = req; try { insights?.trackEvent({ @@ -147,16 +170,28 @@ async function archiveUnArchiveRepositoryHandler(action: ArchivalAction, req: Re const currentRepositoryState = deployment?.features?.repositoryActions?.getCurrentRepositoryState ? await deployment.features.repositoryActions.getCurrentRepositoryState(providers, repository) : null; - await (action === ArchivalAction.Archive ? repository.archive() : repository.unarchive()); + switch (action) { + case RepositoryChangeAction.Archive: { + await repository.archive(); + break; + } + case RepositoryChangeAction.UnArchive: { + await repository.unarchive(); + break; + } + case RepositoryChangeAction.Privatize: { + await repository.update({ + visibility: GitHubRepositoryVisibility.Private, + }); + break; + } + default: { + return next(CreateError.InvalidParameters('Invalid action')); + } + } if (deployment?.features?.repositoryActions?.sendActionReceipt) { deployment.features.repositoryActions - .sendActionReceipt( - providers, - activeContext, - repository, - action === ArchivalAction.Archive ? LocalApiRepoAction.Archive : LocalApiRepoAction.UnArchive, - currentRepositoryState - ) + .sendActionReceipt(providers, activeContext, repository, localAction, currentRepositoryState) .then((ok) => {}) .catch(() => {}); } @@ -200,7 +235,7 @@ async function archiveUnArchiveRepositoryHandler(action: ArchivalAction, req: Re router.delete( '/', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: RequestWithRepo, res, next) { + asyncHandler(async function (req: RequestWithRepo, res: Response, next: NextFunction) { // NOTE: duplicated code from /routes/org/repos.ts const providers = getProviders(req); const { insights } = providers; @@ -250,7 +285,7 @@ router.delete( }); return res.json({ message: `You deleted: ${repository.full_name}`, - }); + }) as unknown as void; } catch (error) { insights?.trackException({ exception: error }); insights?.trackEvent({ @@ -295,6 +330,7 @@ router.delete( const { operations } = getProviders(req); const repositoryMetadataProvider = getRepositoryMetadataProvider(operations); const lockdownSystem = new NewRepositoryLockdownSystem({ + insights, operations, organization, repository, @@ -306,11 +342,11 @@ router.delete( ); return res.json({ message: `You deleted your repo, ${repository.full_name}.`, - }); + }) as unknown as void; }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { console.warn(req.baseUrl); return next(jsonError('no API or function available within this specific repo', 404)); }); diff --git a/api/client/organization/repoPermissions.ts b/api/client/organization/repoPermissions.ts index b479e8ab8..f5eefaba7 100644 --- a/api/client/organization/repoPermissions.ts +++ b/api/client/organization/repoPermissions.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware/jsonError'; @@ -19,7 +19,7 @@ const router: Router = Router(); router.get( '/', - asyncHandler(async (req: RequestWithRepo, res, next) => { + asyncHandler(async (req: RequestWithRepo, res: Response, next: NextFunction) => { const { repository, organization } = req; try { const teamPermissions = await repository.getTeamPermissions(); @@ -38,7 +38,7 @@ router.get( collaborators: collaborators.map((c) => c.asJson()), outsideCollaborators: outsideCollaborators.map((oc) => oc.asJson()), memberCollaborators: memberCollaborators.map((oc) => oc.asJson()), - }); + }) as unknown as void; } catch (error) { return next(jsonError(error)); } diff --git a/api/client/organization/repos.ts b/api/client/organization/repos.ts index 499ec7ac5..2a32f163b 100644 --- a/api/client/organization/repos.ts +++ b/api/client/organization/repos.ts @@ -3,23 +3,25 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../../middleware'; -import { getProviders } from '../../../transitional'; +import { CreateError, getProviders } from '../../../lib/transitional'; import { Repository } from '../../../business'; -import RouteRepo from './repo'; import JsonPager from '../jsonPager'; import { ReposAppRequest, IProviders } from '../../../interfaces'; -import { sortRepositoriesByNameCaseInsensitive } from '../../../utils'; +import { sortRepositoriesByNameCaseInsensitive } from '../../../lib/utils'; +import { apiMiddlewareRepositoriesToRepository } from '../../../middleware/business/repository'; + +import routeRepo from './repo'; const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const providers = getProviders(req); const pager = new JsonPager(req, res); @@ -236,21 +238,10 @@ export async function searchRepos( // --- End of search reimplementation --- -router.use( - '/:repoName', - asyncHandler(async (req: ReposAppRequest, res, next) => { - const { organization } = req; - const { repoName } = req.params; - // does not confirm the name - (req as any).repository = organization.repository(repoName); - return next(); - }) -); - -router.use('/:repoName', RouteRepo); +router.use('/:repoName', asyncHandler(apiMiddlewareRepositoriesToRepository), routeRepo); -router.use('*', (req, res, next) => { - return next(jsonError('no API or function available within this repos endpoint', 404)); +router.use('*', (req, res: Response, next: NextFunction) => { + return next(CreateError.NotFound('no API or function available within org/repos endpoint')); }); export default router; diff --git a/api/client/organization/team.ts b/api/client/organization/team.ts index 20d5925a3..73e44e323 100644 --- a/api/client/organization/team.ts +++ b/api/client/organization/team.ts @@ -3,33 +3,46 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { getContextualTeam } from '../../../middleware/github/teamPermissions'; import { jsonError } from '../../../middleware'; -import { getProviders } from '../../../transitional'; +import { getProviders } from '../../../lib/transitional'; import JsonPager from '../jsonPager'; import { getLinksLightCache } from '../leakyLocalCache'; import { equivalentLegacyPeopleSearch } from './people'; import { TeamRepositoryPermission, OrganizationMember, corporateLinkToJson } from '../../../business'; import { ReposAppRequest, TeamJsonFormat, NoCacheNoBackground, ICorporateLink } from '../../../interfaces'; -import { sortRepositoriesByNameCaseInsensitive } from '../../../utils'; +import { sortRepositoriesByNameCaseInsensitive } from '../../../lib/utils'; +import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + const providers = getProviders(req); const team = getContextualTeam(req); - return res.json(team.asJson(TeamJsonFormat.Augmented /* includes corporateMetadata */)); + const format = TeamJsonFormat.Augmented; // includes corporateMetadata + let json = team.asJson(format); + const companySpecific = getCompanySpecificDeployment(); + if (companySpecific?.features?.augmentApiMetadata?.augmentTeamClientJson) { + json = await companySpecific.features.augmentApiMetadata.augmentTeamClientJson( + providers, + team, + json, + format + ); + } + return res.json(json) as unknown as void; }) ); router.get( '/repos', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { try { const forceRefresh = !!req.query.refresh; const pager = new JsonPager(req, res); @@ -56,7 +69,7 @@ router.get( router.get( '/members', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { try { const forceRefresh = !!req.query.refresh; const team = getContextualTeam(req); @@ -84,7 +97,7 @@ router.get( router.get( '/maintainers', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); try { const forceRefresh = !!req.query.refresh; @@ -108,14 +121,14 @@ router.get( link: corporateLinkToJson(ls.get(Number(maintainer.id))), }; }) - ); + ) as unknown as void; } catch (error) { return next(error); } }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available for this specific team', 404)); }); diff --git a/api/client/organization/teams.ts b/api/client/organization/teams.ts index eebde0d51..b69b82c84 100644 --- a/api/client/organization/teams.ts +++ b/api/client/organization/teams.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Organization } from '../../../business/organization'; @@ -24,7 +24,7 @@ const leakyLocalCache = new LeakyLocalCache(); router.use( '/:teamSlug', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { organization } = req; const { teamSlug } = req.params; let team: Team = null; @@ -61,15 +61,19 @@ async function getTeamsForOrganization( router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { return await getClientApiOrganizationTeamsResponse(req, res, next); }) ); -export async function getClientApiOrganizationTeamsResponse(req: ReposAppRequest, res, next) { +export async function getClientApiOrganizationTeamsResponse( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { const organization = (req.organization || (req as any).aeOrganization) as Organization; if (!organization) { - return next(jsonError('No available organization'), 400); + return next(jsonError('No available organization', 400)); } const pager = new JsonPager(req, res); const q: string = (req.query.q ? (req.query.q as string) : null) || ''; @@ -101,7 +105,7 @@ export async function getClientApiOrganizationTeamsResponse(req: ReposAppRequest } } -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available within this team', 404)); }); diff --git a/api/client/organizations.ts b/api/client/organizations.ts index fac7fcafc..2c26e165c 100644 --- a/api/client/organizations.ts +++ b/api/client/organizations.ts @@ -3,41 +3,41 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; +import throat from 'throat'; -import memoryCache from 'memory-cache'; - -import { jsonError } from '../../middleware'; -import { CreateError, ErrorHelper, getProviders } from '../../transitional'; +import { getIsCorporateAdministrator, jsonError } from '../../middleware'; +import { CreateError, getProviders } from '../../lib/transitional'; import { ReposAppRequest } from '../../interfaces'; import RouteOrganization from './organization'; +import { apiMiddlewareOrganizationsToOrganization } from '../../middleware/business/organization'; +import type { GitHubOrganizationResponseSanitized } from '../../business'; import { - IReposAppRequestWithOrganizationManagementType, - OrganizationManagementType, -} from '../../middleware/business/organization'; - -import { IGitHubOrganizationResponse } from '../../business'; -import { OrganizationAnnotation } from '../../entities/organizationAnnotation'; + OrganizationAnnotation, + OrganizationAnnotationProperty, + getOrganizationAnnotationRestrictedPropertyNames, +} from '../../business/entities/organizationAnnotation'; +import { getOrganizationProfileViaMemoryCache } from '../../middleware/github/ensureOrganizationProfile'; const router: Router = Router(); -type HighlightedOrganization = { - profile: IGitHubOrganizationResponse; +export type OrganizationAnnotationPair = { + profile: GitHubOrganizationResponseSanitized; annotations: OrganizationAnnotation; }; router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); try { const orgs = operations.getOrganizations(); const dd = orgs.map((org) => { return org.asClientJson(); }); - return res.json(dd); + return res.json(dd) as unknown as void; } catch (error) { throw jsonError(error, 400); } @@ -46,39 +46,86 @@ router.get( router.get( '/annotations', - asyncHandler(async (req: ReposAppRequest, res, next) => { - const { operations, organizationAnnotationsProvider } = getProviders(req); - const cacheTimeMs = 1000 * 60 * 60 * 24; + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + const providers = getProviders(req); + const { organizationAnnotationsProvider } = providers; + const projectionQuery = typeof req.query.projection === 'string' ? req.query.projection : undefined; + const isSystemAdministrator = await getIsCorporateAdministrator(req); + // governance filter: a specific value or unset cohort + const governance = + typeof req.query.governance === 'string' ? req.query.governance?.toLowerCase() : undefined; + const filterByGovernance = governance !== undefined; try { - const highlights: HighlightedOrganization[] = []; - const annotations = await organizationAnnotationsProvider.getAllAnnotations(); - for (const annotation of annotations) { + const highlights: OrganizationAnnotationPair[] = []; + let annotations = await organizationAnnotationsProvider.getAllAnnotations(); + if (filterByGovernance) { + annotations = annotations.filter((annotation) => { + const value = annotation?.getProperty(OrganizationAnnotationProperty.Governance); + return governance ? value === governance : !value; + }); + } + const getAnnotationProfile = async (annotation: OrganizationAnnotation) => { try { - const key = `org:profile:${annotation.organizationId}`; - let profile = memoryCache.get(key) as IGitHubOrganizationResponse; - if (!profile) { - const details = await operations.getOrganizationProfileById(Number(annotation.organizationId)); - details.cost && delete details.cost; - details.headers && delete details.headers; - profile = details; - memoryCache.put(key, details, cacheTimeMs); - } - const scrubbedAnnotations = { ...annotation }; - delete scrubbedAnnotations.administratorNotes; - delete scrubbedAnnotations.history; + const profile = await getOrganizationProfileViaMemoryCache(providers, annotation.organizationId); highlights.push({ profile, - annotations: scrubbedAnnotations as OrganizationAnnotation, + annotations: annotation, }); } catch (error) { // we ignore any individual resolution error } + }; + const projections = projectionQuery?.split(','); + if (projections?.length > 0) { + const propertiesToRedact = getOrganizationAnnotationRestrictedPropertyNames(isSystemAdministrator); + if (projections.some((p) => propertiesToRedact.includes(p))) { + throw CreateError.InvalidParameters( + `One or more of the requested projections are not authorized for the current user` + ); + } + } + const parallelRequests = 6; + const throttle = throat(parallelRequests); + await Promise.all(annotations.map((annotation) => throttle(() => getAnnotationProfile(annotation)))); + if (projectionQuery) { + if (projections.length > 1 && !projections.includes('login')) { + throw CreateError.InvalidParameters('When using multiple projections, login must be included'); + } + let projected = highlights.map((highlight) => { + const profile = highlight.profile; + const annotations = highlight.annotations; + const result = {}; + for (const p of projections) { + let value = null; + if (profile[p]) { + value = result[p] = profile[p]; + } else if (annotations?.getProperty(p)) { + value = result[p] = annotations.getProperty(p); + } else if (annotations?.hasFeature(p)) { + value = result[p] = true; + } + if (projections.length === 1) { + return value; + } + } + return result; + }); + if (projections.length === 1 && projected.length >= 1 && typeof projected[0] === 'string') { + projected = projected.sort((a, b) => { + return a.localeCompare(b); + }); + } else if (projections.length > 1) { + projected = projected.sort((a, b) => { + return a['login'].localeCompare(b['login']); + }); + } + return res.json(projected) as unknown as void; } return res.json({ highlights: highlights.sort((a, b) => { return a.profile.login.localeCompare(b.profile.login); }), - }); + }) as unknown as void; } catch (error) { throw jsonError(error, 400); } @@ -87,7 +134,7 @@ router.get( router.get( '/list.txt', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); try { const orgs = operations.getOrganizations(); @@ -102,46 +149,10 @@ router.get( }) ); -router.use( - '/:orgName', - asyncHandler(async (req: IReposAppRequestWithOrganizationManagementType, res, next) => { - const { operations } = getProviders(req); - const { orgName } = req.params; - req.organizationName = orgName; - try { - const org = operations.getOrganization(orgName); - if (org) { - req.organizationManagementType = OrganizationManagementType.Managed; - req.organization = org; - return next(); - } - } catch (orgNotFoundError) { - if (!ErrorHelper.IsNotFound(orgNotFoundError)) { - return next(orgNotFoundError); - } - } - try { - const org = operations.getUncontrolledOrganization(orgName); - const details = await org.getDetails(); - details.cost && delete details.cost; - details.headers && delete details.headers; - req.organizationProfile = details; - } catch (orgProfileError) { - if (ErrorHelper.IsNotFound(orgProfileError)) { - return next(CreateError.NotFound(`The organization ${orgName} does not exist`)); - } else { - return next(orgProfileError); - } - } - req.organizationManagementType = OrganizationManagementType.Unmanaged; - return next(); - }) -); - -router.use('/:orgName', RouteOrganization); +router.use('/:orgName', asyncHandler(apiMiddlewareOrganizationsToOrganization), RouteOrganization); -router.use('*', (req: ReposAppRequest, res, next) => { - return next(jsonError('orgs API not found', 404)); +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { + return next(CreateError.NotFound('orgs API not found')); }); export default router; diff --git a/api/client/people.ts b/api/client/people.ts index c0a2fc12c..41b30e959 100644 --- a/api/client/people.ts +++ b/api/client/people.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { corporateLinkToJson } from '../../business'; import { jsonError } from '../../middleware'; -import { ICorporateLink, ReposAppRequest } from '../../interfaces'; +import { type GitHubSimpleAccount, type ICorporateLink, ReposAppRequest } from '../../interfaces'; import JsonPager from './jsonPager'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import RouteGetPerson from './person'; +import { getPerson as routeGetPerson } from './person'; import { equivalentLegacyPeopleSearch } from './peopleSearch'; const router: Router = Router(); @@ -20,34 +20,28 @@ const router: Router = Router(); const deployment = getCompanySpecificDeployment(); deployment?.routes?.api?.people && deployment.routes.api.people(router); -interface ISimpleAccount { - login: string; - avatar_url: string; - id: number; -} - export interface ICrossOrganizationMemberResponse { - account: ISimpleAccount; + account: GitHubSimpleAccount; link?: ICorporateLink; organizations: string[]; } export interface ICrossOrganizationSearchedMember { id: number; - account: ISimpleAccount; + account: GitHubSimpleAccount; link?: ICorporateLink; orgs: IOrganizationMembershipAccount; } interface IOrganizationMembershipAccount { - [id: string]: ISimpleAccount; + [id: string]: GitHubSimpleAccount; } -router.get('/:login', RouteGetPerson); +router.get('/:login', routeGetPerson); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const pager = new JsonPager(req, res); try { const searcher = await equivalentLegacyPeopleSearch(req); @@ -73,7 +67,7 @@ router.get( }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available within this cross-organization people list', 404)); }); diff --git a/api/client/peopleSearch.ts b/api/client/peopleSearch.ts index 1c55e6d16..82ae5c27f 100644 --- a/api/client/peopleSearch.ts +++ b/api/client/peopleSearch.ts @@ -5,7 +5,7 @@ import { Organization, MemberSearch, ICrossOrganizationMembersResult, Operations } from '../../business'; import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import LeakyLocalCache, { getLinksLightCache } from './leakyLocalCache'; // BAD PRACTICE: leaky local cache diff --git a/api/client/person.ts b/api/client/person.ts index 913658945..61369456a 100644 --- a/api/client/person.ts +++ b/api/client/person.ts @@ -4,13 +4,15 @@ // import asyncHandler from 'express-async-handler'; +import { NextFunction, Response } from 'express'; + import { ReposAppRequest, AccountJsonFormat } from '../../interfaces'; import { IGraphEntry } from '../../lib/graphProvider'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../transitional'; +import { CreateError, ErrorHelper, getProviders } from '../../lib/transitional'; -export default asyncHandler(async (req: ReposAppRequest, res, next) => { +const getPerson = asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const providers = getProviders(req); const { operations, queryCache, graphProvider } = providers; const login = req.params.login as string; @@ -70,8 +72,14 @@ export default asyncHandler(async (req: ReposAppRequest, res, next) => { json, { corporateEntry } ); - return res.json(combined); + return res.json(combined) as unknown as void; } catch (error) { - return next(jsonError(`login ${login} error: ${error}`, 500)); + return next( + ErrorHelper.IsNotFound(error) + ? error + : CreateError.InvalidParameters(`Invalid issue retrieving user ${login}: ${error.message}`) + ); } }); + +export { getPerson }; diff --git a/api/client/repos.ts b/api/client/repos.ts index ae426e7df..ca1675f2a 100644 --- a/api/client/repos.ts +++ b/api/client/repos.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Repository } from '../../business'; import { ReposAppRequest } from '../../interfaces'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import JsonPager from './jsonPager'; import { RepositorySearchSortOrder, searchRepos } from './organization/repos'; @@ -17,7 +17,7 @@ const router: Router = Router(); router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const providers = getProviders(req); const pager = new JsonPager(req, res); const searchOptions = { @@ -39,7 +39,7 @@ router.get( }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available within this cross-organization repps list', 404)); }); diff --git a/api/client/session.ts b/api/client/session.ts index e0b128e99..35f98dd2a 100644 --- a/api/client/session.ts +++ b/api/client/session.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import { jsonError } from '../../middleware/jsonError'; import { IAppSession, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; const router: Router = Router(); @@ -42,7 +42,7 @@ router.post('/github', (req: ReposAppRequest, res) => { res.end(); }); -router.use('*', (req: ReposAppRequest, res, next) => { +router.use('*', (req: ReposAppRequest, res: Response, next: NextFunction) => { return next(jsonError('API or route not found', 404)); }); diff --git a/api/client/teams.ts b/api/client/teams.ts index b2c863291..089fa240b 100644 --- a/api/client/teams.ts +++ b/api/client/teams.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { Operations, Team } from '../../business'; @@ -13,7 +13,7 @@ import { TeamJsonFormat, } from '../../interfaces'; import { jsonError } from '../../middleware'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import JsonPager from './jsonPager'; const router: Router = Router(); @@ -40,7 +40,7 @@ async function getCrossOrganizationTeams(operations: Operations): Promise { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const pager = new JsonPager(req, res); const q: string = (req.query.q ? (req.query.q as string) : null) || ''; @@ -71,7 +71,7 @@ router.get( }) ); -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('no API or function available within this cross-organization teams list', 404)); }); diff --git a/api/client/users.ts b/api/client/users.ts new file mode 100644 index 000000000..940789452 --- /dev/null +++ b/api/client/users.ts @@ -0,0 +1,35 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { NextFunction, Response, Router } from 'express'; +import asyncHandler from 'express-async-handler'; + +import { ReposAppRequest, AccountJsonFormat } from '../../interfaces'; +import { CreateError, getProviders } from '../../lib/transitional'; + +const router: Router = Router(); + +router.get( + '/:login', + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + const { operations } = getProviders(req); + const login = req.params.login as string; + try { + if (!login) { + throw CreateError.ParameterRequired('login'); + } + const accountInfo = await operations.getAccountByUsername(login); + return res.json(accountInfo.asJson(AccountJsonFormat.GitHubExtended)) as any as void; + } catch (error) { + return next(error); + } + }) +); + +router.use('*', (req, res: Response, next: NextFunction) => { + return next(CreateError.NotFound('/users: no API found')); +}); + +export default router; diff --git a/api/createRepo.ts b/api/createRepo.ts index c986bc293..585949c25 100644 --- a/api/createRepo.ts +++ b/api/createRepo.ts @@ -17,9 +17,9 @@ import { ICustomizedNewRepositoryLogic, INewRepositoryContext, splitSemiColonCommas, -} from '../transitional'; +} from '../lib/transitional'; import { Organization, Repository } from '../business'; -import { RepositoryMetadataEntity } from '../entities/repositoryMetadata/repositoryMetadata'; +import { RepositoryMetadataEntity } from '../business/entities/repositoryMetadata/repositoryMetadata'; import RenderHtmlMail from '../lib/emailRender'; import { @@ -29,7 +29,7 @@ import { } from '../routes/org/repoWorkflowEngine'; import { IMailProvider } from '../lib/mailProvider'; import { IndividualContext } from '../business/user'; -import NewRepositoryLockdownSystem from '../features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../business/features/newRepositories/newRepositoryLockdown'; import { ICreateRepositoryResult, ICorporateLink, @@ -176,7 +176,7 @@ export async function CreateRepository( try { createResult = await organization.createRepository(parameters.name, parameters); if (createResult && createResult.repository) { - repository = organization.repositoryFromEntity(createResult.repository); + repository = organization.repositoryFromEntity(createResult.repository.getEntity()); } } catch (error) { providers.insights?.trackEvent({ @@ -624,14 +624,22 @@ async function sendEmail( req.insights.trackException({ exception: renderError, properties: { - content: contentOptions, + correlationId, + existingRepoId, + orgName: repository.organization.name, + repoName: repository.name, + results: repoCreateResults, eventName: 'ApiRepoCreateMailRenderFailure', }, }); throw renderError; } const customData = { - content: contentOptions, + correlationId, + existingRepoId, + orgName: repository.organization.name, + repoName: repository.name, + results: repoCreateResults, receipt: null, eventName: undefined, }; diff --git a/api/extension.ts b/api/extension.ts index c339ab89a..4e9e2f1b0 100644 --- a/api/extension.ts +++ b/api/extension.ts @@ -3,25 +3,25 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Response, Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; import { setIdentity } from '../middleware/business/authentication'; -import { AddLinkToRequest } from '../middleware/links'; +import { AddLinkToRequest } from '../middleware/business/links'; import { jsonError } from '../middleware'; import { apiContextMiddleware } from '../middleware/business/setContext'; -import { ILocalExtensionKeyProvider } from '../entities/localExtensionKey'; -import { LocalExtensionKey } from '../entities/localExtensionKey/localExtensionKey'; +import { ILocalExtensionKeyProvider } from '../business/entities/localExtensionKey'; +import { LocalExtensionKey } from '../business/entities/localExtensionKey/localExtensionKey'; import { IApiRequest } from '../middleware/apiReposAuth'; -import { PersonalAccessToken } from '../entities/token/token'; +import { PersonalAccessToken } from '../business/entities/token/token'; const thisApiScopeName = 'extension'; -interface IExtensionResponse extends Response { +type ExtensionResponse = Response & { localKey?: any; -} +}; interface IConnectionInformation { link?: any; @@ -29,7 +29,7 @@ interface IConnectionInformation { auth?: any; } -router.use(function (req: IApiRequest, res, next) { +router.use(function (req: IApiRequest, res: Response, next: NextFunction) { const token = req.apiKeyToken; if (!token.scopes) { return next(jsonError('The key is not authorized for specific APIs', 403)); @@ -40,7 +40,7 @@ router.use(function (req: IApiRequest, res, next) { return next(); }); -function overwriteUserContext(req: IApiRequest, res, next) { +function overwriteUserContext(req: IApiRequest, res: Response, next: NextFunction) { const token = req.apiKeyToken; const corporateId = token.corporateId; if (!corporateId) { @@ -121,7 +121,7 @@ router.get('/', (req: IApiRequest, res) => { router.get( '/metadata', asyncHandler(getLocalEncryptionKeyMiddleware), - (req: IApiRequest, res: IExtensionResponse) => { + (req: IApiRequest, res: ExtensionResponse) => { const apiContext = req.apiContext; const localKey = res.localKey; @@ -186,7 +186,11 @@ function getSanitizedOrganizations(operations) { return value; } -async function getLocalEncryptionKeyMiddleware(req: IApiRequest, res, next): Promise { +async function getLocalEncryptionKeyMiddleware( + req: IApiRequest, + res: ExtensionResponse, + next: NextFunction +): Promise { const providers = getProviders(req); const localExtensionKeyProvider = providers.localExtensionKeyProvider; const apiKeyToken = req.apiKeyToken; @@ -250,7 +254,7 @@ async function getOrCreateLocalEncryptionKey( return await createLocalEncryptionKey(insights, localExtensionKeyProvider, corporateId); } -router.use('*', (req, res, next) => { +router.use('*', (req, res: Response, next: NextFunction) => { return next(jsonError('API not found', 404)); }); diff --git a/api/index.ts b/api/index.ts index a26d7f502..a4f5c58ba 100644 --- a/api/index.ts +++ b/api/index.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import cors from 'cors'; -import { CreateError, getProviders } from '../transitional'; +import { CreateError, getProviders } from '../lib/transitional'; import { jsonError } from '../middleware'; import { IApiRequest } from '../middleware/apiReposAuth'; @@ -17,8 +17,9 @@ import { IApiRequest } from '../middleware/apiReposAuth'; import apiExtension from './extension'; import apiWebhook from './webhook'; import apiPeople from './people'; +import apiNews from './client/news'; -import AadApiAuthentication, { requireAadApiAuthorizedScope } from '../middleware/apiAad'; +import aadApiAuthentication, { requireAadApiAuthorizedScope } from '../middleware/apiAad'; import AzureDevOpsAuthenticationMiddleware from '../middleware/apiVstsAuth'; import ReposApiAuthentication from '../middleware/apiReposAuth'; import { CreateRepository, CreateRepositoryEntrypoint } from './createRepo'; @@ -36,7 +37,7 @@ function isClientRoute(req: ReposAppRequest) { router.use('/webhook', apiWebhook); -router.use((req: IApiRequest, res, next) => { +router.use((req: IApiRequest, res: Response, next: NextFunction) => { if (isClientRoute(req)) { // The frontend client routes are hooked into Express after // the session middleware. The client route does not require @@ -67,15 +68,16 @@ router.use((req: IApiRequest, res, next) => { // AUTHENTICATION: VSTS or repos //----------------------------------------------------------------------------- const multipleProviders = supportMultipleAuthProviders([ - AadApiAuthentication, + aadApiAuthentication, ReposApiAuthentication, AzureDevOpsAuthenticationMiddleware, ]); -const aadAndCustomProviders = supportMultipleAuthProviders([AadApiAuthentication, ReposApiAuthentication]); +const aadAndCustomProviders = supportMultipleAuthProviders([aadApiAuthentication, ReposApiAuthentication]); router.use('/people', cors(), multipleProviders, apiPeople); router.use('/extension', cors(), multipleProviders, apiExtension); +router.use('/news', cors(), aadApiAuthentication, requireAadApiAuthorizedScope('news'), apiNews); //----------------------------------------------------------------------------- // AUTHENTICATION: AAD or repos (specific to this app) @@ -90,8 +92,8 @@ router.post('/:org/repos', aadAndCustomProviders); router.post( '/:org/repos', - requireAadApiAuthorizedScope('createRepo'), - function (req: IApiRequest, res, next) { + requireAadApiAuthorizedScope(['repo/create', 'createRepo']), + function (req: IApiRequest, res: Response, next: NextFunction) { const orgName = req.params.org; if (!req.apiKeyToken.organizationScopes) { return next(jsonError('There is a problem with the key configuration (no organization scopes)', 412)); @@ -116,7 +118,7 @@ router.post( router.post( '/:org/repos', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const providers = getProviders(req); const organization = req.organization; const convergedObject = Object.assign({}, req.headers); @@ -174,7 +176,7 @@ router.post( response: JSON.stringify(repoCreateResponse), }, }); - return res.json(repoCreateResponse); + return res.json(repoCreateResponse) as unknown as void; } catch (error) { const data = { ...convergedObject }; data.error = error.message; @@ -185,7 +187,7 @@ router.post( }) ); -router.use((req: IApiRequest, res, next) => { +router.use((req: IApiRequest, res: Response, next: NextFunction) => { if (isClientRoute(req)) { // The frontend client routes are hooked into Express after // the session middleware. The client route does not require diff --git a/api/jsonErrorHandler.ts b/api/jsonErrorHandler.ts index 50915b863..9fa874805 100644 --- a/api/jsonErrorHandler.ts +++ b/api/jsonErrorHandler.ts @@ -3,9 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { getProviders } from '../transitional'; +import { NextFunction, Response } from 'express'; +import { getProviders } from '../lib/transitional'; -export default function JsonErrorHandler(err, req, res, next) { +export default function JsonErrorHandler(err, req, res: Response, next: NextFunction) { if (err && err['json']) { // jsonError objects should bubble up like before return next(err); diff --git a/api/people/index.ts b/api/people/index.ts index a724df813..2a02f017e 100644 --- a/api/people/index.ts +++ b/api/people/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import { json404 } from '../../middleware/jsonError'; diff --git a/api/people/link.ts b/api/people/link.ts index d92825a8a..3202e00f3 100644 --- a/api/people/link.ts +++ b/api/people/link.ts @@ -3,7 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { getProviders } from '../../transitional'; +import { NextFunction, Response } from 'express'; + +import { getProviders } from '../../lib/transitional'; import { jsonError } from '../../middleware'; import { IApiRequest } from '../../middleware/apiReposAuth'; import { ICorporateLink, LinkOperationSource } from '../../interfaces'; @@ -15,7 +17,7 @@ const supportedApiVersions = new Set([ '2019-10-01', ]); -export default async function postLinkApi(req: IApiRequest, res, next) { +export default async function postLinkApi(req: IApiRequest, res: Response, next: NextFunction) { const providers = getProviders(req); const { operations } = providers; const token = req.apiKeyToken; diff --git a/api/people/links.ts b/api/people/links.ts index 5332bab1a..3ea4caa59 100644 --- a/api/people/links.ts +++ b/api/people/links.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { jsonError } from '../../middleware'; import { ICrossOrganizationMembersResult, MemberSearch, Operations } from '../../business'; -import { ICorporateLink } from '../../interfaces'; +import { ICorporateLink, VoidedExpressRoute } from '../../interfaces'; import { IApiRequest } from '../../middleware/apiReposAuth'; import postLinkApi from './link'; -import { ErrorHelper, getProviders } from '../../transitional'; -import { wrapError } from '../../utils'; +import { CreateError, ErrorHelper, getProviders } from '../../lib/transitional'; +import { wrapError } from '../../lib/utils'; const router: Router = Router(); @@ -26,7 +26,7 @@ const extendedLinkApiVersions = [ '2019-02-01', ]; -router.use(function (req: IApiRequest, res, next) { +router.use(function (req: IApiRequest, res: Response, next: NextFunction) { const token = req.apiKeyToken; if (!token.scopes) { return next(jsonError('The key is not authorized for specific APIs', 401)); @@ -37,11 +37,11 @@ router.use(function (req: IApiRequest, res, next) { return next(); }); -router.post('/', asyncHandler(postLinkApi)); +router.post('/', asyncHandler(postLinkApi as VoidedExpressRoute)); router.get( '/', - asyncHandler(async (req: IApiRequest, res, next) => { + asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const skipOrganizations = req.query.showOrganizations !== undefined && !!req.query.showOrganizations; const showTimestamps = req.query.showTimestamps !== undefined && req.query.showTimestamps === 'true'; @@ -54,9 +54,11 @@ router.get( router.get( '/:linkid', - asyncHandler(async (req: IApiRequest, res, next) => { + asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { if (unsupportedApiVersions.includes(req.apiVersion)) { - return next(jsonError('This API is not supported by the API version you are using.', 400)); + return next( + CreateError.InvalidParameters('This API is not supported by the API version you are using.') + ); } const linkid = req.params.linkid.toLowerCase(); const { operations } = getProviders(req); @@ -81,31 +83,33 @@ router.get( ); } catch (error) { if (ErrorHelper.IsNotFound(error)) { - return next(jsonError('Could not find the link', 404)); + return next(CreateError.NotFound('Could not find the link')); } else { - return next(jsonError(error, 500)); + return next(CreateError.ServerError(error)); } } req.insights.trackMetric({ name: 'ApiRequestLinkByLinkId', value: 1 }); - return res.json(entry); + return res.json(entry) as unknown as void; } const results = await getAllUsers(req.apiVersion, operations, skipOrganizations, showTimestamps, true); for (let i = 0; i < results.length; i++) { const entry = results[i]; if (entry && entry.id === linkid) { req.insights.trackMetric({ name: 'ApiRequestLinkByLinkId', value: 1 }); - return res.json(entry); + return res.json(entry) as unknown as void; } } - return next(jsonError('Could not find the link', 404)); + return next(CreateError.NotFound('Could not find the link')); }) ); router.get( '/github/:username', - asyncHandler(async (req: IApiRequest, res, next) => { + asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { if (unsupportedApiVersions.includes(req.apiVersion)) { - return next(jsonError('This API is not supported by the API version you are using.', 400)); + return next( + CreateError.InvalidParameters('This API is not supported by the API version you are using.') + ); } const username = req.params.username.toLowerCase(); const { operations } = getProviders(req); @@ -118,9 +122,9 @@ router.get( account = await operations.getAccountByUsername(username); } catch (getAccountError) { if (ErrorHelper.IsNotFound(account)) { - return next(jsonError('Could not find a link for the user', 404)); + return next(CreateError.NotFound('Could not find a link for the user')); } - return next(jsonError(getAccountError, 500)); + return next(CreateError.ServerError(getAccountError)); } try { const entry = await getByThirdPartyId( @@ -131,7 +135,7 @@ router.get( showTimestamps ); req.insights.trackMetric({ name: 'ApiRequestLinkByGitHubUsername', value: 1 }); - return res.json(entry); + return res.json(entry) as unknown as void; } catch (entryError) { return next(jsonError(entryError, ErrorHelper.GetStatus(entryError) || 500)); } @@ -141,16 +145,16 @@ router.get( const entry = results[i]; if (entry && entry.github && entry.github.login.toLowerCase() === username) { req.insights.trackMetric({ name: 'ApiRequestLinkByGitHubUsername', value: 1 }); - return res.json(entry); + return res.json(entry) as unknown as void; } } - return next(jsonError('Could not find a link for the user', 404)); + return next(CreateError.NotFound('Could not find a link for the user')); }) ); router.get( '/aad/userPrincipalName/:upn', - asyncHandler(async (req: IApiRequest, res, next) => { + asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { const upn = req.params.upn; const { operations } = getProviders(req); const skipOrganizations = req.query.showOrganizations !== undefined && !!req.query.showOrganizations; @@ -185,7 +189,7 @@ router.get( userPrincipalName: upn, }, }); - return res.json(r); + return res.json(r) as unknown as void; } const results = await getAllUsers(req.apiVersion, operations, skipOrganizations, showTimestamps); const r = []; @@ -203,18 +207,20 @@ router.get( }, }); if (r.length === 0) { - return next(jsonError('Could not find a link for the user', 404)); + return next(CreateError.NotFound('Could not find a link for the user')); } req.insights.trackMetric({ name: 'ApiRequestLinkByAadUpn', value: 1 }); - return res.json(r); + return res.json(r) as unknown as void; }) ); router.get( '/aad/:id', - asyncHandler(async (req: IApiRequest, res, next) => { + asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { if (req.apiVersion == '2016-12-01') { - return next(jsonError('This API is not supported by the API version you are using.', 400)); + return next( + CreateError.InvalidParameters('This API is not supported by the API version you are using.') + ); } const id = req.params.id; const skipOrganizations = req.query.showOrganizations !== undefined && !!req.query.showOrganizations; @@ -244,7 +250,7 @@ router.get( } } req.insights.trackMetric({ name: 'ApiRequestLinkByAadId', value: 1 }); - return res.json(r); + return res.json(r) as unknown as void; } const results = await getAllUsers(req.apiVersion, operations, skipOrganizations, showTimestamps); const r = []; @@ -258,7 +264,7 @@ router.get( return next(jsonError('Could not find a link for the user', 404)); } req.insights.trackMetric({ name: 'ApiRequestLinkByAadId', value: 1 }); - return res.json(r); + return res.json(r) as unknown as void; }) ); @@ -271,7 +277,6 @@ async function getByThirdPartyId( showLinkIds?: boolean ): Promise { const providers = operations.providers; - const { graphProvider } = providers; let link: ICorporateLink = null; try { link = await providers.linkProvider.getByThirdPartyId(thirdPartyId); @@ -346,7 +351,7 @@ async function getByThirdPartyId( } async function getAllUsers( - apiVersion, + apiVersion: string, operations: Operations, skipOrganizations: boolean, showTimestamps: boolean, diff --git a/api/people/unlink.ts b/api/people/unlink.ts index 3a7aea7d5..dbaa25e72 100644 --- a/api/people/unlink.ts +++ b/api/people/unlink.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { ICorporateLink, UnlinkPurpose } from '../../interfaces'; import { jsonError } from '../../middleware'; import { IApiRequest } from '../../middleware/apiReposAuth'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; const router: Router = Router(); @@ -17,7 +17,7 @@ interface ILinksApiRequestWithUnlink extends IApiRequest { unlink?: ICorporateLink; } -router.use(function (req: ILinksApiRequestWithUnlink, res, next) { +router.use(function (req: ILinksApiRequestWithUnlink, res: Response, next: NextFunction) { const token = req.apiKeyToken; if (!token.scopes) { return next(jsonError('The key is not authorized for specific APIs', 401)); @@ -30,7 +30,7 @@ router.use(function (req: ILinksApiRequestWithUnlink, res, next) { router.use( '/github/id/:id', - asyncHandler(async (req: ILinksApiRequestWithUnlink, res, next) => { + asyncHandler(async (req: ILinksApiRequestWithUnlink, res: Response, next: NextFunction) => { const { linkProvider } = getProviders(req); const id = req.params.id; try { @@ -46,11 +46,11 @@ router.use( }) ); -router.use('*', (req: ILinksApiRequestWithUnlink, res, next) => { +router.use('*', (req: ILinksApiRequestWithUnlink, res: Response, next: NextFunction) => { return next(req.unlink ? undefined : jsonError('No link available for operation', 404)); }); -router.delete('*', (req: ILinksApiRequestWithUnlink, res, next) => { +router.delete('*', (req: ILinksApiRequestWithUnlink, res: Response, next: NextFunction) => { const { config, operations } = getProviders(req); const link = req.unlink; let purpose: UnlinkPurpose = null; diff --git a/api/webhook.ts b/api/webhook.ts index a41104162..c7531a8ce 100644 --- a/api/webhook.ts +++ b/api/webhook.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import moment from 'moment'; import { ReposAppRequest } from '../interfaces'; import { jsonError } from '../middleware'; -import { getProviders, isWebhookIngestionEndpointEnabled } from '../transitional'; +import { getProviders, isWebhookIngestionEndpointEnabled } from '../lib/transitional'; -import OrganizationWebhookProcessor from '../webhooks/organizationProcessor'; +import OrganizationWebhookProcessor from '../business/webhooks/organizationProcessor'; const router: Router = Router(); @@ -21,7 +21,7 @@ interface IRequestWithRaw extends ReposAppRequest { } router.use( - asyncHandler(async (req: IRequestWithRaw, res, next) => { + asyncHandler(async (req: IRequestWithRaw, res: Response, next: NextFunction) => { if (!isWebhookIngestionEndpointEnabled(req)) { return next( jsonError( diff --git a/app.ts b/app.ts deleted file mode 100644 index 6bcc8ce8c..000000000 --- a/app.ts +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import express from 'express'; -import { hostname } from 'os'; - -import { IReposApplication, IReposJob, IReposJobOptions, IReposJobResult } from './interfaces'; - -import configResolver from './lib/config'; -import initialize from './middleware/initialize'; -import { quitInTenSeconds } from './utils'; - -const app = express() as any as IReposApplication; - -import Debug from 'debug'; -Debug.debug('startup')('starting...'); - -app.initializeApplication = initialize.bind(undefined, app, express, __dirname); - -app.initializeJob = function initializeJob(config, configurationError) { - if (config) { - config.isJobInternal = true; - config.skipModules = new Set(['web']); - } else { - console.warn(`Configuration did not resolve successfully`, configurationError); - } - return initialize(app, express, __dirname, config, configurationError); -}; - -async function startup(startupApplication: boolean) { - let painlessConfigResolver = null; - try { - painlessConfigResolver = configResolver(); - } catch (error) { - console.warn('Painless config resolver initialization error:'); - console.error(error); - throw error; - } - let config: any = null; - let configurationError: Error = null; - try { - config = await painlessConfigResolver.resolve(); - } catch (error) { - configurationError = error; - } - - try { - if (startupApplication) { - await app.initializeApplication(config, configurationError); - } else { - await app.initializeJob(config, configurationError); - } - } catch (startupError) { - console.error(`Startup error: ${startupError}`); - process.exit(1); // throw startupError; - } - - return app; -} - -app.startupApplication = startup.bind(null, true); -app.startupJob = startup.bind(null, false); -app.runJob = async function ( - job: (job: IReposJob) => Promise, - options?: IReposJobOptions -): Promise { - options = options || {}; - // TODO: automatically track elapsed job time - const started = new Date(); - if (options.timeoutMinutes) { - setTimeout(() => { - // TODO: insights metric and event, if a prefix exists - console.log(`Kill bit at ${options.timeoutMinutes}m`); - process.exit(1); - }, 1000 * 60 * options.timeoutMinutes); - } - if (options.defaultDebugOutput && !process.env.DEBUG) { - process.env.DEBUG = options.defaultDebugOutput; - } - app.isBackgroundJob = true; - if (options.enableAllGitHubApps) { - app.enableAllGitHubApps = true; - } - try { - await app.startupJob(); - } catch (startupError) { - console.error(`Job startup error before runJob: ${startupError}`); - quitInTenSeconds(false); - return app; - } - if (options.insightsPrefix && app.providers.insights) { - try { - app.providers.insights.trackEvent({ - name: `${options.insightsPrefix}Started`, - properties: { - hostname: hostname(), - }, - }); - } catch (ignoreInsightsError) { - console.error(`insights error: ${ignoreInsightsError}`); - } - } - const jobObject = { - app, - providers: app.providers, - started, - parameters: options && options.parameters ? options.parameters : {}, - args: process.argv.length > 2 ? process.argv.slice(2) : [], - }; - try { - const result = await job.call(null, jobObject); - if (result && result.successProperties && app.providers.insights && options.insightsPrefix) { - try { - app.providers.insights.trackEvent({ - name: `${options.insightsPrefix}Success`, - properties: Object.assign( - { - hostname: hostname(), - }, - result.successProperties - ), - }); - } catch (ignoreInsightsError) { - console.error(`insights error: ${ignoreInsightsError}`); - } - } - } catch (jobError) { - console.error(`The job failed: ${jobError}`); - // by default, let's not show the whole inner error - const simpleError = { ...jobError }; - simpleError?.cause && delete simpleError.cause; - console.dir(simpleError); - quitInTenSeconds(false); - if (options.insightsPrefix && app.providers.insights) { - try { - app.providers.insights.trackException({ - exception: jobError, - properties: { - name: `${options.insightsPrefix}Failure`, - }, - }); - } catch (ignoreInsightsError) { - console.error(`insights error: ${ignoreInsightsError}`); - } - } - return app; - } - // CONSIDER: insights metric for job time - console.log('The job was successful.'); - quitInTenSeconds(true); - return app; -}; - -export default app; diff --git a/bin/www.ts b/bin/www.ts index 8fbd05f5c..af8fe7d7b 100644 --- a/bin/www.ts +++ b/bin/www.ts @@ -9,13 +9,15 @@ import Debug from 'debug'; const debug = Debug.debug('g:server'); const debugInitialization = Debug.debug('startup'); -import app from '../app'; - import http from 'http'; import https from 'https'; import fs from 'fs'; import path from 'path'; +import { createExpressApplication } from '..'; + +const app = createExpressApplication(); + function normalizePort(val) { const port = parseInt(val, 10); diff --git a/business/account.ts b/business/account.ts index 473eb8997..990c52a49 100644 --- a/business/account.ts +++ b/business/account.ts @@ -7,18 +7,18 @@ import _ from 'lodash'; import * as common from './common'; -import { wrapError } from '../utils'; +import { wrapError } from '../lib/utils'; import { corporateLinkToJson } from './corporateLink'; import { Organization } from './organization'; -import { AppPurpose } from './githubApps'; +import { AppPurpose } from '../lib/github/appPurposes'; import { ILinkProvider } from '../lib/linkProviders'; -import { CacheDefault, getMaxAgeSeconds } from '.'; +import { CacheDefault, Operations, getMaxAgeSeconds } from '.'; import { AccountJsonFormat, CoreCapability, ICacheOptions, ICorporateLink, - IGetAuthorizationHeader, + GetAuthorizationHeader, IGitHubAccountDetails, IOperationsInstance, IOperationsLinks, @@ -29,7 +29,7 @@ import { throwIfNotCapable, throwIfNotGitHubCapable, } from '../interfaces'; -import { ErrorHelper } from '../transitional'; +import { ErrorHelper } from '../lib/transitional'; interface IRemoveOrganizationMembershipsResult { error?: IReposError; @@ -46,7 +46,7 @@ const secondaryAccountProperties = []; export class Account { private _operations: IOperationsInstance; - private _getAuthorizationHeader: IGetAuthorizationHeader; + private _getAuthorizationHeader: GetAuthorizationHeader; private _link: ICorporateLink; private _id: number; @@ -70,6 +70,12 @@ export class Account { case AccountJsonFormat.GitHub: { return basic; } + case AccountJsonFormat.GitHubExtended: { + const cloneEntity = Object.assign({}, this._originalEntity || {}); + delete (cloneEntity as any).cost; + delete (cloneEntity as any).headers; + return cloneEntity; + } case AccountJsonFormat.GitHubDetailedWithLink: { const cloneEntity = Object.assign({}, this._originalEntity || {}); delete (cloneEntity as any).cost; @@ -131,7 +137,7 @@ export class Account { return this._originalEntity ? this._originalEntity.name : undefined; } - constructor(entity, operations: IOperationsInstance, getAuthorizationHeader: IGetAuthorizationHeader) { + constructor(entity, operations: IOperationsInstance, getAuthorizationHeader: GetAuthorizationHeader) { common.assignKnownFieldsPrefixed( this, entity, @@ -144,7 +150,7 @@ export class Account { this._getAuthorizationHeader = getAuthorizationHeader; } - overrideAuthorization(getAuthorizationHeader: IGetAuthorizationHeader) { + overrideAuthorization(getAuthorizationHeader: GetAuthorizationHeader) { this._getAuthorizationHeader = getAuthorizationHeader; } @@ -352,8 +358,10 @@ export class Account { cacheOptions.backgroundRefresh = options.backgroundRefresh; } try { + const ops = operations as Operations; const entity = (await operations.github.request( - this.authorize(AppPurpose.Data), + ops.getPublicAuthorizationToken(), + // this.authorize(AppPurpose.Data), 'GET /user/:id', parameters, cacheOptions @@ -412,7 +420,7 @@ export class Account { }; const eventData = { github: { - id: id, + id, login: this._login, }, aad: aadIdentity, @@ -478,7 +486,11 @@ export class Account { return currentOrganizationMemberships; } - async removeCollaboratorPermissions(): Promise { + async removeCollaboratorPermissions( + onlyOneHundred?: boolean + ): Promise { + // NOTE: this at least temporarily adds the ability to punt 100 + // but not all grants; probably should use options eventually vs bool param. const history = []; const error: IReposError = null; const operations = throwIfNotGitHubCapable(this._operations); @@ -492,13 +504,18 @@ export class Account { await this.getDetails(); } const collaborativeRepos = await queryCache.userCollaboratorRepositories(this.id.toString()); + let i = 0; for (const entry of collaborativeRepos) { + if (onlyOneHundred && i >= 100) { + break; + } const { repository } = entry; try { await repository.getDetails(); if (repository.archived) { - history.push(`FYI: previous access to an archived repository ${repository.full_name}`); + history.push(`FYI: cannot alter prior grant to archived repository ${repository.full_name}`); } else { + ++i; await repository.removeCollaborator(this.login); history.push(`Removed ${this.login} as a Collaborator from the repository ${repository.full_name}`); } @@ -556,11 +573,8 @@ export class Account { return { history, error }; } - private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/application.ts b/business/application.ts index 40e0b602a..de134a1dc 100644 --- a/business/application.ts +++ b/business/application.ts @@ -3,14 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { OrganizationSetting } from './entities/organizationSettings/organizationSetting'; import { IOperationsGitHubRestLibrary, IOperationsDefaultCacheTimes, - IGetAuthorizationHeader, + GetAuthorizationHeader, IGitHubAppInstallation, ICacheOptions, } from '../interfaces'; -import { wrapError } from '../utils'; +import { wrapError } from '../lib/utils'; const primaryInstallationProperties = [ 'id', @@ -22,13 +23,34 @@ const primaryInstallationProperties = [ 'events', ]; +export type GitHubAppDefinition = { + id: number; + slug: string; + friendlyName: string; +}; + +export function isInstallationConfigured( + settings: OrganizationSetting, + installation: IGitHubAppInstallation +): boolean { + if (!settings || !settings.installations) { + return false; + } + for (const install of settings.installations) { + if (install.installationId === installation.id) { + return true; + } + } + return false; +} + export default class GitHubApplication { constructor( private operations: IOperationsGitHubRestLibrary & IOperationsDefaultCacheTimes, public id: number, public slug: string, public friendlyName: string, - private getAuthorizationHeader: IGetAuthorizationHeader + private getAuthorizationHeader: GetAuthorizationHeader ) {} static PrimaryInstallationProperties = primaryInstallationProperties; @@ -52,6 +74,14 @@ export default class GitHubApplication { return invalid; } + asClientJson(): GitHubAppDefinition { + return { + id: this.id, + slug: this.slug, + friendlyName: this.friendlyName, + }; + } + async getInstallation(installationId: number, options?: ICacheOptions): Promise { const operations = this.operations; const parameters = { @@ -85,7 +115,7 @@ export default class GitHubApplication { async getInstallations(options?: ICacheOptions): Promise { options = options || {}; const operations = this.operations; - const getAuthorizationHeader = this.getAuthorizationHeader.bind(this) as IGetAuthorizationHeader; + const getAuthorizationHeader = this.getAuthorizationHeader.bind(this) as GetAuthorizationHeader; const github = operations.github; const caching = { maxAgeSeconds: options.maxAgeSeconds || operations.defaults.orgRepoDetailsStaleSeconds, // borrowing from another value @@ -102,8 +132,8 @@ export default class GitHubApplication { return installations; } - private authorize(): IGetAuthorizationHeader | string { - const getAuthorizationHeader = this.getAuthorizationHeader.bind(this) as IGetAuthorizationHeader; + private authorize(): GetAuthorizationHeader | string { + const getAuthorizationHeader = this.getAuthorizationHeader.bind(this) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/collaborator.ts b/business/collaborator.ts index c40bc6f67..ed745527d 100644 --- a/business/collaborator.ts +++ b/business/collaborator.ts @@ -4,6 +4,7 @@ // import { GitHubRepositoryPermission, IGitHubCollaboratorPermissions } from '../interfaces'; +import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../lib/transitional'; import * as common from './common'; // prettier-ignore @@ -14,6 +15,19 @@ const memberPrimaryProperties = [ 'avatar_url', ]; +export type CollaboratorJson = { + avatar_url: string; + id: number; + login: string; + permissions: IGitHubCollaboratorPermissions; +}; + +export type CollaboratorAccount = Collaborator | { id: number; login: string }; + +export function compareCollaborators(a: Collaborator, b: Collaborator) { + return a?.login.localeCompare(b?.login, 'en', { sensitivity: 'base' }); +} + export class Collaborator { public static PrimaryProperties = memberPrimaryProperties; @@ -28,7 +42,7 @@ export class Collaborator { } } - asJson() { + asJson(): CollaboratorJson { return { avatar_url: this.avatar_url, id: this._id, @@ -45,15 +59,7 @@ export class Collaborator { if (!this._permissions) { return GitHubRepositoryPermission.None; } - const permissions = this._permissions; - if (permissions.admin) { - return GitHubRepositoryPermission.Admin; - } else if (permissions.push) { - return GitHubRepositoryPermission.Push; - } else if (permissions.pull) { - return GitHubRepositoryPermission.Pull; - } - throw new Error(`Unsupported permission type by getHighestPermission`); + return projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(this._permissions); } get id(): number { diff --git a/business/domains.ts b/business/domains.ts index d283dac00..73d211f3a 100644 --- a/business/domains.ts +++ b/business/domains.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose, AppPurposeTypes } from './githubApps'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; import { Organization } from '.'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, throwIfNotGitHubCapable, - IGetAuthorizationHeader, + GetAuthorizationHeader, } from '../interfaces'; import { decorateIterable, @@ -17,7 +17,7 @@ import { IteratorResponse, PaginationPageSizeOptions, } from './iterable'; -import { DefaultGraphqlPageSize } from '../transitional'; +import { DefaultGraphqlPageSize } from '../lib/transitional'; type DomainResponse = { id: string; @@ -44,15 +44,15 @@ export class OrganizationDomains { private _organization: Organization; private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _purpose: AppPurpose; constructor( organization: Organization, operations: IOperationsInstance, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader + getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader ) { this._getAuthorizationHeader = getAuthorizationHeader; this._getSpecificAuthorizationHeader = getSpecificAuthorizationHeader; @@ -110,19 +110,16 @@ export class OrganizationDomains { } } - private authorize(purpose: AppPurpose = this._purpose): IGetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose = this._purpose): GetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/enterprise.ts b/business/enterprise.ts new file mode 100644 index 000000000..8c60aa5ae --- /dev/null +++ b/business/enterprise.ts @@ -0,0 +1,194 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { IProviders } from '../interfaces'; + +// TODO: paginate across enterprise fix + support iterators + +export type EnterpriseSamlExternalIdentityBasics = { + id: string; + user: { + login: string; + }; + samlIdentity: { + nameId: string; + }; +}; + +export type EnterpriseSamlExternalIdentityNode = { + node: EnterpriseSamlExternalIdentityBasics; +}; + +export default class GitHubEnterprise { + constructor( + private providers: IProviders, + public slug: string, + private administrativeToken: string + ) {} + + async getGitHubLoginForUserPrincipalName(userPrincipalName: string): Promise { + const node = await this.getSamlNodeFromUserPrincipalName(userPrincipalName); + return node?.user?.login; + } + + async getSamlNodeFromUserPrincipalName( + userPrincipalName: string + ): Promise { + const github = this.providers.github; + try { + const response = await github.graphql( + this.administrativeToken, + queries.getIdentityFromExternal, + { + enterpriseName: this.slug, + userPrincipalName, + }, + { + paginate: false, + } + ); + const nodes = response?.enterprise?.ownerInfo?.samlIdentityProvider?.externalIdentities + ?.edges as EnterpriseSamlExternalIdentityNode[]; + if (nodes.length > 0) { + return nodes[0].node; + } + } catch (error) { + throw error; + } + } + + async getSamlUserPrincipalNameForGitHubLogin(login: string): Promise { + const node = await this.getSamlNodeForGitHubLogin(login); + return node?.samlIdentity?.nameId; + } + + async getSamlNodeForGitHubLogin(login: string): Promise { + const github = this.providers.github; + try { + const response = await github.graphql( + this.administrativeToken, + queries.getIdentityFromGitHubLogin, + { + enterpriseName: this.slug, + login, + }, + { + paginate: false, + } + ); + const nodes = response?.enterprise?.ownerInfo?.samlIdentityProvider?.externalIdentities + ?.edges as EnterpriseSamlExternalIdentityNode[]; + if (nodes.length > 0) { + return nodes[0].node; + } + } catch (error) { + throw error; + } + } + + async getSamlMemberExternalIdentities(): Promise { + const fixedFirstFieldsCount = 8; + const github = this.providers.github; + try { + const response = await github.graphql( + this.administrativeToken, + queries.paginate, + { + enterpriseName: this.slug, + // id: this._id, + }, + { + paginate: false, // true, + } + ); + const nodes = response?.enterprise?.ownerInfo?.samlIdentityProvider?.externalIdentities + ?.edges as EnterpriseSamlExternalIdentityNode[]; + return nodes.map((node) => node.node); + } catch (error) { + throw error; + } + } +} + +const queries = { + getIdentityFromGitHubLogin: ` + query getIdentity($enterpriseName: String!, $login: String!) { + enterprise(slug: $enterpriseName) { + ownerInfo { + samlIdentityProvider { + externalIdentities(first: 5, login: $login) { + pageInfo { + hasNextPage + endCursor + } + edges { + node { + user { + login + } + samlIdentity { + nameId + } + } + } + } + } + } + } + } + `, + getIdentityFromExternal: ` + query getIdentity($enterpriseName: String!, $userPrincipalName: String!) { + enterprise(slug: $enterpriseName) { + ownerInfo { + samlIdentityProvider { + externalIdentities(first: 5, userName: $userPrincipalName) { + pageInfo { + hasNextPage + endCursor + } + edges { + node { + user { + login + } + samlIdentity { + nameId + } + } + } + } + } + } + } + } + `, + paginate: ` + query paginate($cursor: String, $enterpriseName: String!) { + enterprise(slug: $enterpriseName) { + ownerInfo { + samlIdentityProvider { + externalIdentities(after: $cursor, first: 100) { + pageInfo { + hasNextPage + endCursor + } + edges { + node { + user { + login + } + samlIdentity { + nameId + } + } + } + } + } + } + } + } + `, +}; diff --git a/entities/auditLogRecord/auditLogRecord.ts b/business/entities/auditLogRecord/auditLogRecord.ts similarity index 94% rename from entities/auditLogRecord/auditLogRecord.ts rename to business/entities/auditLogRecord/auditLogRecord.ts index a80b77e0a..08f2311ea 100644 --- a/entities/auditLogRecord/auditLogRecord.ts +++ b/business/entities/auditLogRecord/auditLogRecord.ts @@ -5,23 +5,23 @@ import { randomUUID } from 'crypto'; -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; +} from '../../../lib/entityMetadataProvider/declarations'; import { Type } from './type'; import { PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; -import { IDictionary } from '../../interfaces'; +} from '../../../lib/entityMetadataProvider/postgres'; +import { IDictionary } from '../../../interfaces'; import { AuditLogSource } from '.'; -import { stringOrNumberAsString } from '../../utils'; -import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; +import { stringOrNumberAsString } from '../../../lib/utils'; +import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; const type = Type; diff --git a/entities/auditLogRecord/auditLogRecordProvider.ts b/business/entities/auditLogRecord/auditLogRecordProvider.ts similarity index 98% rename from entities/auditLogRecord/auditLogRecordProvider.ts rename to business/entities/auditLogRecord/auditLogRecordProvider.ts index df7b7647a..709df08c9 100644 --- a/entities/auditLogRecord/auditLogRecordProvider.ts +++ b/business/entities/auditLogRecord/auditLogRecordProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { AuditLogRecord, AuditLogRecordQueryUndoCandidatesByThirdPartyId, diff --git a/entities/auditLogRecord/index.ts b/business/entities/auditLogRecord/index.ts similarity index 100% rename from entities/auditLogRecord/index.ts rename to business/entities/auditLogRecord/index.ts diff --git a/entities/auditLogRecord/type.ts b/business/entities/auditLogRecord/type.ts similarity index 69% rename from entities/auditLogRecord/type.ts rename to business/entities/auditLogRecord/type.ts index de552af45..fb9ba2b8f 100644 --- a/entities/auditLogRecord/type.ts +++ b/business/entities/auditLogRecord/type.ts @@ -3,6 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataType } from '../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataType } from '../../../lib/entityMetadataProvider/entityMetadata'; export const Type = new EntityMetadataType('AuditLogRecord'); diff --git a/entities/localExtensionKey/index.ts b/business/entities/localExtensionKey/index.ts similarity index 91% rename from entities/localExtensionKey/index.ts rename to business/entities/localExtensionKey/index.ts index 0aff67b8e..015a8b11f 100644 --- a/entities/localExtensionKey/index.ts +++ b/business/entities/localExtensionKey/index.ts @@ -5,7 +5,7 @@ import { LocalExtensionKeyProvider } from './localExtensionKeyProvider'; import { LocalExtensionKey } from './localExtensionKey'; -import { IEntityMetadataProvider } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadataProvider } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; export interface ILocalExtensionKeyProvider { initialize(): Promise; diff --git a/entities/localExtensionKey/localExtensionKey.ts b/business/entities/localExtensionKey/localExtensionKey.ts similarity index 90% rename from entities/localExtensionKey/localExtensionKey.ts rename to business/entities/localExtensionKey/localExtensionKey.ts index 0a0adb6ac..62dc3dd7c 100644 --- a/entities/localExtensionKey/localExtensionKey.ts +++ b/business/entities/localExtensionKey/localExtensionKey.ts @@ -5,15 +5,15 @@ import crypto from 'crypto'; -import { IObjectWithDefinedKeys } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IObjectWithDefinedKeys } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; import { MetadataMappingDefinition, EntityMetadataMappings, -} from '../../lib/entityMetadataProvider/declarations'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; -import { TableSettings } from '../../lib/entityMetadataProvider/table'; -import { MemorySettings } from '../../lib/entityMetadataProvider/memory'; +} from '../../../lib/entityMetadataProvider/declarations'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; +import { TableSettings } from '../../../lib/entityMetadataProvider/table'; +import { MemorySettings } from '../../../lib/entityMetadataProvider/memory'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; const type = new EntityMetadataType('LocalExtensionKey'); diff --git a/entities/localExtensionKey/localExtensionKeyProvider.ts b/business/entities/localExtensionKey/localExtensionKeyProvider.ts similarity index 94% rename from entities/localExtensionKey/localExtensionKeyProvider.ts rename to business/entities/localExtensionKey/localExtensionKeyProvider.ts index 8b3c99097..adb37e2fd 100644 --- a/entities/localExtensionKey/localExtensionKeyProvider.ts +++ b/business/entities/localExtensionKey/localExtensionKeyProvider.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataBase } from '../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataBase } from '../../../lib/entityMetadataProvider/entityMetadata'; import { LocalExtensionKey, EntityImplementation } from './localExtensionKey'; import { ILocalExtensionKeyProvider, ILocalExtensionKeyProviderOptions } from '.'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; const thisProviderType = EntityImplementation.Type; diff --git a/entities/organizationAnnotation.ts b/business/entities/organizationAnnotation.ts similarity index 90% rename from entities/organizationAnnotation.ts rename to business/entities/organizationAnnotation.ts index 0fe6daf74..61b428b77 100644 --- a/entities/organizationAnnotation.ts +++ b/business/entities/organizationAnnotation.ts @@ -22,16 +22,16 @@ import { EntityMetadataType, IEntityMetadataBaseOptions, EntityMetadataBase, -} from '../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, QueryBase } from '../lib/entityMetadataProvider/query'; +} from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, QueryBase } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../lib/entityMetadataProvider/declarations'; -import { PostgresSettings, PostgresConfiguration } from '../lib/entityMetadataProvider/postgres'; -import { IDictionary } from '../interfaces'; -import { CreateError, ErrorHelper } from '../transitional'; -import { MemoryConfiguration, TableConfiguration } from '../lib/entityMetadataProvider'; +} from '../../lib/entityMetadataProvider/declarations'; +import { PostgresSettings, PostgresConfiguration } from '../../lib/entityMetadataProvider/postgres'; +import { IDictionary } from '../../interfaces'; +import { CreateError, ErrorHelper } from '../../lib/transitional'; +import { MemoryConfiguration, TableConfiguration } from '../../lib/entityMetadataProvider'; const type = new EntityMetadataType('OrganizationAnnotation'); const thisProviderType = type; @@ -41,7 +41,10 @@ const defaultPostgresTableName = 'organizationannotations'; const organizationId = 'organizationId'; const primaryKeyFieldName = organizationId; -export enum OrganizationAnnotationProperty {} +export enum OrganizationAnnotationProperty { + Governance = 'governance', +} + export enum OrganizationAnnotationFeature {} export interface IOrganizationAnnotationChange { @@ -52,6 +55,11 @@ export interface IOrganizationAnnotationChange { text: string; } +export function getOrganizationAnnotationRestrictedPropertyNames(isSystemAdministrator?: boolean): string[] { + const restrictedProperties = ['administratorNodes', 'history']; + return isSystemAdministrator ? [] : restrictedProperties; +} + interface IOrganizationAnnotationMetadataProperties { // organizationId: string; // primary ID diff --git a/entities/organizationMemberCache/index.ts b/business/entities/organizationMemberCache/index.ts similarity index 100% rename from entities/organizationMemberCache/index.ts rename to business/entities/organizationMemberCache/index.ts diff --git a/entities/organizationMemberCache/organizationMemberCache.ts b/business/entities/organizationMemberCache/organizationMemberCache.ts similarity index 93% rename from entities/organizationMemberCache/organizationMemberCache.ts rename to business/entities/organizationMemberCache/organizationMemberCache.ts index 87a2e5b27..98d9506a5 100644 --- a/entities/organizationMemberCache/organizationMemberCache.ts +++ b/business/entities/organizationMemberCache/organizationMemberCache.ts @@ -3,25 +3,25 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; -import { OrganizationMembershipRole } from '../../interfaces'; -import { stringOrNumberAsString } from '../../utils'; +} from '../../../lib/entityMetadataProvider/declarations'; +import { OrganizationMembershipRole } from '../../../interfaces'; +import { stringOrNumberAsString } from '../../../lib/utils'; import { PostgresJsonEntityQuery, PostgresGetAllEntities, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; -import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; -import { TableConfiguration, TableSettings } from '../../lib/entityMetadataProvider'; +} from '../../../lib/entityMetadataProvider/postgres'; +import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +import { TableConfiguration, TableSettings } from '../../../lib/entityMetadataProvider'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; -import { CreateError } from '../../transitional'; +import { CreateError } from '../../../lib/transitional'; const type = new EntityMetadataType('OrganizationMemberCache'); diff --git a/entities/organizationMemberCache/organizationMemberCacheProvider.ts b/business/entities/organizationMemberCache/organizationMemberCacheProvider.ts similarity index 98% rename from entities/organizationMemberCache/organizationMemberCacheProvider.ts rename to business/entities/organizationMemberCache/organizationMemberCacheProvider.ts index 66e789707..2aa1bdcb4 100644 --- a/entities/organizationMemberCache/organizationMemberCacheProvider.ts +++ b/business/entities/organizationMemberCache/organizationMemberCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { OrganizationMemberCacheEntity, EntityImplementation, diff --git a/entities/organizationSettings/index.ts b/business/entities/organizationSettings/index.ts similarity index 100% rename from entities/organizationSettings/index.ts rename to business/entities/organizationSettings/index.ts diff --git a/entities/organizationSettings/organizationSetting.ts b/business/entities/organizationSettings/organizationSetting.ts similarity index 89% rename from entities/organizationSettings/organizationSetting.ts rename to business/entities/organizationSettings/organizationSetting.ts index 3b1705f60..5ce2cee28 100644 --- a/entities/organizationSettings/organizationSetting.ts +++ b/business/entities/organizationSettings/organizationSetting.ts @@ -3,15 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; +} from '../../../lib/entityMetadataProvider/declarations'; import { Type } from './type'; -import { PostgresGetAllEntities } from '../../lib/entityMetadataProvider/postgres'; +import { PostgresGetAllEntities } from '../../../lib/entityMetadataProvider/postgres'; import { MemoryConfiguration, MemorySettings, @@ -19,8 +19,8 @@ import { PostgresConfiguration, TableConfiguration, TableSettings, -} from '../../lib/entityMetadataProvider'; -import { ConfigGitHubOrganization } from '../../config/github.organizations.types'; +} from '../../../lib/entityMetadataProvider'; +import { ConfigGitHubOrganization } from '../../../config/github.organizations.types'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; export interface IBasicGitHubAppInstallation { @@ -29,8 +29,9 @@ export interface IBasicGitHubAppInstallation { appPurposeId?: string; } -export enum SpecialTeam { +export enum SystemTeam { Everyone = 'everyone', // teamAllMembers + OpenAccess = 'openAccess', Sudo = 'sudo', // teamSudoers GlobalSudo = 'globalSudo', // teamPortalSudoers SystemWrite = 'systemWrite', // teamAllReposWrite @@ -56,7 +57,7 @@ export enum OrganizationProperty { } export interface ISpecialTeam { - specialTeam: SpecialTeam; + specialTeam: SystemTeam; teamId: number; } @@ -158,6 +159,16 @@ export class OrganizationSetting implements IOrganizationSettingProperties { return this.#ownerToken; } + static CreateEmptyWithOldToken(token: string, notes: string, organizationId?: number) { + const settings = new OrganizationSetting(); + settings.#ownerToken = token; + if (organizationId) { + settings.organizationId = organizationId; + } + settings.operationsNotes = notes; + return settings; + } + static CreateFromStaticSettings(staticSettings: ConfigGitHubOrganization): OrganizationSetting { const clone = { ...staticSettings }; const settings = new OrganizationSetting(); @@ -260,20 +271,33 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamAllMembers as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SpecialTeam.Everyone, + specialTeam: SystemTeam.Everyone, teamId: Number(value), }); } } delete clone.teamAllMembers; + if (clone.teamOpenAccess) { + const arr = Array.isArray(clone.teamOpenAccess) + ? (clone.teamOpenAccess as any[]) + : [clone.teamOpenAccess as any]; + for (const value of arr) { + settings.specialTeams.push({ + specialTeam: SystemTeam.OpenAccess, + teamId: Number(value), + }); + } + } + delete clone.teamOpenAccess; + if (clone.teamAllReposRead) { const arr = Array.isArray(clone.teamAllReposRead) ? (clone.teamAllReposRead as any[]) : [clone.teamAllReposRead as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SpecialTeam.SystemRead, + specialTeam: SystemTeam.SystemRead, teamId: Number(value), }); } @@ -286,7 +310,7 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamAllReposWrite as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SpecialTeam.SystemWrite, + specialTeam: SystemTeam.SystemWrite, teamId: Number(value), }); } @@ -299,7 +323,7 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamAllReposAdmin as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SpecialTeam.SystemAdmin, + specialTeam: SystemTeam.SystemAdmin, teamId: Number(value), }); } @@ -312,7 +336,7 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamSudoers as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SpecialTeam.Sudo, + specialTeam: SystemTeam.Sudo, teamId: Number(value), }); } @@ -325,7 +349,7 @@ export class OrganizationSetting implements IOrganizationSettingProperties { : [clone.teamPortalSudoers as any]; for (const value of arr) { settings.specialTeams.push({ - specialTeam: SpecialTeam.GlobalSudo, + specialTeam: SystemTeam.GlobalSudo, teamId: Number(value), }); } diff --git a/entities/organizationSettings/organizationSettingProvider.ts b/business/entities/organizationSettings/organizationSettingProvider.ts similarity index 97% rename from entities/organizationSettings/organizationSettingProvider.ts rename to business/entities/organizationSettings/organizationSettingProvider.ts index 6cbf908cc..c7b7944dd 100644 --- a/entities/organizationSettings/organizationSettingProvider.ts +++ b/business/entities/organizationSettings/organizationSettingProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { OrganizationSetting, OrganizationSettingFixedQueryAll } from './organizationSetting'; import { EntityImplementation } from './organizationSetting'; diff --git a/entities/organizationSettings/type.ts b/business/entities/organizationSettings/type.ts similarity index 69% rename from entities/organizationSettings/type.ts rename to business/entities/organizationSettings/type.ts index 6f3cd7419..0d4bc1a6c 100644 --- a/entities/organizationSettings/type.ts +++ b/business/entities/organizationSettings/type.ts @@ -3,6 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataType } from '../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataType } from '../../../lib/entityMetadataProvider/entityMetadata'; export const Type = new EntityMetadataType('OrganizationSetting'); diff --git a/entities/repository.ts b/business/entities/repository.ts similarity index 92% rename from entities/repository.ts rename to business/entities/repository.ts index c2ca9ce3c..bb1b5bd5a 100644 --- a/entities/repository.ts +++ b/business/entities/repository.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { GitHubRepositoryVisibility } from '../interfaces'; +import { GitHubRepositoryVisibility } from '../../interfaces'; import { EntityMetadataBase, EntityMetadataMappings, @@ -14,8 +14,9 @@ import { keyValueMetadataField, MetadataMappingDefinition, QueryBase, -} from '../lib/entityMetadataProvider'; -import { PostgresConfiguration, PostgresSettings } from '../lib/entityMetadataProvider/postgres'; +} from '../../lib/entityMetadataProvider'; +import { PostgresConfiguration, PostgresSettings } from '../../lib/entityMetadataProvider/postgres'; +import { ErrorHelper } from '../../lib/transitional'; const type = new EntityMetadataType('RepositoryDetails'); const typeColumnValue = 'repositorydetails'; @@ -34,7 +35,10 @@ class ThisQueryBase extends QueryBase { } class ThisQuery extends ThisQueryBase { - constructor(query: Query, public parameters: T) { + constructor( + query: Query, + public parameters: T + ) { super(query); if (!this.parameters) { this.parameters = {} as T; @@ -312,6 +316,21 @@ for (let i = 0; i < fieldNames.length; i++) { } } +export async function tryGetRepositoryEntity( + repositoryProvider: IRepositoryProvider, + repositoryId: number +): Promise { + try { + const repositoryEntity = await repositoryProvider.get(repositoryId); + return repositoryEntity; + } catch (error) { + if (ErrorHelper.IsNotFound(error)) { + return null; + } + throw error; + } +} + export const EntityImplementation = { Type: type, EnsureDefinitions: () => {}, diff --git a/entities/repositoryCache/index.ts b/business/entities/repositoryCache/index.ts similarity index 100% rename from entities/repositoryCache/index.ts rename to business/entities/repositoryCache/index.ts diff --git a/entities/repositoryCache/repositoryCache.ts b/business/entities/repositoryCache/repositoryCache.ts similarity index 91% rename from entities/repositoryCache/repositoryCache.ts rename to business/entities/repositoryCache/repositoryCache.ts index 78da4fe3d..f88af3a4b 100644 --- a/entities/repositoryCache/repositoryCache.ts +++ b/business/entities/repositoryCache/repositoryCache.ts @@ -3,23 +3,23 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; +} from '../../../lib/entityMetadataProvider/declarations'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; -import { stringOrNumberAsString } from '../../utils'; -import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; -import { Operations } from '../../business/operations'; -import { TableConfiguration } from '../../lib/entityMetadataProvider'; +} from '../../../lib/entityMetadataProvider/postgres'; +import { stringOrNumberAsString } from '../../../lib/utils'; +import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +import { Operations } from '../../operations'; +import { TableConfiguration } from '../../../lib/entityMetadataProvider'; const type = new EntityMetadataType('RepositoryCache'); diff --git a/entities/repositoryCache/repositoryCacheProvider.ts b/business/entities/repositoryCache/repositoryCacheProvider.ts similarity index 98% rename from entities/repositoryCache/repositoryCacheProvider.ts rename to business/entities/repositoryCache/repositoryCacheProvider.ts index 9109917d2..08b868c62 100644 --- a/entities/repositoryCache/repositoryCacheProvider.ts +++ b/business/entities/repositoryCache/repositoryCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { RepositoryCacheEntity, EntityImplementation, diff --git a/entities/repositoryCollaboratorCache/index.ts b/business/entities/repositoryCollaboratorCache/index.ts similarity index 100% rename from entities/repositoryCollaboratorCache/index.ts rename to business/entities/repositoryCollaboratorCache/index.ts diff --git a/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts b/business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts similarity index 94% rename from entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts rename to business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts index 72e3c7a53..c701be627 100644 --- a/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts +++ b/business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache.ts @@ -3,23 +3,23 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; -import { GitHubCollaboratorType, GitHubRepositoryPermission } from '../../interfaces'; +} from '../../../lib/entityMetadataProvider/declarations'; +import { GitHubCollaboratorType, GitHubRepositoryPermission } from '../../../interfaces'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; -import { stringOrNumberAsString } from '../../utils'; -import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; -import { TableConfiguration } from '../../lib/entityMetadataProvider'; +} from '../../../lib/entityMetadataProvider/postgres'; +import { stringOrNumberAsString } from '../../../lib/utils'; +import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +import { TableConfiguration } from '../../../lib/entityMetadataProvider'; const type = new EntityMetadataType('RepositoryCollaboratorCache'); diff --git a/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts b/business/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts similarity index 99% rename from entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts rename to business/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts index b7da8d4d3..93dd18710 100644 --- a/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts +++ b/business/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { RepositoryCollaboratorCacheEntity, EntityImplementation, diff --git a/entities/repositoryMetadata/index.ts b/business/entities/repositoryMetadata/index.ts similarity index 100% rename from entities/repositoryMetadata/index.ts rename to business/entities/repositoryMetadata/index.ts diff --git a/entities/repositoryMetadata/repositoryMetadata.ts b/business/entities/repositoryMetadata/repositoryMetadata.ts similarity index 95% rename from entities/repositoryMetadata/repositoryMetadata.ts rename to business/entities/repositoryMetadata/repositoryMetadata.ts index c762557aa..015290fb0 100644 --- a/entities/repositoryMetadata/repositoryMetadata.ts +++ b/business/entities/repositoryMetadata/repositoryMetadata.ts @@ -3,28 +3,28 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import type { IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { type IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; +} from '../../../lib/entityMetadataProvider/declarations'; import { Type } from './type'; import { PostgresGetAllEntities, PostgresGetByID, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; -import { TableConfiguration, TableSettings } from '../../lib/entityMetadataProvider/table'; -import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; +} from '../../../lib/entityMetadataProvider/postgres'; +import { TableSettings } from '../../../lib/entityMetadataProvider/table'; +import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; import { GitHubRepositoryVisibility, IInitialTeamPermission, RepositoryLockdownState, -} from '../../interfaces/github/repos'; +} from '../../../interfaces/github/repos'; const type = Type; diff --git a/entities/repositoryMetadata/repositoryMetadataProvider.ts b/business/entities/repositoryMetadata/repositoryMetadataProvider.ts similarity index 98% rename from entities/repositoryMetadata/repositoryMetadataProvider.ts rename to business/entities/repositoryMetadata/repositoryMetadataProvider.ts index 9cd0d39b2..754486fb6 100644 --- a/entities/repositoryMetadata/repositoryMetadataProvider.ts +++ b/business/entities/repositoryMetadata/repositoryMetadataProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { RepositoryMetadataEntity, RepositoryMetadataFixedQueryAll, diff --git a/entities/repositoryMetadata/type.ts b/business/entities/repositoryMetadata/type.ts similarity index 68% rename from entities/repositoryMetadata/type.ts rename to business/entities/repositoryMetadata/type.ts index d86789e50..3c560ca42 100644 --- a/entities/repositoryMetadata/type.ts +++ b/business/entities/repositoryMetadata/type.ts @@ -3,6 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataType } from '../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataType } from '../../../lib/entityMetadataProvider/entityMetadata'; export const Type = new EntityMetadataType('Repository'); diff --git a/entities/repositoryTeamCache/index.ts b/business/entities/repositoryTeamCache/index.ts similarity index 100% rename from entities/repositoryTeamCache/index.ts rename to business/entities/repositoryTeamCache/index.ts diff --git a/entities/repositoryTeamCache/repositoryTeamCache.ts b/business/entities/repositoryTeamCache/repositoryTeamCache.ts similarity index 93% rename from entities/repositoryTeamCache/repositoryTeamCache.ts rename to business/entities/repositoryTeamCache/repositoryTeamCache.ts index 2d4147517..c6a0cf66e 100644 --- a/entities/repositoryTeamCache/repositoryTeamCache.ts +++ b/business/entities/repositoryTeamCache/repositoryTeamCache.ts @@ -3,24 +3,24 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; +} from '../../../lib/entityMetadataProvider/declarations'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresJsonEntityQueryMultiple, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; -import { stringOrNumberAsString } from '../../utils'; -import { GitHubRepositoryPermission } from '../../interfaces/github/repos'; -import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; -import { TableConfiguration } from '../../lib/entityMetadataProvider'; +} from '../../../lib/entityMetadataProvider/postgres'; +import { stringOrNumberAsString } from '../../../lib/utils'; +import { GitHubRepositoryPermission } from '../../../interfaces/github/repos'; +import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +import { TableConfiguration } from '../../../lib/entityMetadataProvider'; const type = new EntityMetadataType('RepositoryTeamCache'); diff --git a/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts b/business/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts similarity index 98% rename from entities/repositoryTeamCache/repositoryTeamCacheProvider.ts rename to business/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts index 72fb0a38a..f22fd79d4 100644 --- a/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts +++ b/business/entities/repositoryTeamCache/repositoryTeamCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { RepositoryTeamCacheEntity, EntityImplementation, diff --git a/entities/teamCache/index.ts b/business/entities/teamCache/index.ts similarity index 97% rename from entities/teamCache/index.ts rename to business/entities/teamCache/index.ts index 57d9f81a8..aef008643 100644 --- a/entities/teamCache/index.ts +++ b/business/entities/teamCache/index.ts @@ -4,7 +4,7 @@ // import { ITeamCacheProvider, ITeamCacheCreateOptions, TeamCacheProvider } from './teamCacheProvider'; -import { FixedQueryType, IEntityMetadataFixedQuery } from '../../lib/entityMetadataProvider/query'; +import { FixedQueryType, IEntityMetadataFixedQuery } from '../../../lib/entityMetadataProvider/query'; export async function CreateTeamCacheProviderInstance( options?: ITeamCacheCreateOptions diff --git a/entities/teamCache/teamCache.ts b/business/entities/teamCache/teamCache.ts similarity index 89% rename from entities/teamCache/teamCache.ts rename to business/entities/teamCache/teamCache.ts index f5f3f3ffb..99bb3592c 100644 --- a/entities/teamCache/teamCache.ts +++ b/business/entities/teamCache/teamCache.ts @@ -3,23 +3,23 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; +} from '../../../lib/entityMetadataProvider/declarations'; import { PostgresJsonEntityQuery, PostgresGetAllEntities, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; +} from '../../../lib/entityMetadataProvider/postgres'; import { TeamCacheFixedQueryByOrganizationId, TeamCacheDeleteByOrganizationId } from '.'; -import { stringOrNumberAsString } from '../../utils'; -import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; -import { TableConfiguration } from '../../lib/entityMetadataProvider'; +import { stringOrNumberAsString } from '../../../lib/utils'; +import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +import { TableConfiguration } from '../../../lib/entityMetadataProvider'; const type = new EntityMetadataType('TeamCache'); diff --git a/entities/teamCache/teamCacheProvider.ts b/business/entities/teamCache/teamCacheProvider.ts similarity index 98% rename from entities/teamCache/teamCacheProvider.ts rename to business/entities/teamCache/teamCacheProvider.ts index dc29686b8..326aca957 100644 --- a/entities/teamCache/teamCacheProvider.ts +++ b/business/entities/teamCache/teamCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { TeamCacheEntity } from './teamCache'; import { TeamCacheFixedQueryAll, diff --git a/entities/teamJoinApproval/approvalProvider.ts b/business/entities/teamJoinApproval/approvalProvider.ts similarity index 90% rename from entities/teamJoinApproval/approvalProvider.ts rename to business/entities/teamJoinApproval/approvalProvider.ts index 95a9acaad..7e3988fc6 100644 --- a/entities/teamJoinApproval/approvalProvider.ts +++ b/business/entities/teamJoinApproval/approvalProvider.ts @@ -4,7 +4,7 @@ // import { TeamJoinApprovalEntity } from './teamJoinApproval'; -import { IEntityMetadataProvider } from '../../lib/entityMetadataProvider/entityMetadataProvider'; +import { IEntityMetadataProvider } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; export interface IApprovalProvider { initialize(): Promise; diff --git a/entities/teamJoinApproval/index.ts b/business/entities/teamJoinApproval/index.ts similarity index 63% rename from entities/teamJoinApproval/index.ts rename to business/entities/teamJoinApproval/index.ts index a7936f8bd..ec378ba3c 100644 --- a/entities/teamJoinApproval/index.ts +++ b/business/entities/teamJoinApproval/index.ts @@ -3,11 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { - IApprovalProvider, - IApprovalProviderCreateOptions, -} from '../../entities/teamJoinApproval/approvalProvider'; -import { TeamJoinApprovalProvider } from '../../entities/teamJoinApproval/teamJoinApprovalProvider'; +import { IApprovalProvider, IApprovalProviderCreateOptions } from './approvalProvider'; +import { TeamJoinApprovalProvider } from './teamJoinApprovalProvider'; export async function createAndInitializeApprovalProviderInstance( options: IApprovalProviderCreateOptions diff --git a/entities/teamJoinApproval/teamJoinApproval.ts b/business/entities/teamJoinApproval/teamJoinApproval.ts similarity index 96% rename from entities/teamJoinApproval/teamJoinApproval.ts rename to business/entities/teamJoinApproval/teamJoinApproval.ts index e9a049b2b..443d39372 100644 --- a/entities/teamJoinApproval/teamJoinApproval.ts +++ b/business/entities/teamJoinApproval/teamJoinApproval.ts @@ -5,22 +5,22 @@ import { randomUUID } from 'crypto'; -import { IObjectWithDefinedKeys } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IObjectWithDefinedKeys } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; import { MetadataMappingDefinition, EntityMetadataMappings, -} from '../../lib/entityMetadataProvider/declarations'; -import { FixedQueryType, IEntityMetadataFixedQuery } from '../../lib/entityMetadataProvider/query'; -import { stringOrNumberAsString, stringOrNumberArrayAsStringArray } from '../../utils'; +} from '../../../lib/entityMetadataProvider/declarations'; +import { FixedQueryType, IEntityMetadataFixedQuery } from '../../../lib/entityMetadataProvider/query'; +import { stringOrNumberAsString, stringOrNumberArrayAsStringArray } from '../../../lib/utils'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; -import { TableSettings } from '../../lib/entityMetadataProvider/table'; -import { MemorySettings } from '../../lib/entityMetadataProvider/memory'; +} from '../../../lib/entityMetadataProvider/postgres'; +import { TableSettings } from '../../../lib/entityMetadataProvider/table'; +import { MemorySettings } from '../../../lib/entityMetadataProvider/memory'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; const type = new EntityMetadataType('TeamJoinRequest'); diff --git a/entities/teamJoinApproval/teamJoinApprovalProvider.ts b/business/entities/teamJoinApproval/teamJoinApprovalProvider.ts similarity index 98% rename from entities/teamJoinApproval/teamJoinApprovalProvider.ts rename to business/entities/teamJoinApproval/teamJoinApprovalProvider.ts index 2cf004b0f..1a5bb4691 100644 --- a/entities/teamJoinApproval/teamJoinApprovalProvider.ts +++ b/business/entities/teamJoinApproval/teamJoinApprovalProvider.ts @@ -7,7 +7,7 @@ import { IApprovalProvider } from './approvalProvider'; import { IEntityMetadataBaseOptions, EntityMetadataBase, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { TeamJoinApprovalEntity, TeamJoinRequestFixedQueryByTeam, diff --git a/entities/teamMemberCache/index.ts b/business/entities/teamMemberCache/index.ts similarity index 95% rename from entities/teamMemberCache/index.ts rename to business/entities/teamMemberCache/index.ts index 652f1b78a..d799cc026 100644 --- a/entities/teamMemberCache/index.ts +++ b/business/entities/teamMemberCache/index.ts @@ -8,7 +8,7 @@ import { ITeamMemberCacheCreateOptions, TeamMemberCacheProvider, } from './teamMemberCacheProvider'; -import { FixedQueryType, IEntityMetadataFixedQuery } from '../../lib/entityMetadataProvider/query'; +import { FixedQueryType, IEntityMetadataFixedQuery } from '../../../lib/entityMetadataProvider/query'; export async function CreateTeamMemberCacheProviderInstance( options?: ITeamMemberCacheCreateOptions @@ -64,7 +64,10 @@ export class TeamMemberCacheFixedQueryByUserId implements IEntityMetadataFixedQu export class TeamMemberCacheFixedQueryByOrganizationIdAndUserId implements IEntityMetadataFixedQuery { public readonly fixedQueryType: FixedQueryType = FixedQueryType.TeamMemberCacheGetByOrganizationIdAndUserId; - constructor(public organizationId: string, public userId: string) { + constructor( + public organizationId: string, + public userId: string + ) { if (typeof this.userId !== 'string') { throw new Error(`userId ${userId} must be a string`); } diff --git a/entities/teamMemberCache/teamMemberCache.ts b/business/entities/teamMemberCache/teamMemberCache.ts similarity index 91% rename from entities/teamMemberCache/teamMemberCache.ts rename to business/entities/teamMemberCache/teamMemberCache.ts index 2cffaaa20..3a7c107a6 100644 --- a/entities/teamMemberCache/teamMemberCache.ts +++ b/business/entities/teamMemberCache/teamMemberCache.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityField } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { EntityField } from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../../lib/entityMetadataProvider/declarations'; +} from '../../../lib/entityMetadataProvider/declarations'; import { TeamMemberCacheFixedQueryByOrganizationId, TeamMemberCacheFixedQueryByUserId, @@ -17,16 +17,16 @@ import { TeamMemberCacheFixedQueryByOrganizationIdAndUserId, TeamMemberCacheDeleteByOrganizationId, } from '.'; -import { GitHubTeamRole } from '../../interfaces'; +import { GitHubTeamRole } from '../../../interfaces'; import { PostgresGetAllEntities, PostgresJsonEntityQuery, PostgresSettings, PostgresConfiguration, -} from '../../lib/entityMetadataProvider/postgres'; -import { stringOrNumberAsString } from '../../utils'; -import { MemoryConfiguration, MemorySettings } from '../../lib/entityMetadataProvider/memory'; -import { TableConfiguration } from '../../lib/entityMetadataProvider'; +} from '../../../lib/entityMetadataProvider/postgres'; +import { stringOrNumberAsString } from '../../../lib/utils'; +import { MemoryConfiguration, MemorySettings } from '../../../lib/entityMetadataProvider/memory'; +import { TableConfiguration } from '../../../lib/entityMetadataProvider'; const type = new EntityMetadataType('TeamMemberCache'); diff --git a/entities/teamMemberCache/teamMemberCacheProvider.ts b/business/entities/teamMemberCache/teamMemberCacheProvider.ts similarity index 99% rename from entities/teamMemberCache/teamMemberCacheProvider.ts rename to business/entities/teamMemberCache/teamMemberCacheProvider.ts index c9083fe39..dc109276a 100644 --- a/entities/teamMemberCache/teamMemberCacheProvider.ts +++ b/business/entities/teamMemberCache/teamMemberCacheProvider.ts @@ -7,7 +7,7 @@ import { IEntityMetadata, EntityMetadataBase, IEntityMetadataBaseOptions, -} from '../../lib/entityMetadataProvider/entityMetadata'; +} from '../../../lib/entityMetadataProvider/entityMetadata'; import { TeamMemberCacheEntity, EntityImplementation } from './teamMemberCache'; import { TeamMemberCacheFixedQueryAll, diff --git a/entities/token/index.ts b/business/entities/token/index.ts similarity index 90% rename from entities/token/index.ts rename to business/entities/token/index.ts index 98f14a4b0..5d152e2b7 100644 --- a/entities/token/index.ts +++ b/business/entities/token/index.ts @@ -5,7 +5,7 @@ import { TokenProvider } from './tokenProvider'; import { PersonalAccessToken } from './token'; -import { IEntityMetadataBaseOptions } from '../../lib/entityMetadataProvider/entityMetadata'; +import { IEntityMetadataBaseOptions } from '../../../lib/entityMetadataProvider/entityMetadata'; export interface ITokenProvider { initialize(): Promise; diff --git a/entities/token/token.ts b/business/entities/token/token.ts similarity index 92% rename from entities/token/token.ts rename to business/entities/token/token.ts index 0c427cee0..518dbe6db 100644 --- a/entities/token/token.ts +++ b/business/entities/token/token.ts @@ -5,25 +5,28 @@ import crypto from 'crypto'; -import { EntityField, IObjectWithDefinedKeys } from '../../lib/entityMetadataProvider/entityMetadataProvider'; -import { EntityMetadataType, IEntityMetadata } from '../../lib/entityMetadataProvider/entityMetadata'; +import { + EntityField, + IObjectWithDefinedKeys, +} from '../../../lib/entityMetadataProvider/entityMetadataProvider'; +import { EntityMetadataType, IEntityMetadata } from '../../../lib/entityMetadataProvider/entityMetadata'; import { MetadataMappingDefinition, EntityMetadataMappings, -} from '../../lib/entityMetadataProvider/declarations'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +} from '../../../lib/entityMetadataProvider/declarations'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { TokenGenerator } from './tokenGenerator'; import { QueryTokensByCorporateID } from './tokenProvider'; import { Type } from './type'; -import { TableSettings } from '../../lib/entityMetadataProvider/table'; -import { MemorySettings } from '../../lib/entityMetadataProvider/memory'; +import { TableSettings } from '../../../lib/entityMetadataProvider/table'; +import { MemorySettings } from '../../../lib/entityMetadataProvider/memory'; import { odata, TableEntityQueryOptions } from '@azure/data-tables'; import { PostgresConfiguration, PostgresJsonEntityQuery, PostgresSettings, -} from '../../lib/entityMetadataProvider/postgres'; -import type { ApiClientGroupDisplay } from '../../interfaces/api'; +} from '../../../lib/entityMetadataProvider/postgres'; +import type { ApiClientGroupDisplay } from '../../../interfaces/api'; const type = Type; @@ -167,6 +170,19 @@ export class PersonalAccessToken implements IObjectWithDefinedKeys, ITokenEntity return apis.includes(scope.toLowerCase()); } + hasAnyScope(scope: string[]) { + if (!this.scopes) { + return false; + } + const apis = this.scopes.toLowerCase().split(','); + for (let i = 0; i < scope.length; i++) { + if (apis.includes(scope[i].toLowerCase())) { + return true; + } + } + return false; + } + hasOrganizationScope(orgName: string) { if (!this.organizationScopes) { return false; diff --git a/entities/token/tokenGenerator.ts b/business/entities/token/tokenGenerator.ts similarity index 100% rename from entities/token/tokenGenerator.ts rename to business/entities/token/tokenGenerator.ts diff --git a/entities/token/tokenProvider.ts b/business/entities/token/tokenProvider.ts similarity index 95% rename from entities/token/tokenProvider.ts rename to business/entities/token/tokenProvider.ts index 19f61926d..6ad5b13bb 100644 --- a/entities/token/tokenProvider.ts +++ b/business/entities/token/tokenProvider.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataBase } from '../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataBase } from '../../../lib/entityMetadataProvider/entityMetadata'; import { PersonalAccessToken, EntityImplementation } from './token'; import { ITokenProvider, ITokenProviderCreateOptions } from '.'; -import { IEntityMetadataFixedQuery, FixedQueryType } from '../../lib/entityMetadataProvider/query'; +import { IEntityMetadataFixedQuery, FixedQueryType } from '../../../lib/entityMetadataProvider/query'; import { Type } from './type'; const thisProviderType = Type; diff --git a/entities/token/type.ts b/business/entities/token/type.ts similarity index 68% rename from entities/token/type.ts rename to business/entities/token/type.ts index 8d70d2f71..a0ca4ea4e 100644 --- a/entities/token/type.ts +++ b/business/entities/token/type.ts @@ -3,6 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { EntityMetadataType } from '../../lib/entityMetadataProvider/entityMetadata'; +import { EntityMetadataType } from '../../../lib/entityMetadataProvider/entityMetadata'; export const Type = new EntityMetadataType('Token'); diff --git a/entities/userSettings.ts b/business/entities/userSettings.ts similarity index 92% rename from entities/userSettings.ts rename to business/entities/userSettings.ts index 10a12a7a0..a8756c1c8 100644 --- a/entities/userSettings.ts +++ b/business/entities/userSettings.ts @@ -8,13 +8,13 @@ import { IEntityMetadataBaseOptions, EntityMetadataBase, IEntityMetadata, -} from '../lib/entityMetadataProvider/entityMetadata'; -import { QueryBase, IEntityMetadataFixedQuery } from '../lib/entityMetadataProvider/query'; +} from '../../lib/entityMetadataProvider/entityMetadata'; +import { QueryBase, IEntityMetadataFixedQuery } from '../../lib/entityMetadataProvider/query'; import { EntityMetadataMappings, MetadataMappingDefinition, -} from '../lib/entityMetadataProvider/declarations'; -import { PostgresConfiguration, PostgresSettings } from '../lib/entityMetadataProvider/postgres'; +} from '../../lib/entityMetadataProvider/declarations'; +import { PostgresConfiguration, PostgresSettings } from '../../lib/entityMetadataProvider/postgres'; const type = new EntityMetadataType('UserSettings'); const thisProviderType = type; @@ -33,7 +33,10 @@ class UserSettingsQueryBase extends QueryBase { } class UserSettingsQuery extends UserSettingsQueryBase { - constructor(query: Query, public parameters: T) { + constructor( + query: Query, + public parameters: T + ) { super(query); if (!this.parameters) { this.parameters = {} as T; diff --git a/features/index.ts b/business/features/index.ts similarity index 100% rename from features/index.ts rename to business/features/index.ts diff --git a/features/newRepositories/actions/createReadme.ts b/business/features/newRepositories/actions/createReadme.ts similarity index 93% rename from features/newRepositories/actions/createReadme.ts rename to business/features/newRepositories/actions/createReadme.ts index 738600562..1fb6fc636 100644 --- a/features/newRepositories/actions/createReadme.ts +++ b/business/features/newRepositories/actions/createReadme.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../../business'; -import { ErrorHelper } from '../../../transitional'; +import { Repository } from '../../..'; +import { ErrorHelper } from '../../../../lib/transitional'; import { setupRepositoryReadmeSubstring } from '../strings'; export async function tryCreateReadme(repository: Repository, log: string[]): Promise { diff --git a/features/newRepositories/actions/deleteFork.ts b/business/features/newRepositories/actions/deleteFork.ts similarity index 93% rename from features/newRepositories/actions/deleteFork.ts rename to business/features/newRepositories/actions/deleteFork.ts index e68aa7cef..a15ff479a 100644 --- a/features/newRepositories/actions/deleteFork.ts +++ b/business/features/newRepositories/actions/deleteFork.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../../business'; +import { Repository } from '../../..'; export async function immediatelyDeleteFork(log: string[], repository: Repository): Promise { const organization = repository.organization; diff --git a/features/newRepositories/actions/downgradeCollaborator.ts b/business/features/newRepositories/actions/downgradeCollaborator.ts similarity index 87% rename from features/newRepositories/actions/downgradeCollaborator.ts rename to business/features/newRepositories/actions/downgradeCollaborator.ts index 127826cf6..ad1698e02 100644 --- a/features/newRepositories/actions/downgradeCollaborator.ts +++ b/business/features/newRepositories/actions/downgradeCollaborator.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../../business'; -import { GitHubRepositoryPermission } from '../../../interfaces'; +import { Repository } from '../../..'; +import { GitHubRepositoryPermission } from '../../../../interfaces'; export async function tryDowngradeCollaborator( repository: Repository, diff --git a/features/newRepositories/actions/dropCollaborator.ts b/business/features/newRepositories/actions/dropCollaborator.ts similarity index 93% rename from features/newRepositories/actions/dropCollaborator.ts rename to business/features/newRepositories/actions/dropCollaborator.ts index 2382c1b3a..508aef375 100644 --- a/features/newRepositories/actions/dropCollaborator.ts +++ b/business/features/newRepositories/actions/dropCollaborator.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../../business'; +import { Repository } from '../../..'; export async function tryDropCollaborator( repository: Repository, diff --git a/features/newRepositories/actions/dropTeam.ts b/business/features/newRepositories/actions/dropTeam.ts similarity index 93% rename from features/newRepositories/actions/dropTeam.ts rename to business/features/newRepositories/actions/dropTeam.ts index 186a73566..62af1b5ef 100644 --- a/features/newRepositories/actions/dropTeam.ts +++ b/business/features/newRepositories/actions/dropTeam.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository, Team } from '../../../business'; +import { Repository, Team } from '../../..'; export async function tryDropTeam(repository: Repository, team: Team, log: string[]): Promise { const organization = repository.organization; diff --git a/features/newRepositories/actions/index.ts b/business/features/newRepositories/actions/index.ts similarity index 100% rename from features/newRepositories/actions/index.ts rename to business/features/newRepositories/actions/index.ts diff --git a/features/newRepositories/actions/lockdown.ts b/business/features/newRepositories/actions/lockdown.ts similarity index 84% rename from features/newRepositories/actions/lockdown.ts rename to business/features/newRepositories/actions/lockdown.ts index 212537b83..de6d28b23 100644 --- a/features/newRepositories/actions/lockdown.ts +++ b/business/features/newRepositories/actions/lockdown.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../../business'; -import { GitHubCollaboratorAffiliationQuery } from '../../../interfaces'; +import { Repository } from '../../..'; +import { GitHubCollaboratorAffiliationQuery } from '../../../../interfaces'; import { tryDowngradeCollaborator } from './downgradeCollaborator'; import { tryDropCollaborator } from './dropCollaborator'; import { tryDropTeam } from './dropTeam'; @@ -18,9 +18,9 @@ export async function lockdownRepository( const organization = repository.organization; try { const specialPermittedTeams = new Set([ - ...organization.specialRepositoryPermissionTeams.admin, - ...organization.specialRepositoryPermissionTeams.write, - ...organization.specialRepositoryPermissionTeams.read, + ...organization.specialSystemTeams.admin, + ...organization.specialSystemTeams.write, + ...organization.specialSystemTeams.read, ]); const teamPermissions = await repository.getTeamPermissions(); for (const tp of teamPermissions) { @@ -42,7 +42,7 @@ export async function lockdownRepository( if (collaborator.login.toLowerCase() !== creatorLogin.toLowerCase()) { await tryDropCollaborator(repository, collaborator.login, log); } else { - // Downgrade the creator to only having READ access (V2) + // Downgrade the creator to only having READ access if (collaborator.permissions.admin || collaborator.permissions.push) { await tryDowngradeCollaborator(repository, collaborator.login, log); } else { diff --git a/features/newRepositories/approve.ts b/business/features/newRepositories/approve.ts similarity index 97% rename from features/newRepositories/approve.ts rename to business/features/newRepositories/approve.ts index 051711e10..ec731b651 100644 --- a/features/newRepositories/approve.ts +++ b/business/features/newRepositories/approve.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Repository } from '../../business'; +import { Operations, Repository } from '../..'; import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; -import { ICachedEmployeeInformation, RepositoryLockdownState } from '../../interfaces'; -import { IMail } from '../../lib/mailProvider'; +import { ICachedEmployeeInformation, RepositoryLockdownState } from '../../../interfaces'; +import { IMail } from '../../../lib/mailProvider'; import { IMailToRemoveAdministrativeLock } from './interfaces'; export async function administrativeApproval( diff --git a/features/newRepositories/initializeMetadata.ts b/business/features/newRepositories/initializeMetadata.ts similarity index 84% rename from features/newRepositories/initializeMetadata.ts rename to business/features/newRepositories/initializeMetadata.ts index ef6217d42..fd53feef0 100644 --- a/features/newRepositories/initializeMetadata.ts +++ b/business/features/newRepositories/initializeMetadata.ts @@ -4,7 +4,8 @@ // import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; -import { GitHubRepositoryVisibility, ICorporateLink } from '../../interfaces'; +import { GitHubRepositoryVisibility, ICorporateLink } from '../../../interfaces'; +import { ErrorHelper } from '../../../lib/transitional'; import { RepositoryLockdownCreateOptions } from './interfaces'; export async function initializeRepositoryMetadata(parameters: RepositoryLockdownCreateOptions) { @@ -19,7 +20,7 @@ export async function initializeRepositoryMetadata(parameters: RepositoryLockdow instances, } = parameters; const { repository } = instances; - const { repositoryMetadataProvider } = providers; + const { insights, repositoryMetadataProvider } = providers; const { organization } = repository; try { // Repository metadata is used to lock down the security of the repository setup system. Only @@ -28,8 +29,20 @@ export async function initializeRepositoryMetadata(parameters: RepositoryLockdow let repositoryMetadata: RepositoryMetadataEntity = null; try { repositoryMetadata = await repositoryMetadataProvider.getRepositoryMetadata(String(repository.id)); - } catch (doesNotExist) { - // ignore: 404 is standard here + } catch (error) { + if (!ErrorHelper.IsNotFound(error)) { + insights?.trackException({ + exception: error, + properties: { + content: 'RepositoryMetadataProviderGetRepositoryMetadataError', + message: error.message, + repositoryId: repository.id.toString(), + repositoryName: repository.name, + organizationName: organization.name, + organizationId: organization.id.toString(), + }, + }); + } } if (repositoryMetadata) { lockdownLog.push(`Repository metadata already exists for repository ID ${repository.id}`); diff --git a/features/newRepositories/interfaces.ts b/business/features/newRepositories/interfaces.ts similarity index 86% rename from features/newRepositories/interfaces.ts rename to business/features/newRepositories/interfaces.ts index 7d5a19cea..d4c07f067 100644 --- a/features/newRepositories/interfaces.ts +++ b/business/features/newRepositories/interfaces.ts @@ -3,9 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Organization, Repository } from '../../business'; +import { TelemetryClient } from 'applicationinsights'; + +import { Operations, Organization, Repository } from '../..'; import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; -import { ICorporateLink, RepositoryLockdownState } from '../../interfaces'; +import { ICorporateLink, RepositoryLockdownState } from '../../../interfaces'; export enum RepositoryLockdownCreateType { Created = 'created', @@ -13,6 +15,7 @@ export enum RepositoryLockdownCreateType { } export type RepositoryLockdownCreateProviders = { + insights: TelemetryClient; operations: Operations; repositoryMetadataProvider: IRepositoryMetadataProvider; }; @@ -73,9 +76,10 @@ export interface IMailToLockdownRepo { isForkDeleted: boolean; } -export interface INewRepositoryLockdownSystemOptions { +export type NewRepositoryLockdownSystemOptions = { + insights: TelemetryClient; operations: Operations; organization: Organization; repository: Repository; repositoryMetadataProvider: IRepositoryMetadataProvider; -} +}; diff --git a/features/newRepositories/lockdownMail.ts b/business/features/newRepositories/lockdownMail.ts similarity index 97% rename from features/newRepositories/lockdownMail.ts rename to business/features/newRepositories/lockdownMail.ts index 0fba395dc..ce4a9edbe 100644 --- a/features/newRepositories/lockdownMail.ts +++ b/business/features/newRepositories/lockdownMail.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Repository } from '../../business'; -import { ICachedEmployeeInformation, ICorporateLink, RepositoryLockdownState } from '../../interfaces'; -import { IMail } from '../../lib/mailProvider'; -import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; +import { Operations, Repository } from '../..'; +import { ICachedEmployeeInformation, ICorporateLink, RepositoryLockdownState } from '../../../interfaces'; +import { IMail } from '../../../lib/mailProvider'; +import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; import { ILockdownResult, IMailToLockdownRepo, RepositoryLockdownCreateType } from './interfaces'; const defaultMailTemplate = 'newrepolockdown'; diff --git a/features/newRepositories/newRepositoryLockdown.ts b/business/features/newRepositories/newRepositoryLockdown.ts similarity index 85% rename from features/newRepositories/newRepositoryLockdown.ts rename to business/features/newRepositories/newRepositoryLockdown.ts index 3ae9829de..4a5dfe90c 100644 --- a/features/newRepositories/newRepositoryLockdown.ts +++ b/business/features/newRepositories/newRepositoryLockdown.ts @@ -3,20 +3,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Organization, Repository } from '../../business'; +import { Operations, Organization, Repository } from '../..'; import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; -import { botBracket } from '../../utils'; +import { botBracket } from '../../../lib/utils'; import { ICorporateLink, RepositoryLockdownState, NoCacheNoBackground, OrganizationMembershipState, OrganizationMembershipRole, -} from '../../interfaces'; -import { CreateError } from '../../transitional'; +} from '../../../interfaces'; +import { CreateError } from '../../../lib/transitional'; import { ILockdownResult, - INewRepositoryLockdownSystemOptions, + NewRepositoryLockdownSystemOptions, IRepoPatch, RepositoryLockdownCreateOptions, RepositoryLockdownCreateType, @@ -29,8 +29,10 @@ import { setupRepositorySubstring } from './strings'; import { immediatelyDeleteFork, tryCreateReadme } from './actions'; import { repositoryLockdownStatics } from './staticFunctions'; import { lockdownRepository } from './actions/lockdown'; +import { TelemetryClient } from 'applicationinsights'; export default class NewRepositoryLockdownSystem { + insights: TelemetryClient; organization: Organization; operations: Operations; repository: Repository; @@ -40,7 +42,8 @@ export default class NewRepositoryLockdownSystem { private readonly lockdownForks: boolean; private readonly lockdownTransfers: boolean; - constructor(options: INewRepositoryLockdownSystemOptions) { + constructor(options: NewRepositoryLockdownSystemOptions) { + this.insights = options.insights; this.organization = options.organization; this.operations = options.operations; this.repository = options.repository; @@ -108,6 +111,7 @@ export default class NewRepositoryLockdownSystem { repository: this.repository, }, providers: { + insights: this.insights, repositoryMetadataProvider: this.repositoryMetadataProvider, operations: this.operations, }, @@ -162,20 +166,22 @@ export default class NewRepositoryLockdownSystem { if (!this.organization.isNewRepositoryLockdownSystemEnabled()) { return { wasLocked: false, notifyOperations: false }; } - lockdownLog.push( - `Confirmed that the ${this.organization.name} organization has opted into the new repository lockdown system` - ); - if (this.deleteForks) { - lockdownLog.push( - 'Confirmed that the delete fork feature is enabled for this org. It will supersede fork lockdown capabilities.' - ); - } - if (this.lockdownForks) { - lockdownLog.push('Confirmed that the additional fork lockdown feature is enabled for this org'); - } - if (this.lockdownTransfers) { - lockdownLog.push('Confirmed that the additional transfer lockdown feature is enabled for this org'); - } + // informationalLog.push( + // `Confirmed that the ${this.organization.name} organization has opted into the new repository lockdown system` + // ); + // if (this.deleteForks) { + // informationalLog.push( + // 'Confirmed that the delete fork feature is enabled for this org. It will supersede fork lockdown capabilities.' + // ); + // } + // if (this.lockdownForks) { + // informationalLog.push('Confirmed that the additional fork lockdown feature is enabled for this org'); + // } + // if (this.lockdownTransfers) { + // informationalLog.push( + // 'Confirmed that the additional transfer lockdown feature is enabled for this org' + // ); + // } const setupUrl = `${this.organization.absoluteBaseUrl}wizard?existingreponame=${this.repository.name}&existingrepoid=${this.repository.id}`; const isTransfer = action === RepositoryLockdownCreateType.Transferred; if (isTransfer && !this.lockdownTransfers) { @@ -198,7 +204,7 @@ export default class NewRepositoryLockdownSystem { lockdownLog.push(`Created by a bot or GitHub App: ${username}`); return { wasLocked: false, log: lockdownLog, notifyOperations: false }; } - lockdownLog.push(`Confirmed that the repository was not ${action} by a bot`); + // informationalLog.push(`Confirmed that the repository was not ${action} by a bot`); // a repository created by one of the operations accounts in the allowed list is OK and will not be locked down const systemAccounts = new Set( this.operations.systemAccountsByUsername.map((username) => username.toLowerCase()) @@ -207,11 +213,11 @@ export default class NewRepositoryLockdownSystem { lockdownLog.push(`Created by a system account: ${username}`); return { wasLocked: false, log: lockdownLog, notifyOperations: true }; } - lockdownLog.push( - `Confirmed that the repository was not ${action} by any of the system accounts: ${Array.from( - systemAccounts.values() - ).join(', ')}` - ); + // informationalLog.push( + // `Confirmed that the repository was not ${action} by any of the system accounts: ${Array.from( + // systemAccounts.values() + // ).join(', ')}` + // ); const userMembership = await this.organization.getMembership(username, NoCacheNoBackground); let userIsOrganizationOwner = false; if ( @@ -261,13 +267,13 @@ export default class NewRepositoryLockdownSystem { const patchChanges: IRepoPatch = {}; if (!isFork && !isTransfer && !this.repository.private) { - lockdownLog.push('Preparing to hide the public repository pending setup (V2)'); + // informationalLog.push('Preparing to hide the public repository pending setup'); patchChanges.private = true; } if (!isFork) { - lockdownLog.push('Updating the description and web site to point at the setup wizard (V2)'); - lockdownLog.push(`Will direct the user to ${setupUrl}`); - patchChanges.description = `${setupRepositorySubstring} ${setupUrl}`; + // informationalLog.push('Updating the description and web site to point at the setup wizard'); + // informationalLog.push(`Will direct the user to ${setupUrl}`); + patchChanges.description = setupRepositorySubstring; patchChanges.homepage = setupUrl; } if (Object.getOwnPropertyNames(patchChanges).length > 0) { @@ -280,7 +286,7 @@ export default class NewRepositoryLockdownSystem { lockdownLog.push(`Updating repository with patch ${descriptiveUpdate}`); await this.repository.update(patchChanges); } catch (hideError) { - lockdownLog.push(`Error while trying to update the new repo: ${hideError} (V2)`); + lockdownLog.push(`Error while trying to update the new repo: ${hideError}`); } } } diff --git a/features/newRepositories/selfServiceDelete.ts b/business/features/newRepositories/selfServiceDelete.ts similarity index 97% rename from features/newRepositories/selfServiceDelete.ts rename to business/features/newRepositories/selfServiceDelete.ts index 9d4374c6d..9e5fbbdb2 100644 --- a/features/newRepositories/selfServiceDelete.ts +++ b/business/features/newRepositories/selfServiceDelete.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Operations, Repository } from '../../business'; +import { Operations, Repository } from '../..'; import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; -import { ICachedEmployeeInformation, RepositoryLockdownState } from '../../interfaces'; -import { IMail } from '../../lib/mailProvider'; +import { ICachedEmployeeInformation, RepositoryLockdownState } from '../../../interfaces'; +import { IMail } from '../../../lib/mailProvider'; export async function selfServiceDeleteLockedRepository( operations: Operations, diff --git a/features/newRepositories/staticFunctions.ts b/business/features/newRepositories/staticFunctions.ts similarity index 90% rename from features/newRepositories/staticFunctions.ts rename to business/features/newRepositories/staticFunctions.ts index 2044ce2c3..d5e225f6b 100644 --- a/features/newRepositories/staticFunctions.ts +++ b/business/features/newRepositories/staticFunctions.ts @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Repository } from '../../business'; +import { Repository } from '../..'; import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; -import { IndividualContext } from '../../business/user'; +import { IndividualContext } from '../../user'; import { validateUserCanSelfDeleteRepository } from './validateSelfServiceDelete'; import { validateUserCanConfigureRepository } from './validateSelfServiceSetup'; diff --git a/features/newRepositories/strings.ts b/business/features/newRepositories/strings.ts similarity index 100% rename from features/newRepositories/strings.ts rename to business/features/newRepositories/strings.ts diff --git a/features/newRepositories/validateSelfServiceDelete.ts b/business/features/newRepositories/validateSelfServiceDelete.ts similarity index 90% rename from features/newRepositories/validateSelfServiceDelete.ts rename to business/features/newRepositories/validateSelfServiceDelete.ts index d16bf6be3..e1f3cc714 100644 --- a/features/newRepositories/validateSelfServiceDelete.ts +++ b/business/features/newRepositories/validateSelfServiceDelete.ts @@ -5,11 +5,11 @@ import { DateTime } from 'luxon'; -import { Repository } from '../../business'; +import { Repository } from '../..'; import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; -import { RepositoryLockdownState } from '../../interfaces'; -import { IndividualContext } from '../../business/user'; -import { daysInMilliseconds } from '../../utils'; +import { RepositoryLockdownState } from '../../../interfaces'; +import { IndividualContext } from '../../user'; +import { daysInMilliseconds } from '../../../lib/utils'; export async function validateUserCanSelfDeleteRepository( repository: Repository, diff --git a/features/newRepositories/validateSelfServiceSetup.ts b/business/features/newRepositories/validateSelfServiceSetup.ts similarity index 94% rename from features/newRepositories/validateSelfServiceSetup.ts rename to business/features/newRepositories/validateSelfServiceSetup.ts index dcb08455e..edbd2cd04 100644 --- a/features/newRepositories/validateSelfServiceSetup.ts +++ b/business/features/newRepositories/validateSelfServiceSetup.ts @@ -4,8 +4,8 @@ // import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; -import { RepositoryLockdownState } from '../../interfaces'; -import { IndividualContext } from '../../business/user'; +import { RepositoryLockdownState } from '../../../interfaces'; +import { IndividualContext } from '../../user'; export async function validateUserCanConfigureRepository( metadata: RepositoryMetadataEntity, diff --git a/features/publicReposFastFilter.ts b/business/features/publicReposFastFilter.ts similarity index 94% rename from features/publicReposFastFilter.ts rename to business/features/publicReposFastFilter.ts index b876c57f2..e481faf57 100644 --- a/features/publicReposFastFilter.ts +++ b/business/features/publicReposFastFilter.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IProviders } from '../interfaces'; -import { Repository } from '../business'; +import { IProviders } from '../../interfaces'; +import { Repository } from '..'; // TODO: refresh occasionally. diff --git a/features/sudo/index.ts b/business/features/sudo/index.ts similarity index 90% rename from features/sudo/index.ts rename to business/features/sudo/index.ts index 8d8791024..f6eddcbcd 100644 --- a/features/sudo/index.ts +++ b/business/features/sudo/index.ts @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import type { Organization } from '../../business'; -import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import { ICorporateLink, IProviders } from '../../interfaces'; +import type { Organization } from '../..'; +import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; +import { ICorporateLink, IProviders } from '../../../interfaces'; export interface IOrganizationSudo { isSudoer(githubLogin: string, link?: ICorporateLink): Promise; @@ -16,7 +16,10 @@ export interface IPortalSudo { } export abstract class OrganizationSudo implements IOrganizationSudo { - constructor(protected providers: IProviders, protected organization: Organization) {} + constructor( + protected providers: IProviders, + protected organization: Organization + ) {} abstract isSudoer(githubLogin: string, link?: ICorporateLink): Promise; protected isSudoEnvironmentOff() { diff --git a/features/sudo/noop.ts b/business/features/sudo/noop.ts similarity index 65% rename from features/sudo/noop.ts rename to business/features/sudo/noop.ts index 88df28d77..8db9f7c00 100644 --- a/features/sudo/noop.ts +++ b/business/features/sudo/noop.ts @@ -4,11 +4,14 @@ // import { OrganizationSudo } from '.'; -import { Organization } from '../../business'; -import { ICorporateLink, IProviders } from '../../interfaces'; +import { Organization } from '../..'; +import { ICorporateLink, IProviders } from '../../../interfaces'; export class OrganizationSudoNoop extends OrganizationSudo { - constructor(protected providers: IProviders, protected organization: Organization) { + constructor( + protected providers: IProviders, + protected organization: Organization + ) { super(providers, organization); } diff --git a/features/sudo/portal.ts b/business/features/sudo/portal.ts similarity index 94% rename from features/sudo/portal.ts rename to business/features/sudo/portal.ts index b87cd0635..dec705167 100644 --- a/features/sudo/portal.ts +++ b/business/features/sudo/portal.ts @@ -4,10 +4,10 @@ // import { IPortalSudo } from '.'; -import { Organization } from '../../business'; -import { IProviders, ICorporateLink } from '../../interfaces'; -import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import { ErrorHelper } from '../../transitional'; +import { Organization } from '../..'; +import { IProviders, ICorporateLink } from '../../../interfaces'; +import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; +import { ErrorHelper } from '../../../lib/transitional'; abstract class PortalSudoBase { constructor(private providers: IProviders) {} diff --git a/features/sudo/securityGroup.ts b/business/features/sudo/securityGroup.ts similarity index 93% rename from features/sudo/securityGroup.ts rename to business/features/sudo/securityGroup.ts index c650ed480..81b7fdc39 100644 --- a/features/sudo/securityGroup.ts +++ b/business/features/sudo/securityGroup.ts @@ -4,9 +4,9 @@ // import { OrganizationSudo } from '.'; -import { Organization } from '../../business'; -import { IProviders, ICorporateLink } from '../../interfaces'; -import { ErrorHelper } from '../../transitional'; +import { Organization } from '../..'; +import { IProviders, ICorporateLink } from '../../../interfaces'; +import { ErrorHelper } from '../../../lib/transitional'; export const OrganizationFeatureSecurityGroupProperty = 'orgsudosecuritygroup'; diff --git a/features/sudo/sudo.md b/business/features/sudo/sudo.md similarity index 90% rename from features/sudo/sudo.md rename to business/features/sudo/sudo.md index ff567cde5..fca93b503 100644 --- a/features/sudo/sudo.md +++ b/business/features/sudo/sudo.md @@ -33,11 +33,6 @@ Overrides are available to allow the company-specific system to provide the org sudo instance for an organization, if you wish to implement a different approach, or use a different company-internal system for these decisions. -### Debug flags - -There is an environmental off-switch enabled that can turn off sudo, allowing for testing -as a regular user in local environments. That env variable name is `DEBUG_GITHUB_ORG_SUDO_OFF`. - ## portal sudo Portal sudo applies sudo for all organizations configured within the application. @@ -46,7 +41,7 @@ Used by system administrators typically. The original design was to use the sudo configuration from the first/primary GitHub org that was configured in the environment. -### Feature flag: FEATURE_FLAG_ALLOW_PORTAL_SUDO +## Feature flag: FEATURE_FLAG_ALLOW_PORTAL_SUDO > This feature is not on by default. @@ -63,7 +58,7 @@ Can be: For the security group provider, configuration should set `SUDO_PORTAL_SECURITY_GROUP_ID` to the security group ID to use. -### Debug flags +## Debug flags: portal sudo Two environment variables designed for development work exist: diff --git a/features/sudo/teams.ts b/business/features/sudo/teams.ts similarity index 91% rename from features/sudo/teams.ts rename to business/features/sudo/teams.ts index f15a48536..ed4758cbb 100644 --- a/features/sudo/teams.ts +++ b/business/features/sudo/teams.ts @@ -4,9 +4,9 @@ // import { OrganizationSudo } from '.'; -import { Organization } from '../../business'; -import { IProviders, ICorporateLink, GitHubTeamRole, ITeamMembershipRoleState } from '../../interfaces'; -import { ErrorHelper } from '../../transitional'; +import { Organization } from '../..'; +import { IProviders, ICorporateLink, GitHubTeamRole, ITeamMembershipRoleState } from '../../../interfaces'; +import { ErrorHelper } from '../../../lib/transitional'; export class OrganizationSudoGitHubTeams extends OrganizationSudo { constructor(providers: IProviders, organization: Organization) { diff --git a/features/teamMemberToMaintainerUpgrade.ts b/business/features/teamMemberToMaintainerUpgrade.ts similarity index 96% rename from features/teamMemberToMaintainerUpgrade.ts rename to business/features/teamMemberToMaintainerUpgrade.ts index f3f3f0d68..5ed5daff4 100644 --- a/features/teamMemberToMaintainerUpgrade.ts +++ b/business/features/teamMemberToMaintainerUpgrade.ts @@ -3,18 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Team } from '../business'; -import { Operations } from '../business'; -import { IndividualContext } from '../business/user'; -import { addArrayToSet } from '../utils'; -import { IMail } from '../lib/mailProvider'; +import { Team } from '..'; +import { Operations } from '..'; +import { IndividualContext } from '../user'; +import { addArrayToSet } from '../../lib/utils'; +import { IMail } from '../../lib/mailProvider'; import { NoCacheNoBackground, ITeamMembershipRoleState, OrganizationMembershipState, GitHubTeamRole, -} from '../interfaces'; -import { ErrorHelper } from '../transitional'; +} from '../../interfaces'; +import { ErrorHelper } from '../../lib/transitional'; interface ISelfServiceAllowedResult { currentMaintainerCount: number; diff --git a/business/githubApps/index.ts b/business/githubApps/index.ts deleted file mode 100644 index 7f1ddfdec..000000000 --- a/business/githubApps/index.ts +++ /dev/null @@ -1,151 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { IReposApplication } from '../../interfaces'; -import { CreateError } from '../../transitional'; - -import Debug from 'debug'; -const debug = Debug('github:tokens'); - -export enum AppPurpose { - Data = 'Data', - CustomerFacing = 'CustomerFacing', - Operations = 'Operations', - BackgroundJobs = 'BackgroundJobs', // "secondary" / "default" fallback - Updates = 'Updates', - Security = 'Security', - ActionsData = 'ActionsData', -} - -export interface ICustomAppPurpose { - isCustomAppPurpose: boolean; // basic type check - id: string; - name: string; - getForOrganizationName?(organizationName: string): IGitHubAppConfiguration; - getApplicationConfigurationForInitialization?(): IGitHubAppConfiguration; -} - -export type AppPurposeTypes = AppPurpose | ICustomAppPurpose; - -export abstract class CustomAppPurpose implements ICustomAppPurpose { - get isCustomAppPurpose() { - return true; - } - constructor(public id: string, public name: string) {} -} - -export class CustomAppPurposeOrganizationVariance extends CustomAppPurpose { - fallbackIfNotConfiguredOrganizationName = false; - constructor(public id: string, public name: string, private configurations: IGitHubAppConfiguration[]) { - super(id, name); - } - getForOrganizationName(organizationName: string) { - const configuration = this.configurations.find( - (c) => c.specificOrganizationName.toLowerCase() === organizationName.toLowerCase() - ); - if (!configuration && this.fallbackIfNotConfiguredOrganizationName === false) { - throw CreateError.NotFound(`No configuration found for organization ${organizationName}`); - } - return configuration || this.configurations[0]; - } -} - -export class CustomAppPurposeSingleConfiguration extends CustomAppPurpose { - constructor(public id: string, public name: string, private configuration: IGitHubAppConfiguration) { - super(id, name); - } - - getApplicationConfigurationForInitialization() { - return this.configuration; - } -} - -export const DefinedAppPurposes = [ - AppPurpose.Data, - AppPurpose.CustomerFacing, - AppPurpose.Operations, - AppPurpose.BackgroundJobs, - AppPurpose.Updates, - AppPurpose.Security, - AppPurpose.ActionsData, -]; - -// export const GitHubAppPurposesExemptFromAllRepositoriesSelection = [AppPurpose.Onboarding]; - -const appPurposeToConfigurationName = { - [AppPurpose.Data]: 'data', - [AppPurpose.CustomerFacing]: 'ui', - [AppPurpose.Operations]: 'operations', - [AppPurpose.BackgroundJobs]: 'jobs', - [AppPurpose.Updates]: 'updates', - [AppPurpose.Security]: 'security', - [AppPurpose.ActionsData]: 'actions', -}; - -export function getAppPurposeId(purpose: AppPurposeTypes) { - if ((purpose as ICustomAppPurpose).isCustomAppPurpose === true) { - return (purpose as ICustomAppPurpose).id; - } - const asPurpose = purpose as AppPurpose; - const id = appPurposeToConfigurationName[asPurpose]; - if (!id) { - throw new Error(`No configuration name for purpose ${asPurpose}`); - } - return id; -} - -export class GitHubAppPurposes { - private static _instance: GitHubAppPurposes = new GitHubAppPurposes(); - - static get AllAvailableAppPurposes() { - debug(`Retrieving all available purposes (${this._instance._purposes.length})`); - return this._instance._purposes; - } - - static RegisterCustomPurpose(purpose: ICustomAppPurpose) { - debug(`Registering custom purpose ${purpose.id} (${purpose.name})`); - if (purpose.isCustomAppPurpose !== true) { - throw new Error('Purpose must have `isCustomAppPurpose` set to true'); - } - if ( - (this._instance._purposes as ICustomAppPurpose[]) - .filter((p) => (p as ICustomAppPurpose)?.isCustomAppPurpose === true) - .find((p) => p.id === purpose.id) - ) { - throw new Error(`Purpose with ID ${purpose.id} already registered`); - } - this._instance._purposes.push(purpose); - } - - private _purposes: AppPurposeTypes[]; - - constructor() { - this._purposes = [...DefinedAppPurposes]; - } -} - -export enum GitHubAppAuthenticationType { - ForceSpecificInstallation = 'force', - BestAvailable = 'best', -} - -export interface IGitHubAppConfiguration { - clientId?: string; - clientSecret?: string; - appId?: number; - appKey?: string; - appKeyFile?: string; - webhookSecret?: string; - slug?: string; - description?: string; - baseUrl?: string; - - specificOrganizationName?: string; -} - -export interface IGitHubAppsOptions { - app: IReposApplication; - configurations: Map; -} diff --git a/business/graphManager.ts b/business/graphManager.ts index eb3624736..a0e0cdc2c 100644 --- a/business/graphManager.ts +++ b/business/graphManager.ts @@ -18,7 +18,7 @@ import { IPagedCrossOrganizationCacheOptions, GitHubRepositoryPermission, } from '../interfaces'; -import { isPermissionBetterThan } from '../transitional'; +import { isPermissionBetterThan } from '../lib/transitional'; interface ILocalLinksCache { updated: moment.Moment; diff --git a/business/operations/administration.ts b/business/operations/administration.ts index 6cc984d31..139f7e830 100644 --- a/business/operations/administration.ts +++ b/business/operations/administration.ts @@ -4,7 +4,7 @@ // import { IProviders } from '../../interfaces'; -import { ErrorHelper } from '../../transitional'; +import { ErrorHelper } from '../../lib/transitional'; export async function isAuthorizedSystemAdministrator( providers: IProviders, diff --git a/business/operations/core.ts b/business/operations/core.ts index 6b4e0fdd4..161e2164e 100644 --- a/business/operations/core.ts +++ b/business/operations/core.ts @@ -3,9 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { OrganizationSetting } from '../../entities/organizationSettings/organizationSetting'; -import { GitHubAppAuthenticationType, AppPurpose, ICustomAppPurpose, AppPurposeTypes } from '../githubApps'; -import { GitHubTokenManager } from '../githubApps/tokenManager'; +import { OrganizationSetting } from '../entities/organizationSettings/organizationSetting'; +import { + GitHubAppAuthenticationType, + AppPurpose, + ICustomAppPurpose, + AppPurposeTypes, +} from '../../lib/github/appPurposes'; +import { GitHubTokenManager } from '../../lib/github/tokenManager'; import { IProviders, ICacheDefaultTimes, @@ -19,22 +24,48 @@ import { throwIfNotGitHubCapable, throwIfNotCapable, IOperationsCentralOperationsToken, - IAuthorizationHeaderValue, + AuthorizationHeaderValue, SiteConfiguration, + ExecutionEnvironment, + IPagedCacheOptions, + ICacheOptionsWithPurpose, } from '../../interfaces'; import { RestLibrary } from '../../lib/github'; -import { CreateError } from '../../transitional'; -import { wrapError } from '../../utils'; +import { CreateError } from '../../lib/transitional'; +import { wrapError } from '../../lib/utils'; import { Account } from '../account'; import GitHubApplication from '../application'; import Debug from 'debug'; const debugGitHubTokens = Debug('github:tokens'); +const symbolCost = Symbol('cost'); +const symbolHeaders = Symbol('headers'); + +export function symbolizeApiResponse(response: any): T { + if (response && response.headers) { + response[symbolHeaders] = response.headers; + delete response.headers; + } + if (response && response.cost) { + response[symbolCost] = response.cost; + delete response.cost; + } + return response; +} + +export function getApiSymbolMetadata(response: any) { + if (response) { + return { headers: response[symbolHeaders], cost: response[symbolCost] }; + } + throw CreateError.ParameterRequired('response'); +} + export interface IOperationsCoreOptions { github: RestLibrary; providers: IProviders; baseUrl?: string; + executionEnvironment: ExecutionEnvironment; } export enum CacheDefault { @@ -61,6 +92,7 @@ export enum CacheDefault { teamDetailStaleSeconds = 'teamDetailStaleSeconds', orgRepoWebhooksStaleSeconds = 'orgRepoWebhooksStaleSeconds', teamRepositoryPermissionStaleSeconds = 'teamRepositoryPermissionStaleSeconds', + defaultStaleSeconds = 'defaultStaleSeconds', } // defaults could move to configuration alternatively @@ -88,6 +120,7 @@ const defaults: ICacheDefaultTimes = { [CacheDefault.teamDetailStaleSeconds]: 60 * 60 * 2 /* 2h */, [CacheDefault.orgRepoWebhooksStaleSeconds]: 60 * 60 * 8 /* 8h */, [CacheDefault.teamRepositoryPermissionStaleSeconds]: 0 /* 0m */, + [CacheDefault.defaultStaleSeconds]: 60 /* 1m */, }; export const DefaultPageSize = 100; @@ -106,6 +139,46 @@ export function getPageSize(operations: IOperationsInstance, options?: IOptionWi return DefaultPageSize; } +export function createCacheOptions( + operations: IOperationsInstance, + options?: ICacheOptions, + cacheDefault: CacheDefault = CacheDefault.defaultStaleSeconds +) { + const cacheOptions: ICacheOptions = { + maxAgeSeconds: getMaxAgeSeconds(operations, cacheDefault, options, 60), + }; + if (options.backgroundRefresh !== undefined) { + cacheOptions.backgroundRefresh = options.backgroundRefresh; + } + return cacheOptions; +} + +export function createPagedCacheOptions( + operations: IOperationsInstance, + options?: IPagedCacheOptions, + cacheDefault: CacheDefault = CacheDefault.defaultStaleSeconds +) { + const cacheOptions: IPagedCacheOptions = { + maxAgeSeconds: getMaxAgeSeconds(operations, cacheDefault, options, 60), + }; + if (options.pageRequestDelay !== undefined) { + cacheOptions.pageRequestDelay = options.pageRequestDelay; + } + if (options.backgroundRefresh !== undefined) { + cacheOptions.backgroundRefresh = options.backgroundRefresh; + } + return cacheOptions; +} + +export function popPurpose(options: ICacheOptionsWithPurpose, defaultPurpose: AppPurposeTypes) { + if (options.purpose) { + const purpose = options.purpose; + delete options.purpose; + return purpose; + } + return defaultPurpose; +} + export function getMaxAgeSeconds( operations: IOperationsInstance, cacheDefault: CacheDefault, @@ -195,7 +268,7 @@ export abstract class OperationsCore async getAccountByUsername(username: string, options?: ICacheOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this); - const centralOperations = throwIfNotCapable( + const ops = throwIfNotCapable( this, CoreCapability.GitHubCentralOperations ); @@ -212,10 +285,9 @@ export abstract class OperationsCore cacheOptions.backgroundRefresh = options.backgroundRefresh; } try { - const getHeaderFunction = centralOperations.getCentralOperationsToken(); - const authorizationHeader = await getHeaderFunction(AppPurpose.Data); + const getHeaderFunction = ops.getPublicAuthorizationToken(); const entity = await operations.github.call( - authorizationHeader, + getHeaderFunction, 'users.getByUsername', parameters, cacheOptions @@ -335,17 +407,16 @@ export abstract class OperationsCore organizationName: string, organizationSettings: OrganizationSetting, legacyOwnerToken: string, - centralOperationsFallbackToken: string, appAuthenticationType: GitHubAppAuthenticationType, purpose: AppPurposeTypes - ): Promise { + ): Promise { const customPurpose = purpose as ICustomAppPurpose; const isCustomPurpose = customPurpose?.isCustomAppPurpose === true; if ( !isCustomPurpose && !this.tokenManager.organizationSupportsAnyPurpose(organizationName, organizationSettings) ) { - const legacyTokenValue = legacyOwnerToken || centralOperationsFallbackToken; + const legacyTokenValue = legacyOwnerToken; if (!legacyTokenValue) { throw new Error( `Organization ${organizationName} is not configured with a GitHub app, Personal Access Token ownerToken configuration value, or a fallback central operations token for the ${ @@ -356,7 +427,7 @@ export abstract class OperationsCore return { value: `token ${legacyTokenValue}`, purpose: null, - source: legacyOwnerToken ? 'legacyOwnerToken' : 'centralOperationsFallbackToken', + source: 'legacyOwnerToken', }; } if (!purpose) { diff --git a/business/operations/index.ts b/business/operations/index.ts index c2124a153..7040e423c 100644 --- a/business/operations/index.ts +++ b/business/operations/index.ts @@ -5,31 +5,33 @@ import axios from 'axios'; import throat from 'throat'; +import { shuffle } from 'lodash'; import { Account } from '../account'; import { GraphManager } from '../graphManager'; -import { IGitHubOrganizationResponse, Organization } from '../organization'; -import { GitHubTokenManager } from '../githubApps/tokenManager'; +import { GitHubOrganizationResponse, Organization } from '../organization'; +import { GitHubTokenManager } from '../../lib/github/tokenManager'; import RenderHtmlMail from '../../lib/emailRender'; -import { wrapError, sortByCaseInsensitive } from '../../utils'; +import { wrapError, sortByCaseInsensitive } from '../../lib/utils'; import { Repository } from '../repository'; import { RestLibrary } from '../../lib/github'; import { + AppPurpose, AppPurposeTypes, getAppPurposeId, GitHubAppAuthenticationType, GitHubAppPurposes, IGitHubAppConfiguration, -} from '../githubApps'; +} from '../../lib/github/appPurposes'; import { OrganizationFeature, OrganizationSetting, -} from '../../entities/organizationSettings/organizationSetting'; -import { OrganizationSettingProvider } from '../../entities/organizationSettings/organizationSettingProvider'; +} from '../entities/organizationSettings/organizationSetting'; +import { OrganizationSettingProvider } from '../entities/organizationSettings/organizationSettingProvider'; import { IMail } from '../../lib/mailProvider'; import { ILinkProvider } from '../../lib/linkProviders'; import { ICacheHelper } from '../../lib/caching'; -import { createPortalSudoInstance, IPortalSudo } from '../../features'; +import { createPortalSudoInstance, IPortalSudo } from '../features'; import { CacheDefault, getMaxAgeSeconds, IOperationsCoreOptions, OperationsCore } from './core'; import { linkAccounts as linkAccountsMethod } from './link'; import { sendTerminatedAccountMail as sendTerminatedAccountMailMethod } from './unlinkMail'; @@ -42,7 +44,7 @@ import { ICreateLinkOptions, ICrossOrganizationMembershipByOrganization, ICrossOrganizationTeamMembership, - IGetAuthorizationHeader, + GetAuthorizationHeader, IGitHubAppInstallation, IMapPlusMetaCost, IOperationsCentralOperationsToken, @@ -56,18 +58,22 @@ import { IOperationsTemplates, IPagedCrossOrganizationCacheOptions, IPromisedLinks, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, ISupportedLinkTypeOutcome, IUnlinkMailStatus, NoCacheNoBackground, SupportedLinkType, UnlinkPurpose, + type LinkEvent, + type UnlinkEvent, } from '../../interfaces'; -import { CreateError, ErrorHelper } from '../../transitional'; +import { CreateError, ErrorHelper } from '../../lib/transitional'; import { Team } from '../team'; -import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; +import { IRepositoryMetadataProvider } from '../entities/repositoryMetadata/repositoryMetadataProvider'; import { isAuthorizedSystemAdministrator } from './administration'; import type { ConfigGitHubOrganizationsSpecializedList } from '../../config/github.organizations.types'; +import { type GitHubTokenType, getGitHubTokenTypeFromValue } from '../../lib/github/appTokens'; +import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; export * from './core'; @@ -86,13 +92,7 @@ export interface ICrossOrganizationMembersResult extends Map {} export interface IOperationsOptions extends IOperationsCoreOptions { - // cacheProvider: ICacheHelper; - // config: any; github: RestLibrary; - // insights: TelemetryClient; - // linkProvider: ILinkProvider; - // mailAddressProvider: IMailAddressProvider; - // mailProvider: IMailProvider; repositoryMetadataProvider: IRepositoryMetadataProvider; } @@ -102,6 +102,12 @@ export type GetInvisibleOrganizationOptions = { storeInstanceByName?: boolean; }; +type CreateOrganizationOptions = { + settings: OrganizationSetting; + appAuthenticationType: GitHubAppAuthenticationType; + asUncontrolledPublicOnly?: boolean; +}; + export class Operations extends OperationsCore implements @@ -122,7 +128,7 @@ export class Operations private _invisibleOrganizations: Map; private _uncontrolledOrganizations: Map; private _organizationOriginalNames: any; - private _organizationNamesWithAuthorizationHeaders: Map; + private _organizationNamesWithAuthorizationHeaders: Map; private _defaultPageSize: number; private _organizationIds: Map; private _organizationSettings: OrganizationSetting[]; @@ -178,10 +184,10 @@ export class Operations } } this._tokenManager = new GitHubTokenManager({ + operations: this, configurations: purposesToConfigurations, - app: this.providers.app, + executionEnvironment: options.executionEnvironment, }); - GitHubTokenManager.RegisterManagerForOperations(this, this._tokenManager); this._dynamicOrganizationIds = new Set(); this._organizationSettings = []; } @@ -342,41 +348,46 @@ export class Operations return Array.from(this._organizationIds.keys()); } - private createOrganization( - name: string, - settings: OrganizationSetting, - centralOperationsFallbackToken: string, - appAuthenticationType: GitHubAppAuthenticationType - ): Organization { + private createOrganization(name: string, options: CreateOrganizationOptions): Organization { name = name.toLowerCase(); + if (!options) { + throw CreateError.ParameterRequired('options'); + } + const { settings, appAuthenticationType, asUncontrolledPublicOnly } = options; if (!settings) { - throw new Error(`This application is not configured for the ${name} organization`); + throw CreateError.InvalidParameters( + `This application does not have configuration information for the ${name} organization` + ); } const ownerToken = settings.getOwnerToken(); const hasDynamicSettings = this._dynamicOrganizationIds && settings.organizationId && this._dynamicOrganizationIds.has(Number(settings.organizationId)); + let configuredGetAuthorizationHeader: GetAuthorizationHeader = this.getAuthorizationHeader.bind( + this, + name, + settings, + ownerToken, + appAuthenticationType + ); + let forcedGetAuthorizationHeader: GetAuthorizationHeader = this.getAuthorizationHeader.bind( + this, + name, + settings, + ownerToken, + GitHubAppAuthenticationType.ForceSpecificInstallation + ); + if (!ownerToken && asUncontrolledPublicOnly) { + configuredGetAuthorizationHeader = this.getPublicAuthorizationToken(); + forcedGetAuthorizationHeader = configuredGetAuthorizationHeader; + } return new Organization( this, name, settings, - this.getAuthorizationHeader.bind( - this, - name, - settings, - ownerToken, - centralOperationsFallbackToken, - appAuthenticationType - ), - this.getAuthorizationHeader.bind( - this, - name, - settings, - ownerToken, - centralOperationsFallbackToken, - GitHubAppAuthenticationType.ForceSpecificInstallation - ), + configuredGetAuthorizationHeader, + forcedGetAuthorizationHeader, hasDynamicSettings ); } @@ -385,7 +396,6 @@ export class Operations if (!this._organizations) { const organizations = new Map(); const names = this.organizationNames; - const centralOperationsToken = this.config.github.operations.centralOperationsToken; for (let i = 0; i < names.length; i++) { const name = names[i]; let settings: OrganizationSetting = null; @@ -398,12 +408,10 @@ export class Operations settings = dos; } } - const organization = this.createOrganization( - name, + const organization = this.createOrganization(name, { settings, - centralOperationsToken, - GitHubAppAuthenticationType.BestAvailable - ); + appAuthenticationType: GitHubAppAuthenticationType.BestAvailable, + }); organizations.set(name, organization); } this._organizations = organizations; @@ -422,13 +430,10 @@ export class Operations for (let i = 0; i < list.length; i++) { const settings = list[i]; if (settings && settings.name && settings.name.toLowerCase() === lowercase) { - const centralOperationsToken = this.config.github.operations.centralOperationsToken; - return this.createOrganization( - lowercase, - OrganizationSetting.CreateFromStaticSettings(settings), - centralOperationsToken, - GitHubAppAuthenticationType.BestAvailable - ); + return this.createOrganization(lowercase, { + settings: OrganizationSetting.CreateFromStaticSettings(settings), + appAuthenticationType: GitHubAppAuthenticationType.BestAvailable, + }); } } } @@ -444,12 +449,10 @@ export class Operations } getUnconfiguredOrganization(settings: OrganizationSetting): Organization { - return this.createOrganization( - settings.organizationName.toLowerCase(), + return this.createOrganization(settings.organizationName.toLowerCase(), { settings, - null, - GitHubAppAuthenticationType.BestAvailable - ); + appAuthenticationType: GitHubAppAuthenticationType.BestAvailable, + }); } // An invisible organization does not appear in the cross-organization @@ -480,7 +483,10 @@ export class Operations dynamicSettings = options.settings; } const authenticationType = options?.authenticationType || GitHubAppAuthenticationType.BestAvailable; - const organization = this.createOrganization(name, dynamicSettings, null, authenticationType); + const organization = this.createOrganization(name, { + settings: dynamicSettings, + appAuthenticationType: authenticationType, + }); if (!options || options?.storeInstanceByName) { this._invisibleOrganizations.set(name, organization); } @@ -498,13 +504,12 @@ export class Operations } const emptySettings = new OrganizationSetting(); emptySettings.operationsNotes = `Uncontrolled Organization - ${organizationName}`; - const centralOperationsToken = this.config.github.operations.centralOperationsToken; - const org = this.createOrganization( - organizationName, - emptySettings, - centralOperationsToken, - GitHubAppAuthenticationType.ForceSpecificInstallation - ); + const asUncontrolledPublicOnly = true; + const org = this.createOrganization(organizationName, { + settings: emptySettings, + appAuthenticationType: GitHubAppAuthenticationType.ForceSpecificInstallation, + asUncontrolledPublicOnly, + }); this._uncontrolledOrganizations.set(organizationName, org); org.uncontrolled = true; return org; @@ -512,18 +517,19 @@ export class Operations getPublicOnlyAccessOrganization(organizationName: string, organizationId?: number): Organization { organizationName = organizationName.toLowerCase(); - const emptySettings = new OrganizationSetting(); - emptySettings.operationsNotes = `Uncontrolled public organization - ${organizationName}`; const publicAccessToken = this.config.github.operations.publicAccessToken; if (!publicAccessToken) { - throw new Error('not configured for public read-only tokens'); + throw CreateError.InvalidParameters('not configured for public read-only tokens'); } - const org = this.createOrganization( - organizationName, - emptySettings, + const emptySettings = OrganizationSetting.CreateEmptyWithOldToken( publicAccessToken, - GitHubAppAuthenticationType.ForceSpecificInstallation + `Uncontrolled public organization - ${organizationName}`, + organizationId ); + const org = this.createOrganization(organizationName, { + settings: emptySettings, + appAuthenticationType: GitHubAppAuthenticationType.ForceSpecificInstallation, + }); this._uncontrolledOrganizations.set(organizationName, org); org.uncontrolled = true; return org; @@ -599,14 +605,14 @@ export class Operations get organizationNamesWithAuthorizationHeaders() { if (!this._organizationNamesWithAuthorizationHeaders) { - const tokens = new Map(); + const tokens = new Map(); const visited = new Set(); for (const entry of this._organizationSettings) { const lowercase = entry.organizationName.toLowerCase(); if (entry.active && !visited.has(lowercase) && !entry.hasFeature(OrganizationFeature.Invisible)) { visited.add(lowercase); const orgInstance = this.getOrganization(lowercase); - const token = orgInstance.getAuthorizationHeader(); + const token = orgInstance.getAuthorizationHeader(AppPurpose.Data); tokens.set(lowercase, token); } } @@ -784,10 +790,6 @@ export class Operations return this.config.brand.operationsMail; } - getInfrastructureNotificationsMail(): string { - return this.config.brand.infrastructureNotificationsMail || this.getOperationsMailAddress(); - } - getLinksNotificationMailAddress(): string { return this.config.notifications.linksMailAddress || this.getOperationsMailAddress(); } @@ -885,6 +887,22 @@ export class Operations } async getRepoById(repoId: number, options?: ICacheOptions): Promise { + const { repositoryCacheProvider } = this.providers; + if (repositoryCacheProvider) { + try { + const cachedRepository = await repositoryCacheProvider.getRepository(String(repoId)); + if (cachedRepository?.organizationId) { + const organization = this.getOrganizationById(Number(cachedRepository.organizationId)); + return organization.repository(cachedRepository.repositoryName); + } + } catch (error) { + if (ErrorHelper.IsNotFound(error)) { + console.log(`Repository ${repoId} not found in the cache: ${error}`); + } else { + console.log(`Repository ${repoId} error retrieving from cache: ${error}`); + } + } + } const cacheOptions = options || { maxAgeSeconds: this.defaults.crossOrgsReposStaleSecondsPerOrg, }; @@ -906,10 +924,46 @@ export class Operations } } - async getOrganizationProfileById( + async getOrganizationProfileById(id: number, options?: ICacheOptions): Promise { + options = options || {}; + if (!id) { + throw new Error('Must provide a repository ID to retrieve the repository.'); + } + const organization = this._organizationIds.get(id); + return this._getOrganizationProfileById(id, organization ? id : null, options); + } + + async getOrganizationPublicProfileById( id: number, options?: ICacheOptions - ): Promise { + ): Promise { + options = options || {}; + if (!id) { + throw new Error('Must provide a repository ID to retrieve the repository.'); + } + let lookupId: number | null = this._organizationIds.get(id) ? id : null; + if (lookupId) { + const allIdsExcludingOrg = this.getOrganizationIds().filter((orgId) => orgId !== id); + const shuffledIds = shuffle(allIdsExcludingOrg); + if (shuffledIds.length > 0) { + lookupId = shuffledIds[0]; + } + } + if (lookupId === null) { + throw CreateError.InvalidParameters( + 'This approach requires configuring at least two organizations (getOrganizationPublicProfileById).' + ); + } + return this._getOrganizationProfileById(id, lookupId, options); + } + + private async _getOrganizationProfileById( + id: number, + lookupUsingIdOrCentralToken: number | null, + options?: ICacheOptions + ): Promise { + // EMU note: you need to use an EMU-installed app vs public... + // Cache note: this will be a cache miss if you switch between public/non-public entrypoints options = options || {}; if (!id) { throw new Error('Must provide a repository ID to retrieve the repository.'); @@ -923,13 +977,15 @@ export class Operations if (options.backgroundRefresh !== undefined) { cacheOptions.backgroundRefresh = options.backgroundRefresh; } + const organization = this._organizationIds.get(lookupUsingIdOrCentralToken); + let header: GetAuthorizationHeader = null; + if (organization) { + header = organization.getAuthorizationHeader(AppPurpose.Data) as GetAuthorizationHeader; + } else { + header = this.getPublicAuthorizationToken(); + } try { - const entity = await this.github.request( - this.getCentralOperationsToken(), - 'GET /organizations/:id', - parameters, - cacheOptions - ); + const entity = await this.github.request(header, 'GET /organizations/:id', parameters, cacheOptions); return entity; } catch (error) { if (error.status && error.status === 404) { @@ -1242,11 +1298,17 @@ export class Operations // Eventually link/unlink should move from context into operations here to centralize more than just the events - async fireLinkEvent(value): Promise { + async fireLinkEvent(value: LinkEvent): Promise { + const companySpecific = getCompanySpecificDeployment(); + companySpecific?.events?.linking?.onLink && companySpecific.events.linking.onLink(this.providers, value); await fireEvent(this.config, 'link', value); } - async fireUnlinkEvent(value): Promise { + async fireUnlinkEvent(value: UnlinkEvent): Promise { + const corporateId = value?.aad?.id; + const companySpecific = getCompanySpecificDeployment(); + companySpecific?.events?.linking?.onUnlink && + companySpecific.events.linking.onUnlink(this.providers, corporateId); await fireEvent(this.config, 'unlink', value); } @@ -1279,19 +1341,32 @@ export class Operations return false; } - getCentralOperationsToken(): IGetAuthorizationHeader { - const func = getCentralOperationsAuthorizationHeader.bind(null, this) as IGetAuthorizationHeader; - return func; + getPublicReadOnlyStaticToken(): GetAuthorizationHeader { + const { config } = this.providers; + if (config?.github?.operations?.publicAccessToken) { + const capturedToken = config.github.operations.publicAccessToken; + return async () => { + return { + value: `token ${capturedToken}`, + purpose: null, + source: 'public read-only token', + }; + }; + } + throw CreateError.InvalidParameters('No configured read-only static token'); } - getPublicReadOnlyToken(): IGetAuthorizationHeader { - const func = getReadOnlyAuthorizationHeader.bind(null, this) as IGetAuthorizationHeader; - return func; + getPublicAuthorizationToken(): GetAuthorizationHeader { + try { + return this._tokenManager.getAuthorizationHeaderForAnyApp.bind(this._tokenManager); + } catch (error) { + return this.getPublicReadOnlyStaticToken(); + } } getAccount(id: string) { const entity = { id }; - return new Account(entity, this, getCentralOperationsAuthorizationHeader.bind(null, this)); + return new Account(entity, this, this.getPublicAuthorizationToken.bind(this)); } async getAccountWithDetailsAndLink(id: string): Promise { @@ -1300,14 +1375,27 @@ export class Operations } async getAuthenticatedAccount(token: string): Promise { + // Returns an account instance based on the account identified in the token. const github = this.github; const parameters = {}; + const fullToken = `token ${token}`; + let tokenType: GitHubTokenType = null; try { - const entity = await github.post(`token ${token}`, 'users.getAuthenticated', parameters); - const account = new Account(entity, this, getCentralOperationsAuthorizationHeader.bind(null, this)); + tokenType = getGitHubTokenTypeFromValue(fullToken); + } catch (error) { + // ignoring any issue here on identifying the type of token + } + try { + const entity = await github.post(fullToken, 'users.getAuthenticated', parameters); + const account = new Account(entity, this, this.getPublicAuthorizationToken.bind(this)); return account; } catch (error) { - throw wrapError(error, 'Could not get details about the authenticated account'); + throw wrapError( + error, + `Could not get details about the authenticated account${ + tokenType ? ' using token type "' + tokenType + '"' : '.' + }` + ); } } @@ -1421,42 +1509,6 @@ async function fireEvent(config, configurationName, value): Promise { - return { - value: `token ${capturedToken}`, - purpose: null, - source: 'public read-only token', - }; - }; - } else { - throw new Error('No public read-only token configured.'); - } -} - -export function getCentralOperationsAuthorizationHeader(self: Operations): IPurposefulGetAuthorizationHeader { - const s = (self || this) as Operations; - if (s.config.github && s.config.github.operations && s.config.github.operations.centralOperationsToken) { - const capturedToken = s.config.github.operations.centralOperationsToken; - return async () => { - return { - value: `token ${capturedToken}`, - purpose: null, // legacy - source: 'central operations token', - }; - }; - } else if (s.getOrganizations().length === 0) { - throw new Error('No central operations token nor any organizations configured.'); - } - // Fallback to the first configured organization as a convenience - // CONSIDER: would randomizing the organization be better, or a priority based on known-rate limit remaining? - const firstOrganization = s.getOrganizations()[0]; - return firstOrganization.getAuthorizationHeader(); -} - function crossOrganizationResults(operations: Operations, results, keyProperty) { keyProperty = keyProperty || 'id'; const map: IMapPlusMetaCost = new Map(); diff --git a/business/operations/link.ts b/business/operations/link.ts index b41e2a6c2..d4a269857 100644 --- a/business/operations/link.ts +++ b/business/operations/link.ts @@ -12,7 +12,7 @@ import { ICorporateLink, } from '../../interfaces'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import { CreateError, ErrorHelper, setImmediateAsync } from '../../transitional'; +import { CreateError, ErrorHelper, setImmediateAsync } from '../../lib/transitional'; export async function linkAccounts( operations: Operations, diff --git a/business/operations/unlinkMail.ts b/business/operations/unlinkMail.ts index 78d4601d9..50522e05f 100644 --- a/business/operations/unlinkMail.ts +++ b/business/operations/unlinkMail.ts @@ -7,7 +7,7 @@ import { Operations } from '.'; import { Account } from '../account'; import { UnlinkPurpose, IUnlinkMailStatus, ICachedEmployeeInformation } from '../../interfaces'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import { assertUnreachable } from '../../transitional'; +import { assertUnreachable } from '../../lib/transitional'; export async function sendTerminatedAccountMail( operations: Operations, @@ -64,7 +64,7 @@ export async function sendTerminatedAccountMail( break; case UnlinkPurpose.Termination: subjectPrefix = '[UNLINKED] '; - headline = `${displayName} is not an active employee`; + headline = `${displayName} has had their GitHub access offboarded`; break; case UnlinkPurpose.Unknown: default: diff --git a/business/organization.ts b/business/organization.ts index b25945d04..ef8fa2b65 100644 --- a/business/organization.ts +++ b/business/organization.ts @@ -10,29 +10,30 @@ import { OrganizationMember } from './organizationMember'; import { Team } from './team'; import { Repository } from './repository'; -import { wrapError } from '../utils'; +import { wrapError } from '../lib/utils'; import { StripGitHubEntity } from '../lib/github/restApi'; import { GitHubResponseType } from '../lib/github/endpointEntities'; -import { AppPurpose, AppPurposeTypes } from './githubApps'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; import { OrganizationFeature, OrganizationSetting, - SpecialTeam, -} from '../entities/organizationSettings/organizationSetting'; -import { createOrganizationSudoInstance, IOrganizationSudo } from '../features'; + SystemTeam, +} from './entities/organizationSettings/organizationSetting'; +import { createOrganizationSudoInstance, IOrganizationSudo } from './features'; import { CacheDefault, getMaxAgeSeconds, getPageSize, OperationsCore } from './operations/core'; import { CoreCapability, GitHubAuditLogEntry, + GitHubOrganizationInvite, GitHubRepositoryVisibility, IAccountBasics, IAddOrganizationMembershipOptions, - IAuthorizationHeaderValue, + AuthorizationHeaderValue, ICacheOptions, ICacheOptionsWithPurpose, ICorporateLink, ICreateRepositoryResult, - IGetAuthorizationHeader, + type GetAuthorizationHeader, IGetOrganizationAuditLogOptions, IGetOrganizationMembersOptions, IGitHubAccountDetails, @@ -48,7 +49,7 @@ import { IOrganizationMemberPair, IOrganizationMembership, IPagedCacheOptions, - IPurposefulGetAuthorizationHeader, + type PurposefulGetAuthorizationHeader, IReposError, IReposRestRedisCacheCost, NoCacheNoBackground, @@ -58,14 +59,17 @@ import { OrganizationMembershipTwoFactorFilter, throwIfNotCapable, throwIfNotGitHubCapable, + GitHubRepositoryDetails, } from '../interfaces'; -import { CreateError, ErrorHelper } from '../transitional'; +import { CreateError, ErrorHelper } from '../lib/transitional'; import { jsonError } from '../middleware'; import getCompanySpecificDeployment from '../middleware/companySpecificDeployment'; import { ConfigGitHubTemplates } from '../config/github.templates.types'; -import { GitHubTokenManager } from './githubApps/tokenManager'; +import { GitHubTokenManager } from '../lib/github/tokenManager'; import { OrganizationProjects } from './projects'; import { OrganizationDomains } from './domains'; +import { OrganizationCopilot } from './organizationCopilot'; +import { OrganizationProperties } from './organizationProperties'; interface IGetMembersParameters { org: string; @@ -101,7 +105,7 @@ export interface IGitHubOrganizationPlanResponse { space: number; } -export interface IGitHubOrganizationResponse { +export type GitHubOrganizationResponse = { avatar_url?: string; billing_email?: string; blog?: string; @@ -135,8 +139,73 @@ export interface IGitHubOrganizationResponse { type: string; updated_at: string; url: string; +}; + +// the only fields we want in this type based on GitHubOrganizationResponse are avatar_url, blog, company, created_at, description, email, id, location, login, name, updated_at +export type GitHubOrganizationResponseSanitized = Pick< + GitHubOrganizationResponse, + | 'avatar_url' + | 'blog' + | 'company' + | 'created_at' + | 'description' + | 'email' + | 'id' + | 'location' + | 'login' + | 'name' + | 'updated_at' +>; + +const sanitizedFields = [ + 'avatar_url', + 'blog', + 'company', + 'created_at', + 'description', + 'email', + 'id', + 'location', + 'login', + 'name', + 'updated_at', +]; + +export function getOrganizationDetailsSanitized( + details: GitHubOrganizationResponse +): GitHubOrganizationResponseSanitized { + if (details) { + const sanitized = {} as GitHubOrganizationResponseSanitized; + for (const field of sanitizedFields) { + if (details[field]) { + sanitized[field] = details[field]; + } + } + return sanitized; + } } +export interface RunnerData { + busy: boolean; + id: number; + name: string; + os: string; + status: string; + labels: { + id: number; + name: string; + type: string; + }; +} + +export interface IGitHubOrganizationRunners { + total_count: number; + runners: RunnerData[]; +} +type CreateRepositoryEntityById = Partial & Pick; +type CreateRepositoryEntityByName = Partial & Pick; +type CreateRepositoryEntity = CreateRepositoryEntityById | CreateRepositoryEntityByName; + export class Organization { private _name: string; private _baseUrl: string; @@ -144,18 +213,21 @@ export class Organization { private _nativeManagementUrl: string; private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _usesGitHubApp: boolean; private _settings: OrganizationSetting; - private _entity: IGitHubOrganizationResponse; + private _entity: GitHubOrganizationResponse; private _organizationSudo: IOrganizationSudo; private _projects: OrganizationProjects; private _domains: OrganizationDomains; + private _copilot: OrganizationCopilot; + private _customProperties: OrganizationProperties; + id: number; uncontrolled: boolean; @@ -163,8 +235,8 @@ export class Organization { operations: IOperationsInstance, name: string, settings: OrganizationSetting, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, public hasDynamicSettings: boolean ) { this._name = settings.organizationName || name; @@ -251,7 +323,7 @@ export class Organization { ); } - return values; + return values as object; } getManagementApproach() { @@ -288,6 +360,28 @@ export class Organization { return this._projects; } + get copilot() { + if (!this._copilot) { + this._copilot = new OrganizationCopilot( + this, + this._getSpecificAuthorizationHeader.bind(this), + this._operations + ); + } + return this._copilot; + } + + get customProperties() { + if (!this._customProperties) { + this._customProperties = new OrganizationProperties( + this, + this._getSpecificAuthorizationHeader.bind(this), + this._operations + ); + } + return this._customProperties; + } + get domains() { if (!this._domains) { this._domains = new OrganizationDomains( @@ -325,7 +419,7 @@ export class Organization { return tokenManager.getRateLimitInformation(purpose, this); } - repository(name: string, optionalEntity?) { + repository(name: string, optionalEntity?: CreateRepositoryEntity) { const entity = Object.assign({}, optionalEntity || {}, { name, }); @@ -356,15 +450,24 @@ export class Organization { cacheOptions.backgroundRefresh = options.backgroundRefresh; } try { - const entity = await operations.github.request( - this.authorize(AppPurpose.Data), - 'GET /repositories/:id', - parameters, - cacheOptions - ); + let entity: any = null; + if ((cacheOptions as any)?.noConditionalRequests === true) { + entity = await operations.github.requestAsPost( + this.authorize(AppPurpose.Data), + 'GET /repositories/:id', + parameters + ); + } else { + entity = await operations.github.request( + this.authorize(AppPurpose.Data), + 'GET /repositories/:id', + parameters, + cacheOptions + ); + } if (entity.owner.id !== this.id) { throw CreateError.NotFound( - `Repository ID ${parameters.id} has a different owner of ${entity.owner.login} instead of ${this.name}. It has been relocated and will be treated as a 404.` + `Repository ID ${id} has a different owner of ${entity.owner.login} instead of ${this.name}. It has been relocated and will be treated as a 404.` ); } return this.repositoryFromEntity(entity); @@ -411,6 +514,29 @@ export class Organization { return repositories; } + async getOrgRunners(options?: ICacheOptions): Promise { + options = options || {}; + const operations = throwIfNotGitHubCapable(this._operations); + const github = operations.github; + const orgName = this.name; + const parameters = { + orgName, + }; + const cacheOptions: ICacheOptions = { + maxAgeSeconds: 1, // getMaxAgeSeconds(operations, CacheDefault.accountDetailStaleSeconds, options), + }; + const runnerData = await operations.github.request( + this.authorize(AppPurpose.ActionsData), + 'GET /orgs/:orgName/actions/runners', + parameters, + cacheOptions + ); + return { + runners: runnerData.runners, + total_count: runnerData.total_count, + }; + } + get priority(): string { return this._settings.properties['priority'] || 'secondary'; } @@ -427,10 +553,6 @@ export class Organization { return this._settings.hasFeature(OrganizationFeature.Hidden) || false; } - get pilot_program() { - return this._settings.properties['1es']; - } - get createRepositoriesOnGitHub(): boolean { return this._settings.hasFeature(OrganizationFeature.CreateNativeRepositories) || false; } @@ -472,7 +594,11 @@ export class Organization { } get broadAccessTeams(): number[] { - return this.getSpecialTeam(SpecialTeam.Everyone, 'everyone membership'); + return this.getSystemTeam(SystemTeam.Everyone, 'everyone membership'); + } + + get openAccessTeams(): number[] { + return this.getSystemTeam(SystemTeam.OpenAccess, 'open access'); } get invitationTeam(): Team { @@ -484,7 +610,7 @@ export class Organization { } get systemSudoersTeam(): Team { - const teams = this.getSpecialTeam(SpecialTeam.GlobalSudo, 'system sudoers'); + const teams = this.getSystemTeam(SystemTeam.GlobalSudo, 'system sudoers'); if (teams.length > 1) { throw new Error('Multiple system sudoer teams are not supported.'); } @@ -496,7 +622,7 @@ export class Organization { } get sudoersTeam(): Team { - const teams = this.getSpecialTeam(SpecialTeam.Sudo, 'organization sudoers'); + const teams = this.getSystemTeam(SystemTeam.Sudo, 'organization sudoers'); if (teams.length > 1) { throw new Error('Multiple sudoer teams are not supported.'); } @@ -510,16 +636,16 @@ export class Organization { return this._settings; } - get specialRepositoryPermissionTeams() { + get specialSystemTeams() { return { - read: this.getSpecialTeam(SpecialTeam.SystemRead, 'read everything'), - write: this.getSpecialTeam(SpecialTeam.SystemWrite, 'write everything'), - admin: this.getSpecialTeam(SpecialTeam.SystemAdmin, 'administer everything'), + read: this.getSystemTeam(SystemTeam.SystemRead, 'read everything'), + write: this.getSystemTeam(SystemTeam.SystemWrite, 'write everything'), + admin: this.getSystemTeam(SystemTeam.SystemAdmin, 'administer everything'), }; } - getAuthorizationHeader(): IPurposefulGetAuthorizationHeader { - return this._getAuthorizationHeader; + getAuthorizationHeader(purpose: AppPurposeTypes): PurposefulGetAuthorizationHeader { + return purpose ? this._getAuthorizationHeader.bind(this, purpose) : this._getAuthorizationHeader; } async getUserDetailsByLogin(login: string, purpose?: AppPurposeTypes): Promise { @@ -592,7 +718,13 @@ export class Organization { teamIds.push(broadAccessTeams[i]); // is the actual ID, not the team object } } - const specialTeams = this.specialRepositoryPermissionTeams; + const openAccessTeams = this.openAccessTeams; + if (openAccessTeams) { + for (let i = 0; i < openAccessTeams.length; i++) { + teamIds.push(openAccessTeams[i]); // is the actual ID, not the team object + } + } + const specialTeams = this.specialSystemTeams; const keys = Object.getOwnPropertyNames(specialTeams); keys.forEach((type) => { const values = specialTeams[type]; @@ -625,12 +757,12 @@ export class Organization { ); } - async getRepositoryCreateGitHubToken(): Promise { + async getRepositoryCreateGitHubToken(): Promise { // This method leaks/releases the owner token. In the future a more crisp // way of accomplishing this without exposing the token should be created. // The function name is specific to the intended use instead of a general- // purpose token name. - const token = await (this.authorize(AppPurpose.Operations) as IGetAuthorizationHeader)(); + const token = await (this.authorize(AppPurpose.Operations) as GetAuthorizationHeader)(); token.source = 'repository create token'; return token; } @@ -674,7 +806,7 @@ export class Organization { } } - async getDetails(): Promise { + async getDetails(): Promise { const operations = throwIfNotGitHubCapable(this._operations); const parameters = { org: this.name, @@ -685,7 +817,7 @@ export class Organization { this.id = entity.id; } this._entity = entity; - return entity as IGitHubOrganizationResponse; + return entity as GitHubOrganizationResponse; } catch (error) { throw wrapError(error, `Could not get details about the ${this.name} organization: ${error.message}`); } @@ -710,6 +842,42 @@ export class Organization { return metadata; } + async getTeamById(id: number, options?: ICacheOptions): Promise { + options = options || {}; + const operations = throwIfNotGitHubCapable(this._operations); + const cacheOptions = { + maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgTeamDetailsStaleSeconds, options), + backgroundRefresh: false, + }; + if (options.backgroundRefresh !== undefined) { + cacheOptions.backgroundRefresh = options.backgroundRefresh; + } + const orgId = this.id; + if (!orgId) { + throw CreateError.InvalidParameters('The organization ID is not available.'); + } + const parameters = { + org_id: orgId, + team_id: id, + }; + try { + const entity = await operations.github.request( + this.authorize(AppPurpose.Data), + 'GET /organizations/:org_id/team/:team_id', + parameters, + cacheOptions + ); + return this.teamFromEntity(entity); + } catch (error) { + if (error.status && error.status === 404) { + throw CreateError.NotFound( + `The GitHub team with the ID ${id} could not be found for organization ${this.name} with ID ${orgId}.` + ); + } + throw error; + } + } + async getTeamFromSlug(slug: string, options?: ICacheOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this._operations); @@ -1126,7 +1294,7 @@ export class Organization { const getAuthorizationHeader = this._getAuthorizationHeader.bind( this, AppPurpose.Data - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; const github = operations.github; const parameters: IGetMembersParameters = { org: this.name, @@ -1241,7 +1409,7 @@ export class Organization { const getAuthorizationHeader = this._getAuthorizationHeader.bind( this, AppPurpose.Data - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; const teamEntities = await github.collections.getOrgTeams(getAuthorizationHeader, parameters, caching); const teams = common.createInstances(this, this.teamFromEntity, teamEntities); return teams; @@ -1267,12 +1435,12 @@ export class Organization { if (queryCache?.supportsOrganizationMembership) { try { if (!optionalId) { - const centralOps = operationsWithCapability( + const ops = operationsWithCapability( operations, CoreCapability.GitHubCentralOperations ); - if (centralOps) { - const account = await centralOps.getAccountByUsername(login); + if (ops) { + const account = await ops.getAccountByUsername(login); optionalId = account.id.toString(); } } @@ -1284,7 +1452,7 @@ export class Organization { } } - async getMembershipInvitations(): Promise { + async getMembershipInvitations(): Promise { const operations = throwIfNotGitHubCapable(this._operations); const parameters = { org: this.name, @@ -1295,7 +1463,7 @@ export class Organization { 'orgs.listPendingInvitations', parameters ); - return invitations; + return invitations as GitHubOrganizationInvite[]; } catch (error) { if (error.status == /* loose */ 404) { return null; @@ -1304,19 +1472,16 @@ export class Organization { } } - private authorize(purpose: AppPurpose): IGetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose): GetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getAuthorizationHeader; } @@ -1448,7 +1613,7 @@ export class Organization { return this.team(entity.id, entity); } - repositoryFromEntity(entity): Repository { + repositoryFromEntity(entity: CreateRepositoryEntity): Repository { return this.repository(entity.name, entity); } @@ -1458,23 +1623,15 @@ export class Organization { return { settings, operations }; } - private getSpecialTeam(specialTeam: SpecialTeam, friendlyName: string, throwIfMissing?: boolean): number[] { - let teamId: number = null; - for (const entry of this._settings.specialTeams) { - if (entry.specialTeam === specialTeam) { - teamId = entry.teamId; - break; - } - } - if (throwIfMissing) { + private getSystemTeam(teamType: SystemTeam, friendlyName: string, throwIfMissing?: boolean): number[] { + const allOrgSystemTeams = this._settings.specialTeams; + const matchingSystemTeamTypes = allOrgSystemTeams.filter((t) => t.specialTeam === teamType); + const teams: number[] = matchingSystemTeamTypes.map((t) => t.teamId); + if (throwIfMissing && teams.length === 0) { throw new Error( - `Missing configured organization "${this.name}" special team ${specialTeam} - ${friendlyName}` + `Missing configured organization "${this.name}" special team ${teamType} - ${friendlyName}` ); } - const teams: number[] = []; - if (teamId) { - teams.push(teamId); - } return teams; } diff --git a/business/organizationCopilot.ts b/business/organizationCopilot.ts new file mode 100644 index 000000000..8081ba09f --- /dev/null +++ b/business/organizationCopilot.ts @@ -0,0 +1,126 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { + GetAuthorizationHeader, + ICacheOptions, + IOperationsInstance, + IPagedCacheOptions, + PurposefulGetAuthorizationHeader, + throwIfNotGitHubCapable, +} from '../interfaces'; +import type { CollectionCopilotSeatsOptions } from '../lib/github/collections'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { CacheDefault, getMaxAgeSeconds, getPageSize, symbolizeApiResponse } from './operations/core'; +import { Organization } from './organization'; +import { HttpMethod } from '../lib/github'; + +export type CopilotSeatData = { + assignee: { + avatar_url: string; + id: number; + login: string; + }; + created_at: string; + updated_at: string; + last_activity_at: string; + last_activity_editor: string; +}; + +export type CopilotDailyBreakdown = { + language: string; + editor: string; + suggestions_count: number; + acceptances_count: number; + lines_suggested: number; + lines_accepted: number; + active_users: number; +}; + +export type CopilotDailySummary = { + day: string; + total_suggestions_count: number; + total_acceptances_count: number; + total_lines_suggested: number; + total_lines_accepted: number; + total_active_users: number; + breakdown: CopilotDailyBreakdown[]; +}; + +export type OrganizationCopilotSummary = CopilotDailySummary[]; + +export class OrganizationCopilot { + constructor( + private organization: Organization, + private getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + private operations: IOperationsInstance + ) {} + + async getSeatActivity( + options?: IPagedCacheOptions, + appPurpose: AppPurposeTypes = AppPurpose.Data + ): Promise { + options = options || {}; + const operations = throwIfNotGitHubCapable(this.operations); + const getAuthorizationHeader = this.getSpecificAuthorizationHeader.bind( + this, + appPurpose + ) as GetAuthorizationHeader; + const github = operations.github; + const parameters: CollectionCopilotSeatsOptions = { + org: this.organization.name, + per_page: getPageSize(operations), + }; + const caching = { + maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgMembersStaleSeconds, options), + backgroundRefresh: true, + pageRequestDelay: options.pageRequestDelay, + }; + if (options && options.backgroundRefresh === false) { + caching.backgroundRefresh = false; + } + // (caching as any).pageLimit = 10; + const seats = (await github.collections.getOrganizationCopilotSeats( + getAuthorizationHeader, + parameters, + caching + )) as CopilotSeatData[]; + return seats; + } + + async getDailyActivitySummary( + options?: ICacheOptions, + appPurpose: AppPurposeTypes = AppPurpose.Data + ): Promise { + options = options || {}; + const operations = throwIfNotGitHubCapable(this.operations); + const getAuthorizationHeader = this.getSpecificAuthorizationHeader.bind( + this, + appPurpose + ) as GetAuthorizationHeader; + const github = operations.github; + const parameters = { + org: this.organization.name, + }; + const caching = { + maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgMembersStaleSeconds, options), + backgroundRefresh: true, + }; + if (options && options.backgroundRefresh === false) { + caching.backgroundRefresh = false; + } + try { + const result: OrganizationCopilotSummary = await github.request( + getAuthorizationHeader, + 'GET /orgs/:org/copilot/usage', + parameters, + caching + ); + return symbolizeApiResponse(result); + } catch (error) { + throw error; + } + } +} diff --git a/business/organizationProperties.ts b/business/organizationProperties.ts new file mode 100644 index 000000000..36080e05b --- /dev/null +++ b/business/organizationProperties.ts @@ -0,0 +1,198 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { + ICacheOptions, + ICacheOptionsWithPurpose, + GetAuthorizationHeader, + IOperationsInstance, + PurposefulGetAuthorizationHeader, + PagedCacheOptionsWithPurpose, + throwIfNotGitHubCapable, +} from '../interfaces'; +import { HttpMethod } from '../lib/github'; +import { CreateError } from '../lib/transitional'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { + CacheDefault, + createPagedCacheOptions, + getMaxAgeSeconds, + getPageSize, + popPurpose, + symbolizeApiResponse, +} from './operations/core'; +import { Organization } from './organization'; + +export enum CustomPropertyValueType { + String = 'string', + SingleSelect = 'single_select', +} + +export type OrganizationCustomPropertyEntity = { + property_name: string; + value_type: CustomPropertyValueType; + required: boolean; + description?: string; + default_value?: string; + allowed_values?: string[]; +}; + +export type OrganizationCustomPropertySetPropertyValue = { + property_name: string; + value: string; +}; + +type CreateOrUpdateResponse = { + properties: OrganizationCustomPropertyEntity[]; +}; + +export class OrganizationProperties { + private _defaultPurpose = AppPurpose.Data; + + constructor( + private organization: Organization, + private getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, + private operations: IOperationsInstance + ) {} + + private authorize(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + const getAuthorizationHeader = this.getSpecificAuthorizationHeader.bind( + this, + purpose + ) as GetAuthorizationHeader; + return getAuthorizationHeader; + } + + async getCustomProperties( + options?: PagedCacheOptionsWithPurpose + ): Promise { + options = options || {}; + const operations = throwIfNotGitHubCapable(this.operations); + const { github } = operations; + const purpose = popPurpose(options, this._defaultPurpose); + const parameters = { + org: this.organization.name, + per_page: getPageSize(operations), + }; + const cacheOptions = createPagedCacheOptions(operations, options); + try { + const entities = await github.collections.collectAllPagesViaHttpGet< + any, + OrganizationCustomPropertyEntity + >( + this.authorize(purpose), + 'orgCustomProps', + 'GET /orgs/:org/properties/schema', + parameters, + cacheOptions + ); + return symbolizeApiResponse(entities); + } catch (error) { + throw error; + } + } + + async getCustomProperty( + propertyName: string, + options?: ICacheOptionsWithPurpose + ): Promise { + options = options || {}; + const operations = throwIfNotGitHubCapable(this.operations); + const { github } = operations; + if (!propertyName) { + throw CreateError.InvalidParameters('propertyName'); + } + const purpose = popPurpose(options, this._defaultPurpose); + const parameters = { + org: this.organization.name, + custom_property_name: propertyName, + }; + const cacheOptions: ICacheOptions = { + maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.accountDetailStaleSeconds, options, 60), + }; + if (options.backgroundRefresh !== undefined) { + cacheOptions.backgroundRefresh = options.backgroundRefresh; + } + try { + const entity = (await github.request( + this.authorize(purpose), + 'GET /orgs/:org/properties/schema/:custom_property_name', + parameters, + cacheOptions + )) as OrganizationCustomPropertyEntity; + return symbolizeApiResponse(entity); + } catch (error) { + throw error; + } + } + + async deleteProperty(propertyName: string, purpose?: AppPurposeTypes): Promise { + const operations = throwIfNotGitHubCapable(this.operations); + const parameters = { + org: this.organization.name, + custom_property_name: propertyName, + }; + await operations.github.restApi( + this.authorize(purpose || this._defaultPurpose), + HttpMethod.Delete, + '/orgs/:org/properties/schema/:custom_property_name', + parameters + ); + } + + async createOrUpdate( + properties: OrganizationCustomPropertyEntity[], + purpose?: AppPurposeTypes + ): Promise { + const operations = throwIfNotGitHubCapable(this.operations); + const parameters = { + org: this.organization.name, + properties, + }; + const res = (await operations.github.restApi( + this.authorize(purpose || this._defaultPurpose), + HttpMethod.Patch, + '/orgs/:org/properties/schema', + parameters + )) as CreateOrUpdateResponse; + return res.properties; + } + + async createOrUpdateRepositoriesProperties( + organizationRepositoryNames: string[], + propertiesAndValues: Record, + purpose?: AppPurposeTypes + ): Promise { + const operations = throwIfNotGitHubCapable(this.operations); + if (organizationRepositoryNames.length > 30) { + throw CreateError.InvalidParameters( + 'GitHub has a hard limit of 30 repositories to update in a single patch' + ); + } + const parameters = { + org: this.organization.name, + properties: setPropertiesRecordToArray(propertiesAndValues), + repository_names: organizationRepositoryNames, + }; + (await operations.github.restApi( + this.authorize(purpose || this._defaultPurpose), + HttpMethod.Patch, + '/orgs/:org/properties/values', + parameters + )) as CreateOrUpdateResponse; + } +} + +function setPropertiesRecordToArray(propertiesAndValues: Record) { + const keys = Object.getOwnPropertyNames(propertiesAndValues); + const properties: OrganizationCustomPropertySetPropertyValue[] = []; + for (const key of keys) { + properties.push({ + property_name: key, + value: propertiesAndValues[key], + }); + } + return properties; +} diff --git a/business/project.ts b/business/project.ts index e1fb54c80..54571be82 100644 --- a/business/project.ts +++ b/business/project.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose, AppPurposeTypes } from './githubApps'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; import { Organization, Repository } from '.'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, throwIfNotGitHubCapable, - IGetAuthorizationHeader, + GetAuthorizationHeader, } from '../interfaces'; import { decorateIterable, @@ -17,7 +17,7 @@ import { IteratorResponse, PaginationPageSizeOptions, } from './iterable'; -import { CreateError, DefaultGraphqlPageSize } from '../transitional'; +import { CreateError, DefaultGraphqlPageSize } from '../lib/transitional'; import { OrganizationProjects } from './projects'; import { OrganizationProjectView } from './projectView'; @@ -117,8 +117,8 @@ export class OrganizationProject { private _projects: OrganizationProjects; private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _purpose: AppPurpose; private _id: string; @@ -126,8 +126,8 @@ export class OrganizationProject { constructor( organizationProjects: OrganizationProjects, operations: IOperationsInstance, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, projectId: string ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -413,19 +413,16 @@ export class OrganizationProject { } } - private authorize(purpose: AppPurpose = this._purpose): IGetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose = this._purpose): GetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/projectView.ts b/business/projectView.ts index 0ab645ae8..b4386b4ec 100644 --- a/business/projectView.ts +++ b/business/projectView.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose, AppPurposeTypes } from './githubApps'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; import { Organization } from '.'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, throwIfNotGitHubCapable, - IGetAuthorizationHeader, + GetAuthorizationHeader, } from '../interfaces'; import { decorateIterable, @@ -17,7 +17,7 @@ import { IteratorResponse, PaginationPageSizeOptions, } from './iterable'; -import { DefaultGraphqlPageSize } from '../transitional'; +import { DefaultGraphqlPageSize } from '../lib/transitional'; import { OrganizationProject, ProjectViewEssentials } from './project'; type ProjectViewDetails = { @@ -30,8 +30,8 @@ export class OrganizationProjectView { private _project: OrganizationProject; private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _purpose: AppPurpose; private _id: string; @@ -41,8 +41,8 @@ export class OrganizationProjectView { constructor( organizationProject: OrganizationProject, operations: IOperationsInstance, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, projectId: string, essentials?: ProjectViewEssentials ) { @@ -217,19 +217,16 @@ export class OrganizationProjectView { // } // } - private authorize(purpose: AppPurpose = this._purpose): IGetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose = this._purpose): GetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/projects.ts b/business/projects.ts index f010b3aaa..60cc6b8e6 100644 --- a/business/projects.ts +++ b/business/projects.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose, AppPurposeTypes } from './githubApps'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; import { Organization } from '.'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, throwIfNotGitHubCapable, - IGetAuthorizationHeader, + GetAuthorizationHeader, } from '../interfaces'; import { decorateIterable, @@ -17,7 +17,7 @@ import { IteratorResponse, PaginationPageSizeOptions, } from './iterable'; -import { DefaultGraphqlPageSize } from '../transitional'; +import { DefaultGraphqlPageSize } from '../lib/transitional'; import { OrganizationProject } from './project'; type ProjectResponse = { @@ -35,15 +35,15 @@ export class OrganizationProjects { private _organization: Organization; private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _purpose: AppPurpose; constructor( organization: Organization, operations: IOperationsInstance, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader + getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader ) { this._getAuthorizationHeader = getAuthorizationHeader; this._getSpecificAuthorizationHeader = getSpecificAuthorizationHeader; @@ -134,19 +134,16 @@ export class OrganizationProjects { } } - private authorize(purpose: AppPurpose = this._purpose): IGetAuthorizationHeader { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose = this._purpose): GetAuthorizationHeader { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/queryCache.ts b/business/queryCache.ts index 03c586097..d1610530d 100644 --- a/business/queryCache.ts +++ b/business/queryCache.ts @@ -16,15 +16,15 @@ import Debug from 'debug'; -import { MassagePermissionsToGitHubRepositoryPermission } from '../transitional'; -import { OrganizationMemberCacheEntity } from '../entities/organizationMemberCache/organizationMemberCache'; +import { projectCollaboratorPermissionToGitHubRepositoryPermission } from '../lib/transitional'; +import { OrganizationMemberCacheEntity } from './entities/organizationMemberCache/organizationMemberCache'; import { Operations } from './operations'; -import { TeamMemberCacheEntity } from '../entities/teamMemberCache/teamMemberCache'; +import { TeamMemberCacheEntity } from './entities/teamMemberCache/teamMemberCache'; -import { TeamCacheEntity } from '../entities/teamCache/teamCache'; -import { RepositoryTeamCacheEntity } from '../entities/repositoryTeamCache/repositoryTeamCache'; -import { RepositoryCacheEntity } from '../entities/repositoryCache/repositoryCache'; -import { RepositoryCollaboratorCacheEntity } from '../entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; +import { TeamCacheEntity } from './entities/teamCache/teamCache'; +import { RepositoryTeamCacheEntity } from './entities/repositoryTeamCache/repositoryTeamCache'; +import { RepositoryCacheEntity } from './entities/repositoryCache/repositoryCache'; +import { RepositoryCollaboratorCacheEntity } from './entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; import { Repository } from '.'; import { IProviders, @@ -665,9 +665,10 @@ export default class QueryCache { try { const organization = this.operations.getOrganizationById(Number(cacheEntity.organizationId)); const team = organization.team(Number(cacheEntity.teamId)); - const iid = cacheEntity.repositoryId; + const idAsStringOrNumber = cacheEntity.repositoryId; + const repositoryIdAsNumber = Number(idAsStringOrNumber); const repository = organization.repository(cacheEntity.repositoryName, { - id: cacheEntity.repositoryId, // a string version of repositoryId FYI + id: repositoryIdAsNumber, private: cacheEntity.repositoryPrivate, }); return { @@ -835,9 +836,8 @@ export default class QueryCache { this.throwMethodNotSupported('repositoryCollaborators', 'repositoryCollaboratorCacheProvider'); } const repositoryCollaboratorCacheProvider = this._providers.repositoryCollaboratorCacheProvider; - const rawEntities = await repositoryCollaboratorCacheProvider.queryCollaboratorsByRepositoryId( - repositoryId - ); + const rawEntities = + await repositoryCollaboratorCacheProvider.queryCollaboratorsByRepositoryId(repositoryId); return rawEntities .map((cacheEntity) => this.hydrateRepositoryCollaborator(cacheEntity)) .filter((real) => real); @@ -894,9 +894,10 @@ export default class QueryCache { cacheEntity: RepositoryCollaboratorCacheEntity ): IQueryCacheRepositoryCollaborator { const organization = this.operations.getOrganizationById(Number(cacheEntity.organizationId)); - const iid = cacheEntity.repositoryId; + const idAsStringOrNumber = cacheEntity.repositoryId; + const repositoryIdAsNumber = Number(idAsStringOrNumber); const repository = organization.repository(cacheEntity.repositoryName, { - id: cacheEntity.repositoryId, + id: repositoryIdAsNumber, private: cacheEntity.repositoryPrivate, }); // a string version of repositoryId FYI return { @@ -904,7 +905,7 @@ export default class QueryCache { affiliation: cacheEntity.collaboratorType, cacheEntity, userId: cacheEntity.userId, - permission: MassagePermissionsToGitHubRepositoryPermission(cacheEntity.permission), + permission: projectCollaboratorPermissionToGitHubRepositoryPermission(cacheEntity.permission), }; } @@ -993,9 +994,8 @@ export default class QueryCache { this.throwMethodNotSupported('organizationMembers', 'organizationMemberCacheProvider'); } const organizationMemberCacheProvider = this._providers.organizationMemberCacheProvider; - const rawEntities = await organizationMemberCacheProvider.queryOrganizationMembersByOrganizationId( - organizationId - ); + const rawEntities = + await organizationMemberCacheProvider.queryOrganizationMembersByOrganizationId(organizationId); return this.hydrateOrganizationMembers(rawEntities); } diff --git a/business/repoSearch.ts b/business/repoSearch.ts index 310f89ec8..945e54691 100644 --- a/business/repoSearch.ts +++ b/business/repoSearch.ts @@ -7,10 +7,10 @@ import querystring from 'querystring'; import { Repository } from './repository'; import { IPersonalizedUserAggregateRepositoryPermission } from './graphManager'; -import { RepositoryMetadataEntity } from '../entities/repositoryMetadata/repositoryMetadata'; -import { IRepositoryMetadataProvider } from '../entities/repositoryMetadata/repositoryMetadataProvider'; +import { RepositoryMetadataEntity } from './entities/repositoryMetadata/repositoryMetadata'; +import { IRepositoryMetadataProvider } from './entities/repositoryMetadata/repositoryMetadataProvider'; import { TeamRepositoryPermission } from './teamRepositoryPermission'; -import { sortRepositoriesByNameCaseInsensitive } from '../utils'; +import { sortRepositoriesByNameCaseInsensitive } from '../lib/utils'; import { GitHubRepositoryPermission, IRepositorySearchOptions, RepositoryLockdownState } from '../interfaces'; const defaultPageSize = 20; // GitHub.com seems to use a value around 33 diff --git a/business/repository.ts b/business/repository.ts index a1e82be00..f213ca64d 100644 --- a/business/repository.ts +++ b/business/repository.ts @@ -18,10 +18,10 @@ import { TeamMember, OrganizationMember, } from '.'; -import { RepositoryMetadataEntity } from '../entities/repositoryMetadata/repositoryMetadata'; -import { AppPurpose, AppPurposeTypes } from './githubApps'; +import { RepositoryMetadataEntity } from './entities/repositoryMetadata/repositoryMetadata'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; import { - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, IOperationsInstance, ICacheOptions, throwIfNotGitHubCapable, @@ -33,7 +33,7 @@ import { ITemporaryCommandOutput, NoCacheNoBackground, IGitHubProtectedBranchConfiguration, - IRepositoryBranchAccessProtections, + RepositoryBranchAccessProtections as RepositoryBranchAccessProtections, IListContributorsOptions, IGetCollaboratorsOptions, GitHubCollaboratorAffiliationQuery, @@ -44,19 +44,24 @@ import { IGitHubSecretScanningAlert, operationsWithCapability, IOperationsServiceAccounts, - IGetAuthorizationHeader, + GetAuthorizationHeader, IRepositoryGetIssuesOptions, IOperationsRepositoryMetadataProvider, IOperationsUrls, GitHubRepositoryPermission, + GitHubRepositoryVisibility, + GitHubRepositoryDetails, } from '../interfaces'; import { IListPullsParameters, GitHubPullRequestState } from '../lib/github/collections'; -import { wrapError } from '../utils'; +import { wrapError } from '../lib/utils'; import { RepositoryActions } from './repositoryActions'; import { RepositoryPullRequest } from './repositoryPullRequest'; -import { ErrorHelper } from '../transitional'; +import { CreateError, ErrorHelper } from '../lib/transitional'; import { augmentInertiaPreview, RepositoryProject } from './repositoryProject'; +import { RepositoryInvitation } from './repositoryInvitation'; +import { RepositoryProperties } from './repositoryProperties'; +import { WithGitHubRestHeaders } from '../lib/github/core'; interface IRepositoryMoments { created?: moment.Moment; @@ -160,6 +165,46 @@ interface IUnarchiveResponse { }; } +export type GitHubBranchProtectionParameters = { + owner: string; + repo: string; + branch: string; + required_status_checks: { + strict: boolean; + contexts: string[]; + checks?: string[]; + } | null; + enforce_admins: boolean | null; + required_pull_request_reviews: { + dismissal_restrictions: { + users: string[]; + teams: string[]; + apps: string[]; + }; + dismiss_stale_reviews: boolean; + require_code_owner_reviews: boolean; + required_approving_review_count: number; + require_last_push_approval: boolean; + bypass_pull_request_allowances: { + users: string[]; + teams: string[]; + apps: string[]; + }; + } | null; + restrictions: { + users: string[]; + teams: string[]; + apps: string[]; + }; + required_linear_history: boolean; + allow_force_pushes: boolean | null; + allow_deletions: boolean; + block_creations: boolean; + required_conversation_resolution: boolean; + lock_branch: boolean; + allow_fork_syncing: boolean; +}; + export type GitHubPagesResponse = { status: string; cname: string; @@ -203,6 +248,7 @@ const safeEntityFieldsForJsonSend = [ 'stargazers_count', 'open_issues_count', 'id', + 'visibility' ]; const sortByLogin = (list) => { @@ -218,7 +264,7 @@ const sortByLogin = (list) => { }; export class Repository { - private _entity: any; + private _entity: WithGitHubRestHeaders; private _baseUrl: string; private _absoluteBaseUrl: string; private _nativeUrl: string; @@ -226,17 +272,18 @@ export class Repository { private _awesomeness: number; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _operations: IOperationsInstance; private _organization: Organization; + private _customProperties: RepositoryProperties; private _name: string; private _moments: IRepositoryMoments; - getEntity(): any { + getEntity(): WithGitHubRestHeaders { return this._entity; } @@ -270,6 +317,9 @@ export class Repository { get private(): boolean { return this._entity ? this._entity.private : false; } + get visibility(): GitHubRepositoryVisibility { + return this._entity ? this._entity.visibility : null; + } get html_url(): string { return this._entity ? this._entity.html_url : null; } @@ -285,13 +335,13 @@ export class Repository { get archived(): boolean { return this._entity ? this._entity.archived : false; } - get created_at(): Date { + get created_at(): string { return this._entity ? this._entity.created_at : null; } - get updated_at(): Date { + get updated_at(): string { return this._entity ? this._entity.updated_at : null; } - get pushed_at(): Date { + get pushed_at(): string { return this._entity ? this._entity.pushed_at : null; } get git_url(): string { @@ -375,8 +425,8 @@ export class Repository { constructor( organization: Organization, entity: any, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, operations: IOperationsInstance ) { this._organization = organization; @@ -397,6 +447,17 @@ export class Repository { this._operations = operations; } + get customProperties() { + if (!this._customProperties) { + this._customProperties = new RepositoryProperties( + this, + this._operations, + this._getSpecificAuthorizationHeader.bind(this) + ); + } + return this._customProperties; + } + get moment(): IRepositoryMoments { if (!this._moments) { this._moments = { @@ -417,6 +478,17 @@ export class Repository { }; } + async getId(options?: ICacheOptions): Promise { + // Repositories by name may not actually have the ID; this ensures it's available + // and a number. Similar to previously checking "isDeleted" or "getDetails" first. + if (!this.id) { + await this.getDetails(options); + } + if (this.id) { + return typeof this.id === 'number' ? this.id : parseInt(this.id, 10); + } + } + async isDeleted(options?: ICacheOptions): Promise { try { await this.getDetails(options); @@ -437,12 +509,22 @@ export class Repository { ); } - async getDetails(options?: ICacheOptions): Promise { + async getDetails(options?: ICacheOptions): Promise> { options = options || {}; const operations = throwIfNotGitHubCapable(this._operations); - if (this.id && !this.name) { + const cacheOptions: ICacheOptions = { + maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgRepoDetailsStaleSeconds, options), + }; + if (options.backgroundRefresh !== undefined) { + cacheOptions.backgroundRefresh = options.backgroundRefresh; + } + if ((options as any).noConditionalRequests === true) { + (cacheOptions as any).noConditionalRequests = true; + } + // always prefer ID over name + if (this.id) { try { - const lookupById = await this.organization.getRepositoryById(this.id); + const lookupById = await this.organization.getRepositoryById(this.id, cacheOptions); this._entity = lookupById.getEntity(); this._name = this._entity.name; } catch (getByIdError) { @@ -460,17 +542,8 @@ export class Repository { if (mediaType) { (parameters as any).mediaType = mediaType; } - const cacheOptions: ICacheOptions = { - maxAgeSeconds: getMaxAgeSeconds(operations, CacheDefault.orgRepoDetailsStaleSeconds, options), - }; - if (options.backgroundRefresh !== undefined) { - cacheOptions.backgroundRefresh = options.backgroundRefresh; - } - if ((options as any).noConditionalRequests === true) { - (cacheOptions as any).noConditionalRequests = true; - } try { - let entity: any = undefined; + let entity: WithGitHubRestHeaders = undefined; if ((cacheOptions as any)?.noConditionalRequests === true) { entity = await operations.github.post(this.authorize(AppPurpose.Data), 'repos.get', parameters); } else { @@ -758,6 +831,27 @@ export class Repository { } } + async updateBranchProtectionRule2( + parameters: GitHubBranchProtectionParameters, + cacheOptions?: ICacheOptions + ): Promise { + cacheOptions = cacheOptions || {}; + const operations = throwIfNotGitHubCapable(this._operations); + const github = operations.github; + + Object.assign(parameters, cacheOptions); + // PUT /repos/{owner}/{repo}/branches/{branch}/protection + const protections = await github.call( + this.authorize(AppPurpose.Data), + 'repos.updateBranchProtection', + parameters + ); + if (protections.length >= 100) { + console.warn('This API does not support pagination currently... there may be more items'); + } + return protections as RepositoryBranchAccessProtections; + } + async listBranchProtectionRules(): Promise { await this.organization.requireUpdatesApp('listBranchProtectionRules'); const query = `query($owner: String!, $repo: String!) { @@ -810,7 +904,7 @@ export class Repository { async getProtectedBranchAccessRestrictions( branchName: string, cacheOptions?: ICacheOptions - ): Promise { + ): Promise { // NOTE: GitHub has a "100-item limit" currently. This is an object response and not // technically paginated. cacheOptions = cacheOptions || {}; @@ -834,7 +928,31 @@ export class Repository { 'repos.getBranchProtection', parameters ); - return protections as IRepositoryBranchAccessProtections; + return protections as RepositoryBranchAccessProtections; + } + + async getAdminProtectedBranchAccessRestrictions( + branchName: string, + cacheOptions?: ICacheOptions + ): Promise { + // NOTE: GitHub has a "100-item limit" currently. This is an object response and not + // technically paginated. + cacheOptions = cacheOptions || {}; + const operations = throwIfNotGitHubCapable(this._operations); + const github = operations.github; + const parameters = { + owner: this.organization.name, + repo: this.name, + branch: branchName, + }; + Object.assign(parameters, cacheOptions); + // GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins + const protections = await github.call( + this.authorize(AppPurpose.Data), + 'repos.getAdminBranchProtection', + parameters + ); + return protections as RepositoryBranchAccessProtections; } async setDefaultBranch(defaultBranchName: string): Promise { @@ -882,9 +1000,8 @@ export class Repository { cacheOptions.backgroundRefresh = options.backgroundRefresh; } try { - // CONSIDER: need a fallback authentication approach: try and app for a specific capability (the installation knows) and fallback to central ops - // const centralOps = operationsWithCapability(operations, CoreCapability.GitHubCentralOperations); - const tokenSource = this._getSpecificAuthorizationHeader(AppPurpose.Data); // centralOps ? centralOps.getCentralOperationsToken()(AppPurpose.Data) : + // CONSIDER: need a fallback authentication approach: try and app for a specific capability + const tokenSource = this._getSpecificAuthorizationHeader(AppPurpose.Data); const token = await tokenSource; return await operations.github.call(token, 'repos.getPages', parameters, cacheOptions); } catch (error) { @@ -1056,6 +1173,39 @@ export class Repository { return collaborators; } + async listCollaboratorInvitations(cacheOptions?: IPagedCacheOptions): Promise { + cacheOptions = cacheOptions || {}; + const operations = throwIfNotGitHubCapable(this._operations); + const github = operations.github; + const parameters = { + owner: this.organization.name, + repo: this.name, + per_page: getPageSize(operations), + }; + if (!cacheOptions.maxAgeSeconds) { + cacheOptions.maxAgeSeconds = getMaxAgeSeconds( + operations, + CacheDefault.orgRepoCollaboratorsStaleSeconds + ); + } + if (cacheOptions.backgroundRefresh === undefined) { + cacheOptions.backgroundRefresh = true; + } + const invitationEntities = await github.collections.getRepoInvitations( + this.authorize(AppPurpose.Data), + parameters, + cacheOptions + ); + const invitations = common.createInstances( + this, + invitationFromEntity, + invitationEntities + ); + invitationEntities?.cost && ((invitations as any).cost = invitationEntities.cost); + invitationEntities?.headers && ((invitations as any).headers = invitationEntities.headers); + return invitations; + } + async addCollaborator( username: string, permission: GitHubRepositoryPermission @@ -1330,9 +1480,6 @@ export class Repository { private: options.private, } ); - // BUG: GitHub Apps do not work with locking down no repository permissions as documented here: https://github.community/t5/GitHub-API-Development-and/GitHub-App-cannot-patch-repo-visibility-in-org-with-repo/m-p/33448#M3150 - // const token = this._operations.getCentralOperationsToken(); - // return this._operations.github.post(token, 'repos.update', parameters); return operations.github.post(this.authorize(AppPurpose.Operations), 'repos.update', parameters); } @@ -1554,7 +1701,10 @@ export class Repository { const teams = (await this.getTeamPermissions()).filter((tp) => tp.permission === 'admin'); for (let i = 0; i < teams.length; i++) { const team = teams[i]; - if (excludeBroadAndSystemTeams && (team.team.isSystemTeam || team.team.isBroadAccessTeam)) { + if ( + excludeBroadAndSystemTeams && + (team.team.isSystemTeam || team.team.isBroadAccessTeam || team.team.isOpenAccessTeam) + ) { // Do not include broad access teams continue; } @@ -1734,19 +1884,16 @@ export class Repository { return Array.from(users.values()); } - private authorize(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } - private specificAuthorization(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { + private specificAuthorization(purpose: AppPurposeTypes): GetAuthorizationHeader | string { const getSpecificHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getSpecificHeader; } @@ -2014,3 +2161,9 @@ function collaboratorPermissionFromEntity(entity) { const permission = new Collaborator(entity); return permission; } + +function invitationFromEntity(entity) { + // 'this' is bound for this function to be a private method + const invitation = new RepositoryInvitation(this, entity); + return invitation; +} diff --git a/business/repositoryActions.ts b/business/repositoryActions.ts index ec2d2b539..fff60e0c7 100644 --- a/business/repositoryActions.ts +++ b/business/repositoryActions.ts @@ -5,16 +5,13 @@ import { Repository } from './repository'; import { getPageSize, getMaxAgeSeconds, CacheDefault } from '.'; -import { AppPurpose } from './githubApps'; +import { AppPurpose } from '../lib/github/appPurposes'; import { - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, IOperationsInstance, - IGetBranchesOptions, - IGitHubBranch, throwIfNotGitHubCapable, - IGetPullsOptions, ICacheOptions, - IGetAuthorizationHeader, + GetAuthorizationHeader, } from '../interfaces'; export interface IGitHubActionWorkflowsResponse { @@ -36,16 +33,16 @@ export interface IGitHubActionWorkflow { } export class RepositoryActions { - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _operations: IOperationsInstance; private _repository: Repository; constructor( repository: Repository, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, operations: IOperationsInstance ) { this._repository = repository; @@ -178,11 +175,11 @@ export class RepositoryActions { return entity; } - private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { + private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/repositoryInvitation.ts b/business/repositoryInvitation.ts new file mode 100644 index 000000000..449774cbb --- /dev/null +++ b/business/repositoryInvitation.ts @@ -0,0 +1,77 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { GitHubRepositoryPermission, GitHubSimpleAccount } from '../interfaces'; +import * as common from './common'; +import { Repository } from './repository'; + +const primaryProperties = ['inviter', 'invitee', 'permissions', 'created_at', 'html_url', 'node_id']; + +export type RepositoryInvitationClientJson = { + inviter: { + id: number; + login: string; + }; + invitee: { + id: number; + login: string; + }; + permissions: GitHubRepositoryPermission; + created_at: string; + html_url: string; + // node_id: string; +}; + +export class RepositoryInvitation { + public static PrimaryProperties = primaryProperties; + + private _inviter: GitHubSimpleAccount; + private _invitee: GitHubSimpleAccount; + private _permissions: GitHubRepositoryPermission; + private _html_url: string; + private _created_at: string; + + constructor( + private repository: Repository, + entity: unknown + ) { + if (entity) { + common.assignKnownFieldsPrefixed(this, entity, 'invitation', primaryProperties); + } + } + + asJson(): RepositoryInvitationClientJson { + return { + invitee: this.invitee, + inviter: this.inviter, + permissions: this.permission, + html_url: this.invitationUrl, + created_at: this._created_at, + }; + } + + get permission(): GitHubRepositoryPermission { + return this._permissions; + } + + // getHighestPermission() { + // if (!this._permissions) { + // return GitHubRepositoryPermission.None; + // } + // return projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(this._permissions); + // } + + get inviter(): GitHubSimpleAccount { + return this._inviter; + } + + get invitee(): GitHubSimpleAccount { + return this._invitee; + } + + get invitationUrl(): string { + return this._html_url; + } +} diff --git a/business/repositoryIssue.ts b/business/repositoryIssue.ts index 936bc606b..3e80750e0 100644 --- a/business/repositoryIssue.ts +++ b/business/repositoryIssue.ts @@ -4,25 +4,25 @@ // import { Repository } from './repository'; -import { wrapError } from '../utils'; -import { AppPurpose } from './githubApps'; +import { wrapError } from '../lib/utils'; +import { AppPurpose } from '../lib/github/appPurposes'; import { CacheDefault, getMaxAgeSeconds, Operations } from '.'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, GitHubIssueState, IIssueLabel, throwIfNotGitHubCapable, ICacheOptions, - IGetAuthorizationHeader, + GetAuthorizationHeader, GitHubIssuePatchParameters, GitHubStateReason, } from '../interfaces'; -import { CreateError, ErrorHelper } from '../transitional'; +import { CreateError, ErrorHelper } from '../lib/transitional'; export class RepositoryIssue { private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; private _number: number; private _repository: Repository; @@ -33,7 +33,7 @@ export class RepositoryIssue { repository: Repository, issueNumber: number, operations: IOperationsInstance, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, entity?: any ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -211,11 +211,8 @@ export class RepositoryIssue { return false; } - private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } diff --git a/business/repositoryPermission.ts b/business/repositoryPermission.ts index daea8021f..a0dbcca24 100644 --- a/business/repositoryPermission.ts +++ b/business/repositoryPermission.ts @@ -9,17 +9,21 @@ import { GitHubCollaboratorPermissionLevel, ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermission, GitHubRepositoryPermission, + IGitHubCollaboratorPermissions, } from '../interfaces'; +import type { CollaboratorAccount, CollaboratorJson } from './collaborator'; // prettier-ignore const repoPermissionProperties = [ 'permission', 'user', + 'role_name', ]; export class RepositoryPermission { - private _id: string; - private _user: any; + private _id: number; + private _user: CollaboratorAccount; + private _role_name: string; private _permission: GitHubCollaboratorPermissionLevel; @@ -32,17 +36,86 @@ export class RepositoryPermission { } } - get id(): string { + get id(): number { return this._id; } + + get roleName(): string { + return this._role_name; + } + get permission(): GitHubCollaboratorPermissionLevel { return this._permission; } - get user(): any { + + get user(): CollaboratorAccount { return this._user; } - public asGitHubRepositoryPermission(): GitHubRepositoryPermission { + asCollaboratorJson(): CollaboratorJson { + return { + avatar_url: null, + id: this._id, + login: this._user?.login, + permissions: this.asCollaboratorPermissions(), + }; + } + + asCollaboratorPermissions(): IGitHubCollaboratorPermissions { + return repositoryPermissionToPermissionsObject(this.asGitHubLegacyRepositoryPermission()); + } + + asGitHubLegacyRepositoryPermission(): GitHubRepositoryPermission { + // GitHub's API will only return "admin", "read", "write"; while the function + // implements recognition of maintain, etc., it isn't a thing. return ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermission(this._permission); } + + hasCustomRolePermission() { + switch (this._role_name) { + case GitHubRepositoryPermission.Admin: + case GitHubRepositoryPermission.Maintain: + case GitHubRepositoryPermission.Triage: + case GitHubRepositoryPermission.Push: + case GitHubRepositoryPermission.Pull: + return false; + default: + return true; + } + } + + interpretRoleAsDetailedPermission(): GitHubRepositoryPermission { + if (!this.hasCustomRolePermission()) { + return this._role_name as GitHubRepositoryPermission; + } + return this.asGitHubLegacyRepositoryPermission(); + } +} + +export function repositoryPermissionToPermissionsObject( + permission: GitHubRepositoryPermission +): IGitHubCollaboratorPermissions { + const permissions: IGitHubCollaboratorPermissions = { + admin: false, + maintain: false, + push: false, + triage: false, + pull: false, + }; + if (permission === GitHubRepositoryPermission.Admin) { + permissions.admin = true; + } + if (permission === GitHubRepositoryPermission.Maintain || permissions.admin === true) { + permissions.maintain = true; + } + if (permission === GitHubRepositoryPermission.Push || permissions.maintain === true) { + permissions.push = true; + } + if (permission === GitHubRepositoryPermission.Triage || permissions.push === true) { + permissions.triage = true; + } + if (permission === GitHubRepositoryPermission.Pull || permissions.triage === true) { + permissions.pull = true; + } + return permissions; } diff --git a/business/repositoryProject.ts b/business/repositoryProject.ts index 5bf5d084e..034eea1d9 100644 --- a/business/repositoryProject.ts +++ b/business/repositoryProject.ts @@ -4,26 +4,26 @@ // import { Repository } from './repository'; -import { wrapError } from '../utils'; -import { AppPurpose, AppPurposeTypes } from './githubApps'; +import { wrapError } from '../lib/utils'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; import { CacheDefault, getMaxAgeSeconds } from '.'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, GitHubIssueState, throwIfNotGitHubCapable, ICacheOptions, - IGetAuthorizationHeader, + GetAuthorizationHeader, ICacheOptionsWithPurpose, } from '../interfaces'; -import { ErrorHelper } from '../transitional'; +import { ErrorHelper } from '../lib/transitional'; import { RepositoryProjectColumn } from './repositoryProjectColumn'; import * as common from './common'; export class RepositoryProject { private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _id: number; private _repository: Repository; @@ -36,8 +36,8 @@ export class RepositoryProject { repository: Repository, projectId: number, operations: IOperationsInstance, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, entity?: any ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -213,11 +213,11 @@ export class RepositoryProject { return false; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/repositoryProjectCard.ts b/business/repositoryProjectCard.ts index 596c3a14d..2e052422c 100644 --- a/business/repositoryProjectCard.ts +++ b/business/repositoryProjectCard.ts @@ -3,17 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurpose } from './githubApps'; -import { - IOperationsInstance, - IPurposefulGetAuthorizationHeader, - IGetAuthorizationHeader, -} from '../interfaces'; +import { AppPurpose } from '../lib/github/appPurposes'; +import { IOperationsInstance, PurposefulGetAuthorizationHeader, GetAuthorizationHeader } from '../interfaces'; import { RepositoryProjectColumn } from './repositoryProjectColumn'; export class RepositoryProjectCard { private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; private _id: number; private _column: RepositoryProjectColumn; @@ -24,7 +20,7 @@ export class RepositoryProjectCard { column: RepositoryProjectColumn, cardId: number, operations: IOperationsInstance, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, entity?: any ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -64,11 +60,8 @@ export class RepositoryProjectCard { return this._column; } - private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } diff --git a/business/repositoryProjectColumn.ts b/business/repositoryProjectColumn.ts index c69fc7017..d0dd408d2 100644 --- a/business/repositoryProjectColumn.ts +++ b/business/repositoryProjectColumn.ts @@ -4,11 +4,11 @@ // import { CacheDefault, getMaxAgeSeconds, RepositoryIssue } from '.'; -import { AppPurpose, AppPurposeTypes } from './githubApps'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, - IGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, + GetAuthorizationHeader, ICacheOptionsWithPurpose, throwIfNotGitHubCapable, ICacheOptions, @@ -16,11 +16,11 @@ import { import { augmentInertiaPreview, RepositoryProject } from './repositoryProject'; import { RepositoryProjectCard } from './repositoryProjectCard'; import * as common from './common'; -import { CreateError } from '../transitional'; +import { CreateError } from '../lib/transitional'; export class RepositoryProjectColumn { private _operations: IOperationsInstance; - private _getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; private _id: number; private _project: RepositoryProject; @@ -31,7 +31,7 @@ export class RepositoryProjectColumn { project: RepositoryProject, columnId: number, operations: IOperationsInstance, - getSpecificAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader, entity?: any ) { this._getSpecificAuthorizationHeader = getSpecificAuthorizationHeader; @@ -136,11 +136,11 @@ export class RepositoryProjectColumn { return card; } - private authorizeSpecificPurpose(purpose: AppPurposeTypes): IGetAuthorizationHeader | string { + private authorizeSpecificPurpose(purpose: AppPurposeTypes): GetAuthorizationHeader | string { const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( this, purpose - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/repositoryProperties.ts b/business/repositoryProperties.ts new file mode 100644 index 000000000..f653ebff6 --- /dev/null +++ b/business/repositoryProperties.ts @@ -0,0 +1,77 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { Repository } from './repository'; +import { AppPurpose, AppPurposeTypes } from '../lib/github/appPurposes'; +import { createCacheOptions, popPurpose, symbolizeApiResponse } from '.'; +import { + IOperationsInstance, + PurposefulGetAuthorizationHeader, + throwIfNotGitHubCapable, + GetAuthorizationHeader, + ICacheOptionsWithPurpose, +} from '../interfaces'; +import { OrganizationCustomPropertySetPropertyValue } from './organizationProperties'; + +export class RepositoryProperties { + private _defaultPurpose = AppPurpose.Data; + private _getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader; + + constructor( + public readonly repository: Repository, + private operations: IOperationsInstance, + getSpecificAuthorizationHeader: PurposefulGetAuthorizationHeader + ) { + this._getSpecificAuthorizationHeader = getSpecificAuthorizationHeader; + } + + createOrUpdateProperties( + propertiesAndValues: Record, + purpose?: AppPurposeTypes + ): Promise { + const names = [this.repository.name]; + const organizationProperties = this.repository.organization.customProperties; + return organizationProperties.createOrUpdateRepositoriesProperties(names, propertiesAndValues, purpose); + } + + async getProperties(options?: ICacheOptionsWithPurpose): Promise> { + options = options || {}; + const operations = throwIfNotGitHubCapable(this.operations); + const { github } = operations; + const purpose = popPurpose(options, this._defaultPurpose); + const parameters = { + owner: this.repository.organization.name, + repo: this.repository.name, + }; + const cacheOptions = createCacheOptions(operations, options); + try { + const responseArray = await github.request( + this.authorize(purpose), + 'GET /repos/:owner/:repo/properties/values', + parameters, + cacheOptions + ); + return symbolizeApiResponse(arrayToSetProperties(responseArray)); + } catch (error) { + throw error; + } + } + + private authorize(purpose: AppPurposeTypes): GetAuthorizationHeader | string { + const getAuthorizationHeader = this._getSpecificAuthorizationHeader.bind( + this, + purpose + ) as GetAuthorizationHeader; + return getAuthorizationHeader; + } +} + +function arrayToSetProperties(properties: OrganizationCustomPropertySetPropertyValue[]) { + const propertiesAndValues: Record = {}; + for (const property of properties) { + propertiesAndValues[property.property_name] = property.value; + } + return propertiesAndValues; +} diff --git a/business/repositoryPullRequest.ts b/business/repositoryPullRequest.ts index 81d2b8a51..41fad1c01 100644 --- a/business/repositoryPullRequest.ts +++ b/business/repositoryPullRequest.ts @@ -4,26 +4,26 @@ // import { Repository } from './repository'; -import { wrapError } from '../utils'; -import { AppPurpose } from './githubApps'; +import { wrapError } from '../lib/utils'; +import { AppPurpose } from '../lib/github/appPurposes'; import { CacheDefault, getMaxAgeSeconds } from '.'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, GitHubIssueState, IIssueLabel, throwIfNotGitHubCapable, ICacheOptions, - IGetAuthorizationHeader, + GetAuthorizationHeader, } from '../interfaces'; -import { ErrorHelper } from '../transitional'; +import { ErrorHelper } from '../lib/transitional'; // Pull requests are issues but not all issues are pull requests. So this is mostly a clone of repositoryIssue.ts // right now, with slightly different endpoints. export class RepositoryPullRequest { private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; private _number: number; private _repository: Repository; @@ -34,7 +34,7 @@ export class RepositoryPullRequest { repository: Repository, pullRequestNumber: number, operations: IOperationsInstance, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, entity?: any ) { this._getAuthorizationHeader = getAuthorizationHeader; @@ -219,11 +219,8 @@ export class RepositoryPullRequest { return false; } - private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/team.ts b/business/team.ts index d2950b1e6..33e17002f 100644 --- a/business/team.ts +++ b/business/team.ts @@ -8,16 +8,16 @@ import _ from 'lodash'; import * as common from './common'; -import { wrapError } from '../utils'; +import { wrapError } from '../lib/utils'; import { TeamMember } from './teamMember'; import { TeamRepositoryPermission } from './teamRepositoryPermission'; -import { IApprovalProvider } from '../entities/teamJoinApproval/approvalProvider'; -import { TeamJoinApprovalEntity } from '../entities/teamJoinApproval/teamJoinApproval'; -import { AppPurpose } from './githubApps'; +import { IApprovalProvider } from './entities/teamJoinApproval/approvalProvider'; +import { TeamJoinApprovalEntity } from './entities/teamJoinApproval/teamJoinApproval'; +import { AppPurpose } from '../lib/github/appPurposes'; import { CacheDefault, getMaxAgeSeconds, getPageSize, Organization } from '.'; import { IOperationsInstance, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, TeamJsonFormat, throwIfNotCapable, IOperationsUrls, @@ -25,7 +25,7 @@ import { ICacheOptions, throwIfNotGitHubCapable, IPagedCacheOptions, - IGetAuthorizationHeader, + GetAuthorizationHeader, IUpdateTeamMembershipOptions, GitHubTeamRole, ITeamMembershipRoleState, @@ -36,8 +36,9 @@ import { IGetTeamRepositoriesOptions, GitHubRepositoryType, IOperationsProviders, + GitHubTeamDetails, } from '../interfaces'; -import { validateGitHubLogin, ErrorHelper } from '../transitional'; +import { validateGitHubLogin, ErrorHelper } from '../lib/transitional'; const teamPrimaryProperties = [ 'id', @@ -82,7 +83,7 @@ export class Team { private _organization: Organization; private _operations: IOperationsInstance; - private _getAuthorizationHeader: IPurposefulGetAuthorizationHeader; + private _getAuthorizationHeader: PurposefulGetAuthorizationHeader; private _id: number; @@ -139,7 +140,7 @@ export class Team { constructor( organization: Organization, entity, - getAuthorizationHeader: IPurposefulGetAuthorizationHeader, + getAuthorizationHeader: PurposefulGetAuthorizationHeader, operations: IOperationsInstance ) { if (!entity || !entity.id) { @@ -181,6 +182,7 @@ export class Team { clone.corporateMetadata = { isSystemTeam: this.isSystemTeam, isBroadAccessTeam: this.isBroadAccessTeam, + isOpenAccessTeam: this.isOpenAccessTeam, }; return clone; } @@ -216,7 +218,7 @@ export class Team { if (this._name && this._slug) { return; } - return await this.getDetails(); + await this.getDetails(); } async isDeleted(options?: ICacheOptions): Promise { @@ -230,7 +232,7 @@ export class Team { return false; } - async getDetails(options?: ICacheOptions): Promise { + async getDetails(options?: ICacheOptions): Promise { options = options || {}; const operations = throwIfNotGitHubCapable(this._operations); const cacheOptions = { @@ -303,7 +305,7 @@ export class Team { const getAuthorizationHeader = this._getAuthorizationHeader.bind( this, AppPurpose.Data - ) as IGetAuthorizationHeader; + ) as GetAuthorizationHeader; const teamEntities = await github.collections.getTeamChildTeams( getAuthorizationHeader, parameters, @@ -323,6 +325,15 @@ export class Team { return res >= 0; } + get isOpenAccessTeam(): boolean { + const teams = this._organization.openAccessTeams; + if (typeof this._id !== 'number') { + throw new Error('Team.id must be a number'); + } + const res = teams.indexOf(this._id); + return res >= 0; + } + get isSystemTeam(): boolean { const systemTeams = this._organization.systemTeamIds; const res = systemTeams.indexOf(this._id); @@ -687,11 +698,8 @@ export class Team { }; } - private authorize(purpose: AppPurpose): IGetAuthorizationHeader | string { - const getAuthorizationHeader = this._getAuthorizationHeader.bind( - this, - purpose - ) as IGetAuthorizationHeader; + private authorize(purpose: AppPurpose): GetAuthorizationHeader | string { + const getAuthorizationHeader = this._getAuthorizationHeader.bind(this, purpose) as GetAuthorizationHeader; return getAuthorizationHeader; } } diff --git a/business/teamMember.ts b/business/teamMember.ts index bca38e787..7e68c535f 100644 --- a/business/teamMember.ts +++ b/business/teamMember.ts @@ -23,6 +23,12 @@ const memberPrimaryProperties = [ ]; const memberSecondaryProperties = []; +export type TeamMemberJson = { + id: number; + login: string; + avatar_url: string; +}; + export class TeamMember { private _team: Team; private _operations: IOperationsInstance; @@ -76,7 +82,7 @@ export class TeamMember { this._operations = operations; } - asJson() { + asJson(): TeamMemberJson { return { id: this.id, login: this.login, diff --git a/business/teamPermission.ts b/business/teamPermission.ts index f05f49d28..3fd781410 100644 --- a/business/teamPermission.ts +++ b/business/teamPermission.ts @@ -9,24 +9,61 @@ import { Organization } from './organization'; import { TeamMember } from './teamMember'; import { Team } from '.'; import { - IOperationsInstance, + type IOperationsInstance, GitHubTeamPrivacy, TeamJsonFormat, - IGetMembersOptions, + type IGetMembersOptions, GitHubRepositoryPermission, + type IGitHubTeamBasics, } from '../interfaces'; +import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../lib/transitional'; + +export interface ITeamRepositoryPermission { + pull: boolean; + triage: boolean; + push: boolean; + maintain: boolean; + admin: boolean; +} + +export function isStandardGitHubTeamPermission(val: string | GitHubRepositoryPermission) { + switch (val) { + case GitHubRepositoryPermission.Pull: + case GitHubRepositoryPermission.Triage: + case GitHubRepositoryPermission.Push: + case GitHubRepositoryPermission.Maintain: + case GitHubRepositoryPermission.Admin: + return true; + default: + return false; + } +} + +type TeamPermissionIncomingEntity = { + name: string; + id: number; + // node_id: we remove this currently + slug: string; + description: string; + privacy: GitHubTeamPrivacy; + permission: GitHubRepositoryPermission | string; + permissions: ITeamRepositoryPermission; + parent: IGitHubTeamBasics; +}; export class TeamPermission { + // private _operations: IOperationsInstance; private _organization: Organization; - private _operations: IOperationsInstance; private _team: Team; - private _permission: GitHubRepositoryPermission; + private _permission: GitHubRepositoryPermission | string; private _privacy: GitHubTeamPrivacy; private _teamMembersIfSet: TeamMember[]; + private _entity: TeamPermissionIncomingEntity; + [util.inspect.custom](depth, options) { return `GitHub Team Permission: team=${this.team?.slug || this.team?.id} permission=${this._permission}`; } @@ -41,7 +78,7 @@ export class TeamPermission { }; } - get permission(): GitHubRepositoryPermission { + get permission(): string | GitHubRepositoryPermission { return this._permission; } @@ -53,8 +90,13 @@ export class TeamPermission { return this._team; } - constructor(organization: Organization, entity: any, operations: IOperationsInstance) { + constructor( + organization: Organization, + entity: TeamPermissionIncomingEntity, + operations: IOperationsInstance + ) { this._organization = organization; + this._entity = entity; this._permission = entity.permission; this._privacy = entity.privacy; @@ -65,7 +107,7 @@ export class TeamPermission { const id = entity.id; this._team = organization.team(id, entity); - this._operations = operations; + // this._operations = operations; } get relativeJoinLink() { @@ -82,6 +124,20 @@ export class TeamPermission { } } + get customRoleName() { + if (!isStandardGitHubTeamPermission(this._entity.permission)) { + return this._entity.permission; + } + } + + get permissions(): ITeamRepositoryPermission { + return this._entity.permissions; + } + + getAsPermission(): GitHubRepositoryPermission { + return projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(this._entity.permissions); + } + async resolveTeamMembers(options?: IGetMembersOptions): Promise { this._teamMembersIfSet = await this.team.getMembers(options); } diff --git a/business/teamRepositoryPermission.ts b/business/teamRepositoryPermission.ts index 1ed650604..972d8e51d 100644 --- a/business/teamRepositoryPermission.ts +++ b/business/teamRepositoryPermission.ts @@ -5,29 +5,48 @@ import { Team } from './team'; import { Repository } from './repository'; -import { IOperationsInstance } from '../interfaces'; + +import type { GitHubRepositoryPermission, IOperationsInstance } from '../interfaces'; +import { isStandardGitHubTeamPermission, type ITeamRepositoryPermission } from './teamPermission'; +import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../lib/transitional'; + +// this is used when a team returns the repositories it can work with; +// the GitHub API is pretty inconsistent. The actual entities are a combination of +// repository AND permission here. + +type RepositoryWithTeamPermissionsEntity = { + id: number; + name: string; + full_name: string; + private: boolean; + description: string; + fork: boolean; + permissions: ITeamRepositoryPermission; + role_name: string; +}; export class TeamRepositoryPermission { + // private _operations: IOperationsInstance; + + private _entity: RepositoryWithTeamPermissionsEntity; + private _team: Team; - private _operations: IOperationsInstance; - private _permissions: any; private _repository: Repository; private _id: number; - constructor(team: Team, entity: any, operations: IOperationsInstance) { + constructor(team: Team, entity: RepositoryWithTeamPermissionsEntity, operations: IOperationsInstance) { this._team = team; if (!entity) { throw new Error('TeamRepositoryPermission: requires entity'); } - this._permissions = entity.permissions; + this._entity = entity; this._repository = team.organization.repositoryFromEntity(entity); this._id = this._repository.id; - this._operations = operations; } asJson() { const repo = this._repository.asJson(); - const permissions = this._permissions; + const permissions = this.permissions; const combined = { ...repo, permissions }; return combined; } @@ -44,8 +63,18 @@ export class TeamRepositoryPermission { return this._id; } - get permissions(): any { - return this._permissions; + get customRoleName() { + if (!isStandardGitHubTeamPermission(this._entity.role_name)) { + return this._entity.role_name; + } + } + + get permissions(): ITeamRepositoryPermission { + return this._entity.permissions; + } + + getAsPermission(): GitHubRepositoryPermission { + return projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(this._entity.permissions); } get name(): string { diff --git a/business/user/aggregate.ts b/business/user/aggregate.ts index 30aabe83f..63116e9e5 100644 --- a/business/user/aggregate.ts +++ b/business/user/aggregate.ts @@ -19,7 +19,7 @@ import { OrganizationMembershipRoleQuery, GitHubRepositoryPermission, } from '../../interfaces'; -import { SettleToStateValue, isPermissionBetterThan, ErrorHelper } from '../../transitional'; +import { SettleToStateValue, isPermissionBetterThan, ErrorHelper } from '../../lib/transitional'; import LinkManager from './linkManager'; // PLANNING once consolidated @@ -267,7 +267,11 @@ export class UserContext { const permission = tp.permission; const entity = { ...team.toSimpleJsonObject() }; entity['permission'] = permission; - const teamRepositoryPermission = new TeamRepositoryPermission(team, entity, this._operations); + const teamRepositoryPermission = new TeamRepositoryPermission( + team, + entity as any /* RepositoryWithTeamPermissionsEntity */, + this._operations + ); if (isPermissionBetterThan(bestPermission, permission)) { bestPermission = permission; } diff --git a/business/user/index.ts b/business/user/index.ts index 93d52895e..e74c64fdd 100644 --- a/business/user/index.ts +++ b/business/user/index.ts @@ -10,7 +10,7 @@ import objectPath from 'object-path'; import Debug from 'debug'; const debug = Debug.debug('context'); -import { addBreadcrumb, isCodespacesAuthenticating } from '../../utils'; +import { addBreadcrumb, isCodespacesAuthenticating } from '../../lib/utils'; import { Operations } from '../operations'; import { UserContext } from './aggregate'; import { @@ -537,7 +537,7 @@ export class IndividualContext { async isPortalAdministrator(): Promise { const operations = this._operations; - const ghi = this.getGitHubIdentity().username; + const ghi = this.getGitHubIdentity()?.username; const link = this._link; this._isPortalAdministrator = await operations.isPortalSudoer(ghi, link); return this._isPortalAdministrator; diff --git a/webhooks/organizationProcessor.ts b/business/webhooks/organizationProcessor.ts similarity index 88% rename from webhooks/organizationProcessor.ts rename to business/webhooks/organizationProcessor.ts index a84150a9a..d20905548 100644 --- a/webhooks/organizationProcessor.ts +++ b/business/webhooks/organizationProcessor.ts @@ -6,18 +6,21 @@ import crypto from 'crypto'; import secureCompare from 'secure-compare'; -import { Operations } from '../business'; -import { Organization } from '../business'; +import { Organization } from '..'; -import Tasks from './tasks'; -import { sleep } from '../utils'; -import { type IProviders } from '../interfaces'; +import { sleep } from '../../lib/utils'; +import { type IProviders } from '../../interfaces'; + +import defaultWebhookTasks from './tasks'; +import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; interface IValidationError extends Error { statusCode?: number; computedHash?: string; } +let companySpecificWebhookTasks: WebhookProcessor[] = null; + export abstract class WebhookProcessor { abstract filter(data: any): boolean; abstract run(providers: IProviders, organization: Organization, data: any): Promise; @@ -50,6 +53,14 @@ export default async function ProcessOrganizationWebhook( if (!providers) { throw new Error('No providers provided'); } + const companySpecific = getCompanySpecificDeployment(); + if ( + companySpecific?.features?.firehose?.getAdditionalWebhookTasks && + companySpecificWebhookTasks === null + ) { + companySpecificWebhookTasks = + await companySpecific.features.firehose.getAdditionalWebhookTasks(providers); + } const organization = options.organization; const event = options.event; if (!organization || !organization.name) { @@ -110,7 +121,8 @@ export default async function ProcessOrganizationWebhook( options.acknowledgeValidEvent(); } let interestingEvents = 0; - const work = Tasks.filter((task) => task.filter(event)); + const availableTasks = [...defaultWebhookTasks, ...(companySpecificWebhookTasks || [])]; + const work = availableTasks.filter((task) => task.filter(event)); if (work.length > 0) { ++interestingEvents; console.log(`[* interesting event: ${event.properties.event} (${work.length} interested tasks)]`); diff --git a/webhooks/tasks/auditLog.ts b/business/webhooks/tasks/auditLog.ts similarity index 97% rename from webhooks/tasks/auditLog.ts rename to business/webhooks/tasks/auditLog.ts index c8c7d37e1..8aff9f335 100644 --- a/webhooks/tasks/auditLog.ts +++ b/business/webhooks/tasks/auditLog.ts @@ -9,10 +9,10 @@ // for organizations, and also to import JSON-based audit export files. import { WebhookProcessor } from '../organizationProcessor'; -import { Organization } from '../../business'; +import { Organization } from '../..'; import { AuditLogRecord } from '../../entities/auditLogRecord/auditLogRecord'; import { MapWebhookEventsToAuditEvents, AuditLogSource } from '../../entities/auditLogRecord'; -import type { IProviders } from '../../interfaces'; +import type { IProviders } from '../../../interfaces'; // prettier-ignore const eventTypes = new Set([ @@ -28,6 +28,7 @@ const knownEventTypesToIgnore = new Set([ 'fork', 'watch', 'star', + 'installation_repositories', ]); async function runAsync(providers: IProviders, organization: Organization, data: any) { diff --git a/webhooks/tasks/automaticTeams.ts b/business/webhooks/tasks/automaticTeams.ts similarity index 95% rename from webhooks/tasks/automaticTeams.ts rename to business/webhooks/tasks/automaticTeams.ts index 0f93e3416..76df95476 100644 --- a/webhooks/tasks/automaticTeams.ts +++ b/business/webhooks/tasks/automaticTeams.ts @@ -7,13 +7,13 @@ const teamTypes = ['read', 'write', 'admin']; const defaultLargeAdminTeamSize = 250; import { WebhookProcessor } from '../organizationProcessor'; -import { Operations } from '../../business'; -import { Organization } from '../../business'; +import { Operations } from '../..'; +import { Organization } from '../..'; -import RenderHtmlMail from '../../lib/emailRender'; -import { IMailProvider } from '../../lib/mailProvider'; -import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; -import { GitHubRepositoryPermission, IProviders } from '../../interfaces'; +import RenderHtmlMail from '../../../lib/emailRender'; +import { IMailProvider } from '../../../lib/mailProvider'; +import getCompanySpecificDeployment from '../../../middleware/companySpecificDeployment'; +import { GitHubRepositoryPermission, IProviders } from '../../../interfaces'; interface IAutomaticTeamsMail { to: string; @@ -31,7 +31,7 @@ interface ICustomDataEventName { export default class AutomaticTeamsWebhookProcessor implements WebhookProcessor { processOrgSpecialTeams(organization: Organization) { - const specialTeams = organization.specialRepositoryPermissionTeams; + const specialTeams = organization.specialSystemTeams; const specials = []; const specialTeamIds = new Set(); const specialTeamLevels = new Map(); @@ -362,9 +362,8 @@ async function setTeamPermission( const orgName = organization.name; const repository = organization.repository(repoName, { id: repoId }); if (customizedTeamPermissionsWebhookLogic) { - const shouldSkipEnforcement = await customizedTeamPermissionsWebhookLogic.shouldSkipEnforcement( - repository - ); + const shouldSkipEnforcement = + await customizedTeamPermissionsWebhookLogic.shouldSkipEnforcement(repository); if (shouldSkipEnforcement && necessaryPermission !== GitHubRepositoryPermission.Pull) { console.log( `Customized logic for team permissions: skipping enforcement for repository ${repository.id}` diff --git a/webhooks/tasks/index.ts b/business/webhooks/tasks/index.ts similarity index 100% rename from webhooks/tasks/index.ts rename to business/webhooks/tasks/index.ts diff --git a/webhooks/tasks/member.ts b/business/webhooks/tasks/member.ts similarity index 92% rename from webhooks/tasks/member.ts rename to business/webhooks/tasks/member.ts index 17941bab8..f5c49f79b 100644 --- a/webhooks/tasks/member.ts +++ b/business/webhooks/tasks/member.ts @@ -6,9 +6,9 @@ // COLLABORATOR on a repository import { WebhookProcessor } from '../organizationProcessor'; -import { Operations, Organization } from '../../business'; -import { IProviders, GitHubCollaboratorType } from '../../interfaces'; -import { ErrorHelper } from '../../transitional'; +import { Operations, Organization } from '../..'; +import { IProviders, GitHubCollaboratorType } from '../../../interfaces'; +import { ErrorHelper } from '../../../lib/transitional'; export default class MemberWebhookProcessor implements WebhookProcessor { filter(data: any) { @@ -68,8 +68,7 @@ export default class MemberWebhookProcessor implements WebhookProcessor { const repositoryName = event.repository.name; const repository = organization.repository(repositoryName, event.repository); const collaborator = await repository.getCollaborator(event.member.login); - const permission = collaborator.asGitHubRepositoryPermission(); - // TODO: may need to support the new 5 levels vs 3... + const permission = collaborator.interpretRoleAsDetailedPermission(); if (permission) { const isOrganizationMember = await organization.getMembership(userLogin); const collaboratorType = isOrganizationMember diff --git a/webhooks/tasks/membership.ts b/business/webhooks/tasks/membership.ts similarity index 96% rename from webhooks/tasks/membership.ts rename to business/webhooks/tasks/membership.ts index 730bb3645..6a1dca5a2 100644 --- a/webhooks/tasks/membership.ts +++ b/business/webhooks/tasks/membership.ts @@ -4,8 +4,8 @@ // import { WebhookProcessor } from '../organizationProcessor'; -import { Operations, Organization } from '../../business'; -import { IProviders, GitHubTeamRole } from '../../interfaces'; +import { Operations, Organization } from '../..'; +import { IProviders, GitHubTeamRole } from '../../../interfaces'; export default class MembershipWebhookProcessor implements WebhookProcessor { filter(data: any) { diff --git a/webhooks/tasks/organization.ts b/business/webhooks/tasks/organization.ts similarity index 98% rename from webhooks/tasks/organization.ts rename to business/webhooks/tasks/organization.ts index b2a49039f..03b9e2d4d 100644 --- a/webhooks/tasks/organization.ts +++ b/business/webhooks/tasks/organization.ts @@ -5,13 +5,13 @@ // ORGANIZATION membership and ownership -import { Organization } from '../../business'; +import { Organization } from '../..'; import { OrganizationMembershipRole, type IProviders, NoCacheNoBackground, OrganizationMembershipState, -} from '../../interfaces'; +} from '../../../interfaces'; import { WebhookProcessor } from '../organizationProcessor'; // NOTE: unfortunately role changes from admin->member or member->admin do not fire GitHub hooks diff --git a/webhooks/tasks/repository.ts b/business/webhooks/tasks/repository.ts similarity index 93% rename from webhooks/tasks/repository.ts rename to business/webhooks/tasks/repository.ts index eda134063..76a31f571 100644 --- a/webhooks/tasks/repository.ts +++ b/business/webhooks/tasks/repository.ts @@ -6,9 +6,9 @@ // REPOSITORY created or updated import { WebhookProcessor } from '../organizationProcessor'; -import { Organization } from '../../business'; +import { Organization } from '../..'; import NewRepositoryLockdownSystem from '../../features/newRepositories/newRepositoryLockdown'; -import { getRepositoryMetadataProvider, RepositoryLockdownState, type IProviders } from '../../interfaces'; +import { getRepositoryMetadataProvider, RepositoryLockdownState, type IProviders } from '../../../interfaces'; export default class RepositoryWebhookProcessor implements WebhookProcessor { filter(data: any) { @@ -17,7 +17,7 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { } async run(providers: IProviders, organization: Organization, data: any): Promise { - const { immutable, operations } = providers; + const { immutable, insights, operations } = providers; const event = data.body; const queryCache = operations.providers.queryCache; let update = false; @@ -26,6 +26,9 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { let transferSourceLogin: string = null; const action = event.action; const organizationId = event.organization.id as number; + const repositoryId = event?.repository?.id as number; + const repositoryIdAsString = String(repositoryId); + const organizationIdAsString = String(organizationId); if (!operations.isOrganizationManagedById(organizationId)) { console.log( `skipping organization ID ${organizationId} which is not directly managed: ${event.organization.login}` @@ -57,8 +60,6 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { } by ${event.sender.login}` ); update = true; - const repositoryIdAsString = event.repository.id.toString(); - const organizationIdAsString = event.organization.id.toString(); try { if ( organizationIdAsString === organization.id.toString() && @@ -88,8 +89,6 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { console.log(`repository event not being intercepted: ${action}`); } if (addOrUpdateRepositoryQueryCache) { - const repositoryIdAsString = event.repository.id.toString(); - const organizationIdAsString = event.organization.id.toString(); try { if ( organizationIdAsString === organization.id.toString() && @@ -132,6 +131,7 @@ export default class RepositoryWebhookProcessor implements WebhookProcessor { const repository = organization.repository(event.repository.name, event.repository); const repositoryMetadataProvider = getRepositoryMetadataProvider(organization.operations); const lockdownSystem = new NewRepositoryLockdownSystem({ + insights, operations, organization, repository, diff --git a/webhooks/tasks/team.ts b/business/webhooks/tasks/team.ts similarity index 89% rename from webhooks/tasks/team.ts rename to business/webhooks/tasks/team.ts index 7f9aedcdb..bdbfd249f 100644 --- a/webhooks/tasks/team.ts +++ b/business/webhooks/tasks/team.ts @@ -5,20 +5,15 @@ // TEAM changes -import moment from 'moment'; - import { WebhookProcessor } from '../organizationProcessor'; -import { Operations } from '../../business'; -import { Organization } from '../../business'; -import { permissionsObjectToValue } from '../../transitional'; -import type { IProviders } from '../../interfaces'; +import { Operations } from '../..'; +import { Organization } from '../..'; +import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../../../lib/transitional'; +import type { IProviders } from '../../../interfaces'; // When teams are added or removed on GitHub, refresh the organization's list of // teams as well as the cross-organization view of the teams. -// TODO: connect to query cache -// TODO: consider whether to slowly kick off Redis cache updates, too - export default class TeamWebhookProcessor implements WebhookProcessor { filter(data: any) { const eventType = data.properties.event; @@ -32,7 +27,7 @@ export default class TeamWebhookProcessor implements WebhookProcessor { let refresh = false; let expectedAfterRefresh = false; const teamId = event.team.id; - const teamIdAsString = event.team.id.toString(); + const teamIdAsString = String(teamId); const organizationIdAsString = event.organization.id.toString(); let addOrUpdate = false; if (event.action === 'created') { @@ -64,10 +59,12 @@ export default class TeamWebhookProcessor implements WebhookProcessor { queryCache && queryCache.supportsTeamPermissions ) { - const oldRepositoryPermissionLevel = permissionsObjectToValue( + const oldRepositoryPermissionLevel = projectCollaboratorPermissionsObjectToGitHubRepositoryPermission( event.changes.repository.permissions.from ); - const newRepositoryPermissionLevel = permissionsObjectToValue(event.repository.permissions); + const newRepositoryPermissionLevel = projectCollaboratorPermissionsObjectToGitHubRepositoryPermission( + event.repository.permissions + ); console.log( `team ${event.team.name} permission level for repo ${event.repository.name} changed from ${oldRepositoryPermissionLevel} to ${newRepositoryPermissionLevel}` ); @@ -100,7 +97,7 @@ export default class TeamWebhookProcessor implements WebhookProcessor { isPrivate, repoName, event.team.id.toString(), - permissionsObjectToValue(event.repository.permissions) + projectCollaboratorPermissionsObjectToGitHubRepositoryPermission(event.repository.permissions) ); // equiv to event.team.permission as GitHubRepositoryPermission } } @@ -131,7 +128,6 @@ export default class TeamWebhookProcessor implements WebhookProcessor { } if (refresh) { - const startingRefresh = moment(); // organization.getTeams(immediateRefreshOptions, () => { // console.log('refreshing teams list after add or remove operations'); // const now = moment(); diff --git a/config/brand.types.ts b/config/brand.types.ts index 4c16aa981..62c89a816 100644 --- a/config/brand.types.ts +++ b/config/brand.types.ts @@ -17,5 +17,4 @@ export type ConfigBrand = { operationsMail: string; forkApprovalMail: string; electionMail: string; - infrastructureNotificationsMail: string; }; diff --git a/config/continuousDeployment.types.ts b/config/continuousDeployment.types.ts index 4c7d22560..52602db41 100644 --- a/config/continuousDeployment.types.ts +++ b/config/continuousDeployment.types.ts @@ -8,6 +8,9 @@ export type ConfigRootContinuousDeployment = { }; export type ConfigContinuousDeployment = { + branchName: string; + build: string; + commitId: string; version: string; name: string; }; diff --git a/config/debug.json b/config/debug.json index 56175a688..1f904f311 100644 --- a/config/debug.json +++ b/config/debug.json @@ -2,5 +2,7 @@ "environmentName": "env://ENVIRONMENT_NAME?default=Unknown", "showUsers": "env://SITE_SHOW_USERS?trueIf=show", "showDebugFooter": "env://DEBUG_SHOW_FOOTER?trueIf=1", - "unlinkWithoutDrops": "env://DEBUG_UNLINK_WITHOUT_DROPS?trueIf=1" + "exitImmediately": "env://EXIT_IMMEDIATELY?trueIf=1", + "unlinkWithoutDrops": "env://DEBUG_UNLINK_WITHOUT_DROPS?trueIf=1", + "breakConsoleEveryMinute": "env://DEBUG_MINUTE_BREAKS?trueIf=1" } diff --git a/config/debug.types.ts b/config/debug.types.ts index 4c6c7b2a9..2dc85bd95 100644 --- a/config/debug.types.ts +++ b/config/debug.types.ts @@ -12,4 +12,6 @@ export type ConfigDebug = { showUsers: boolean; showDebugFooter: boolean; unlinkWithoutDrops: boolean; + exitImmediately: boolean; + breakConsoleEveryMinute?: boolean; }; diff --git a/config/github.operations.json b/config/github.operations.json index 73b95dee3..22222b72d 100644 --- a/config/github.operations.json +++ b/config/github.operations.json @@ -1,5 +1,4 @@ { - "centralOperationsToken": "env://GITHUB_CENTRAL_OPERATIONS_TOKEN", "publicAccessToken": "env://GITHUB_PUBLIC_OPERATIONS_TOKEN", "primaryOrganizationId": "env://GITHUB_PRIMARY_ORGANIZATION_ID?type=integer" } diff --git a/config/github.organizations.types.ts b/config/github.organizations.types.ts index b33c37ada..3e0ba49a1 100644 --- a/config/github.organizations.types.ts +++ b/config/github.organizations.types.ts @@ -19,6 +19,7 @@ export type ConfigGitHubOrganization = { teamAllReposRead: string; // | number teamAllReposWrite: string; // | number teamAllReposAdmin: string; + teamOpenAccess: string; teamSudoers: string; templates: string[]; onboarding: boolean; diff --git a/config/npm.publishing.json b/config/npm.publishing.json deleted file mode 100644 index a6b728dac..000000000 --- a/config/npm.publishing.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "former_token": "env://NPM_PUBLISHING_TOKEN", - "token": "", - "notify": "env://NPM_PUBLISHING_NOTIFICATION_EMAIL", - "notifyFrom": "env://NPM_PUBLISHING_NOTIFICATION_FROM" -} diff --git a/config/npm.publishing.types.ts b/config/npm.publishing.types.ts deleted file mode 100644 index 6eccf0230..000000000 --- a/config/npm.publishing.types.ts +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -export type ConfigNpmRootPublishing = { - publishing: ConfigNpmPublishing; -}; - -// NOTE: this config and associated concept is no longer part of this application - -export type ConfigNpmPublishing = { - former_token: string; - token: string; - notify: string; - notifyFrom: string; -}; diff --git a/config/npm.types.ts b/config/npm.types.ts index 1299e552a..e3e943afa 100644 --- a/config/npm.types.ts +++ b/config/npm.types.ts @@ -3,12 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import type { ConfigNpmRootPublishing } from './npm.publishing.types'; - export type ConfigRootNpm = { npm: ConfigNpm; }; -export type ConfigNpm = ConfigNpmRootPublishing & { +export type ConfigNpm = { privateFeedScope: string; }; diff --git a/config/webServer.json b/config/webServer.json index 5ad274329..f5f9bf26f 100644 --- a/config/webServer.json +++ b/config/webServer.json @@ -4,7 +4,18 @@ "appService": { "slot": "env://WEBSITE_SLOT_NAME", "name": "env://WEBSITE_SITE_NAME", - "region": "env://REGION_NAME" + "region": "env://REGION_NAME", + "advanced": { + "resourceGroup": "env://WEBSITE_RESOURCE_GROUP", + "warmup": "env://WEBSITE_WARMUP_PATH", + "swapWarmup": "env://WEBSITE_SWAP_WARMUP_PING_PATH", + "containerName": "env://WEBSITES_WEB_CONTAINER_NAME", + "instanceId": "env://WEBSITE_INSTANCE_ID", + "sku": "env://WEBSITE_SKU", + "hostname": "env://WEBSITE_HOSTNAME", + "alwaysOn": "env://WEBSITE_SCM_ALWAYS_ON_ENABLED", + "slotType": "env://SITE_SLOT_TYPE" + } }, "baseUrl": "env://SITE_BASE_URL", "sslify": { diff --git a/config/webServer.types.ts b/config/webServer.types.ts index b531fe90b..c716230d7 100644 --- a/config/webServer.types.ts +++ b/config/webServer.types.ts @@ -14,6 +14,17 @@ export type ConfigWebServer = { slot: string; name: string; region: string; + advanced?: { + resourceGroup: string; + warmup: string; + swapWarmup: string; + containerName: string; + instanceId: string; + sku: string; + hostname: string; + alwaysOn: string; + slotType: 'production' | 'staging' | undefined; + }; }; baseUrl: string; sslify: { diff --git a/pg.sql b/data/pg.sql similarity index 100% rename from pg.sql rename to data/pg.sql diff --git a/default-assets-package/package-lock.json b/default-assets-package/package-lock.json index 35d2a3b52..1306cdac6 100644 --- a/default-assets-package/package-lock.json +++ b/default-assets-package/package-lock.json @@ -36,23 +36,6 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "optional": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -149,79 +132,18 @@ "node": ">=0.10.0" } }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true, - "optional": true - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "optional": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/async": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true, - "optional": true - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "optional": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true, - "optional": true - }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "optional": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/blockui": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/blockui/-/blockui-1.0.0.tgz", @@ -276,13 +198,6 @@ "d3": "~3.5.0" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true, - "optional": true - }, "node_modules/chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -299,15 +214,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -335,19 +241,6 @@ "node": ">=0.1.90" } }, - "node_modules/combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "dev": true, - "optional": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/components-font-awesome": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/components-font-awesome/-/components-font-awesome-4.2.0.tgz", @@ -359,12 +252,17 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", "dev": true, - "optional": true + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } }, "node_modules/d3": { "version": "3.5.17", @@ -372,19 +270,6 @@ "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=", "dev": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -394,16 +279,6 @@ "node": "*" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -418,17 +293,6 @@ "resolved": "https://registry.npmjs.org/dom/-/dom-0.0.2.tgz", "integrity": "sha1-4V+3WV4ym9Enj8yFjQ97jPOOS1E=" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "optional": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -497,30 +361,6 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "optional": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "optional": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true, - "optional": true - }, "node_modules/file-sync-cmp": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", @@ -613,31 +453,6 @@ "node": ">=0.10.0" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "optional": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "optional": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -659,16 +474,6 @@ "node": ">=10" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -1076,31 +881,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "deprecated": "this library is no longer supported", - "dev": true, - "optional": true, - "dependencies": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1155,22 +935,6 @@ "node": "*" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1303,13 +1067,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true, - "optional": true - }, "node_modules/is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", @@ -1322,6 +1079,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -1346,13 +1109,6 @@ "node": ">=0.10.0" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true, - "optional": true - }, "node_modules/jquery": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz", @@ -1371,50 +1127,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "optional": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "optional": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true, - "optional": true - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "optional": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -1425,27 +1137,27 @@ } }, "node_modules/less": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", - "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz", + "integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==", "dev": true, "dependencies": { - "clone": "^2.1.2" + "copy-anything": "^2.0.1", + "tslib": "^1.10.0" }, "bin": { "lessc": "bin/lessc" }, "engines": { - "node": ">=4" + "node": ">=6" }, "optionalDependencies": { "errno": "^0.1.1", "graceful-fs": "^4.1.2", "image-size": "~0.5.0", + "make-dir": "^2.1.0", "mime": "^1.4.1", - "mkdirp": "^0.5.0", - "promise": "^7.1.1", - "request": "^2.83.0", + "native-request": "^1.0.5", "source-map": "~0.6.0" } }, @@ -1539,6 +1251,20 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -1586,29 +1312,6 @@ "node": ">=4" } }, - "node_modules/mime-db": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", - "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", - "dev": true, - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.22", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", - "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", - "dev": true, - "optional": true, - "dependencies": { - "mime-db": "~1.38.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", @@ -1621,26 +1324,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true, - "optional": true - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "optional": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/multimatch": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", @@ -1656,6 +1339,13 @@ "node": ">=0.10.0" } }, + "node_modules/native-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.0.tgz", + "integrity": "sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw==", + "dev": true, + "optional": true + }, "node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -1668,16 +1358,6 @@ "nopt": "bin/nopt.js" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "optional": true, - "engines": { - "node": "*" - } - }, "node_modules/object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -1853,13 +1533,6 @@ "node": ">=0.10.0" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true, - "optional": true - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1872,6 +1545,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", @@ -1896,16 +1579,6 @@ "node": ">=4" } }, - "node_modules/promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "optional": true, - "dependencies": { - "asap": "~2.0.3" - } - }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -1913,33 +1586,6 @@ "dev": true, "optional": true }, - "node_modules/psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", - "dev": true, - "optional": true - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", @@ -1952,39 +1598,6 @@ "node": ">= 0.10" } }, - "node_modules/request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "optional": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 4" - } - }, "node_modules/resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -2048,19 +1661,22 @@ "rimraf": "bin.js" } }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -2076,32 +1692,6 @@ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "optional": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -2159,46 +1749,11 @@ "node": ">=8.0" } }, - "node_modules/tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "optional": true, - "dependencies": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true, - "optional": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "optional": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/typeahead": { "version": "0.2.2", @@ -2239,33 +1794,12 @@ "node": "*" } }, - "node_modules/uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "optional": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "optional": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", @@ -2278,21 +1812,6 @@ "node": ">= 0.10" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -2327,19 +1846,6 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "optional": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -2411,73 +1917,18 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true, - "optional": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "optional": true - }, "async": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true, - "optional": true - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, "blockui": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/blockui/-/blockui-1.0.0.tgz", @@ -2523,13 +1974,6 @@ "d3": "~3.5.0" } }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true, - "optional": true - }, "chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -2540,12 +1984,6 @@ "supports-color": "^7.1.0" } }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2567,16 +2005,6 @@ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "dev": true, - "optional": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, "components-font-awesome": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/components-font-awesome/-/components-font-awesome-4.2.0.tgz", @@ -2588,12 +2016,14 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", "dev": true, - "optional": true + "requires": { + "is-what": "^3.14.1" + } }, "d3": { "version": "3.5.17", @@ -2601,29 +2031,12 @@ "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "optional": true - }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -2635,17 +2048,6 @@ "resolved": "https://registry.npmjs.org/dom/-/dom-0.0.2.tgz", "integrity": "sha1-4V+3WV4ym9Enj8yFjQ97jPOOS1E=" }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -2695,27 +2097,6 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "optional": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "optional": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true, - "optional": true - }, "file-sync-cmp": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", @@ -2789,25 +2170,6 @@ "for-in": "^1.0.1" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "optional": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2826,16 +2188,6 @@ "integrity": "sha512-tj18lLe+917AACr6BdVoUuHnBPTVd9BEJp1vxnMZ58ztNvuxz9Ufa+wf3g37tlGITH35jggwZ2d9lcgHJJgXfQ==", "dev": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -3150,24 +2502,6 @@ } } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "optional": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "optional": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3207,18 +2541,6 @@ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -3321,13 +2643,6 @@ "is-unc-path": "^1.0.0" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true, - "optional": true - }, "is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", @@ -3337,6 +2652,12 @@ "unc-path-regex": "^0.1.2" } }, + "is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -3355,13 +2676,6 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true, - "optional": true - }, "jquery": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz", @@ -3377,47 +2691,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "optional": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "optional": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true, - "optional": true - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -3425,20 +2698,20 @@ "dev": true }, "less": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", - "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz", + "integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==", "dev": true, "requires": { - "clone": "^2.1.2", + "copy-anything": "^2.0.1", "errno": "^0.1.1", "graceful-fs": "^4.1.2", "image-size": "~0.5.0", + "make-dir": "^2.1.0", "mime": "^1.4.1", - "mkdirp": "^0.5.0", - "promise": "^7.1.1", - "request": "^2.83.0", - "source-map": "~0.6.0" + "native-request": "^1.0.5", + "source-map": "~0.6.0", + "tslib": "^1.10.0" }, "dependencies": { "source-map": { @@ -3516,6 +2789,17 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -3548,23 +2832,6 @@ "dev": true, "optional": true }, - "mime-db": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", - "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", - "dev": true, - "optional": true - }, - "mime-types": { - "version": "2.1.22", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", - "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", - "dev": true, - "optional": true, - "requires": { - "mime-db": "~1.38.0" - } - }, "minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", @@ -3574,23 +2841,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true, - "optional": true - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.6" - } - }, "multimatch": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", @@ -3603,6 +2853,13 @@ "minimatch": "^3.0.0" } }, + "native-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.0.tgz", + "integrity": "sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw==", + "dev": true, + "optional": true + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -3612,13 +2869,6 @@ "abbrev": "1" } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "optional": true - }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -3755,19 +3005,19 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true, - "optional": true - }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true + }, "pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", @@ -3788,16 +3038,6 @@ } } }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "optional": true, - "requires": { - "asap": "~2.0.3" - } - }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -3805,27 +3045,6 @@ "dev": true, "optional": true }, - "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", - "dev": true, - "optional": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "optional": true - }, "rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", @@ -3835,35 +3054,6 @@ "resolve": "^1.9.0" } }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, "resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -3909,19 +3099,19 @@ "glob": "^7.1.3" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -3934,24 +3124,6 @@ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "optional": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -3994,42 +3166,11 @@ "is-number": "^7.0.0" } }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "optional": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true, - "optional": true - } - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "typeahead": { "version": "0.2.2", @@ -4064,29 +3205,12 @@ "util-deprecate": "^1.0.2" } }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "optional": true, - "requires": { - "punycode": "^2.1.0" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true, - "optional": true - }, "v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", @@ -4096,18 +3220,6 @@ "homedir-polyfill": "^1.0.1" } }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/default-assets-package/package.json b/default-assets-package/package.json index 3ec400fe0..7990f1aff 100644 --- a/default-assets-package/package.json +++ b/default-assets-package/package.json @@ -26,7 +26,7 @@ "grunt-contrib-copy": "^1.0.0", "grunt-contrib-less": "^2.0.0", "grunt-exec": "3.0.0", - "jquery": "^3.4.0", + "jquery": "^3.5.1", "load-grunt-tasks": "^4.0.0", "octicons": "4.4.0", "timeago": "1.6.4" diff --git a/docker-compose.yml b/docker-compose.yml index 52c7929cd..a4d057139 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: - portal volumes: - portal_postgres_data:/var/lib/postgresql/data - - ./pg.sql:/docker-entrypoint-initdb.d/pg.sql + - ./data/pg.sql:/docker-entrypoint-initdb.d/pg.sql environment: POSTGRES_DB: portal-repos POSTGRES_USER: portal diff --git a/docs/api.md b/docs/api.md index 261e6b6aa..b912d44a9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -147,7 +147,7 @@ This API will retrieve information about a specific user. The first API version Where `login` is a GitHub username, case insensitive. -##### Response +##### Response: by GitHub username If a link is not found for the GitHub user @@ -188,7 +188,7 @@ This API returns an array if there is at least one matching account or accounts. Where `id` is an AAD ID. -##### Response +##### Response: by AAD ID If a link is not registered for this user @@ -233,7 +233,7 @@ Required API scope: `link` > POST /api/people/links -#### Request +#### Request: create a link ```text BODY @@ -249,7 +249,7 @@ BODY > If the account is a Service Account, the `corporate` object should also include a field called `serviceAccountMail` that points to a contact for the service account. -#### Response +#### Response: create a link ```http Status: 201 OK @@ -261,7 +261,7 @@ Status: 201 OK ### Create a repo -> This API requires that your API key be authorized for the `createRepo` scope +> This API requires that your API key be authorized for the `repo/create` scope This example uses a pure POST request plus headers for authorization: diff --git a/docs/configuration.md b/docs/configuration.md index 53cd38b68..a2ce8965a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -85,7 +85,7 @@ Here is a short overview about the meanings of the different parameters: - **setupbycorporateusername** (string) - Username (from the corporate identity system) of the user who set up the organization - **setupbycorporateid** (string) - Unique identifier (from the corporate identity system) for the user who set up the organization - **setupbycorporatedisplayname** (string) - Display name (from the corporate identity system) for the user who set up the organization -- **specialteams** (object{specialTeam: string, teamId: integer}) - Special team configuration for the organization supported values for `specialTeam` types are: `everyone, sudo, globalSudo, systemWrite, systemRead, systemAdmin`. The `teamId` is the GitHub team ID for the special team. +- **specialteams** (object{specialTeam: string, teamId: integer}) - Special team configuration for the organization supported values for `specialTeam` types are: `everyone, sudo, globalSudo, systemWrite, systemRead, systemAdmin, openAccess`. The `teamId` is the GitHub team ID for the special team. ### Static settings @@ -125,13 +125,13 @@ The opensource-portal can also be configured to read organization configurations ## PostgreSQL Configuration -To run the opensource-portal with a postgres database, you need to [setup postgres](https://www.postgresql.org/docs/11/runtime.html) and initialize the database by running the `pg.sql`-file in the psql-terminal. +To run the opensource-portal with a postgres database, you need to [setup postgres](https://www.postgresql.org/docs/11/runtime.html) and initialize the database by running the `data/pg.sql`-file in the psql-terminal. It's recommended to [run postgres in a docker container](https://hub.docker.com/_/postgres), there is also an official docker image called `postgres` for building. Once the setup is done, set the `host`, `database`, `user`, `password`, `ssl` (as boolean) and `port` of the postgres in the `config/data.postgres.json`-file. -Additionally set the name of the linking-table (`tableName` parameter), if the tables were created with the `pg.sql`-file, the name for this table is `links`. +Additionally set the name of the linking-table (`tableName` parameter), if the tables were created with the `data/pg.sql`-file, the name for this table is `links`. -There is also a script in the `scripts` folder that can blast the `pg.sql` insertions into a new database. Be +There is also a script in the `scripts` folder that can blast the `data/pg.sql` insertions into a new database. Be sure to configure grants and your user accounts with the concept of least privilege required. ## Cache Configuration diff --git a/docs/jobs.md b/docs/jobs.md deleted file mode 100644 index 56173c8fc..000000000 --- a/docs/jobs.md +++ /dev/null @@ -1,20 +0,0 @@ -# Jobs - -There are automated cronjobs available to help keep things running smoothly, -if you choose to use them. - -Jobs are an alternate entrypoint into the application, and have full use of -the same set of [providers](./providers.md). - -## list of cronjobs - -Several jobs are available in the container or the `jobs/` folder. These can -optionally provide useful operational and services support. Often a Kubernetes -CronJob can help. - -- `cleanupInvites`: if configured for an org, cleanup old unaccepted invites -- `firehose`: ongoing processing of GitHub events for keeping cache up-to-date -- `managers`: cache the last-known manager for links, to use in notifications after a departure may remove someone from the graph -- `permissions`: updating permissions for all-write/all-read/all-admin teams when configured -- `refreshUsernames`: keeping link data fresh with GitHub username renames, corporate username and display name updates, and removing links for deleted GitHub users who remove their accounts permanently from GitHub.com -- `reports`: processing the building of report data about use, abandoned repos, etc. **this job is broken** diff --git a/docs/scripts.md b/docs/scripts.md deleted file mode 100644 index 25064f56b..000000000 --- a/docs/scripts.md +++ /dev/null @@ -1,5 +0,0 @@ -# Scripts - -> this file is incomplete - -- `migrateLinks`: a one-time migration script to help when moving link source of truth diff --git a/docs/service-dependencies.md b/docs/service-dependencies.md new file mode 100644 index 000000000..69269e5ce --- /dev/null +++ b/docs/service-dependencies.md @@ -0,0 +1,26 @@ +# Service dependencies + +_This content was moved from the `README.md` to reduce clutter. More content would be helpful._ + +- GitHub organization(s) +- Hosting environment +- Background job environment for eventual consistency work and maintenance cronjobs +- Daemon hosting for near-real-time process +- Queue system +- A cache system or multi-tiered cache implementation +- Azure Active Directory and the Microsoft Graph +- An email service to send mail +- Optional insights or telemetry system + +## Source of truth store + +The backend maintains in a data store of your choice key metadata for +repositories, links, and general compliance info. The backend supports +natively Azure Storage, Azure Table, Azure CosmosDB, and Postgres. + +We use **Postgres** for source of truth including: + +- GitHub organization configuration +- corporate GitHub repository metadata +- corporate identity-to-GitHub login links +- compliance metadata (enable/disabled repos) diff --git a/features/graphTeamSync.ts b/features/graphTeamSync.ts deleted file mode 100644 index e1c8c4777..000000000 --- a/features/graphTeamSync.ts +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import { Team } from '../business'; -import { IProviders } from '../interfaces'; - -export class GraphTeamSync { - #team: Team; - #providers: IProviders; - - constructor(providers: IProviders, team: Team) { - this.#providers = providers; - this.#team = team; - } - - // On the GitHub side, they define: - // - The team must not have any sub-teams (must be a leaf node) - // - Can have up to 5 directory groups assigned to the team - // - Team Maintainers are not touched (TBD need to confirm) - // - If you suspend sync, it removes all the members - - // Unknowns: - // - What happens if the sole maint leaves... guess it just becomes an orphan team - // - How to handle removed directory groups - // - How much to store, log, show in the UI, or notify people about - - // Value-adds: - // - When a user links for the first time, kick off a job to evaluate the directory groups they're in -} diff --git a/index.ts b/index.ts new file mode 100644 index 000000000..b90109b36 --- /dev/null +++ b/index.ts @@ -0,0 +1,97 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import express from 'express'; +import Debug from 'debug'; + +import type { ExecutionEnvironment, IReposApplication, SiteConfiguration } from './interfaces'; +import configResolver from './lib/config'; +import initialize from './middleware/initialize'; + +export * from './interfaces'; + +type InitializeCall = ( + executionEnvironment: ExecutionEnvironment, + config: SiteConfiguration, + configurationError: Error +) => Promise; + +export function createExpressApplication(): IReposApplication { + Debug.debug('startup')('starting web framework...'); + const app = express() as any as IReposApplication; + + app.initializeApplication = initializeApp.bind(undefined, app, express, __dirname); + app.startupApplication = commonStartup.bind( + undefined, + app.initializeApplication, + false /* not a job */, + true /* enable all apps */, + app + ); + + return app; +} + +function initializeApp( + app: IReposApplication, + express: any, + dirname: string, + executionEnvironment: ExecutionEnvironment, + config: SiteConfiguration, + configurationError: Error +) { + return initialize(executionEnvironment, app, express, dirname, config, configurationError); +} + +export async function commonStartup( + call: InitializeCall, + isJob: boolean, + enableAllGitHubApps: boolean, + app?: IReposApplication, + entrypointName?: string +) { + const executionEnvironment: ExecutionEnvironment = { + isJob, + enableAllGitHubApps, + entrypointName, + // + expressApplication: app, + // + providers: undefined, + skipModules: new Set(), + // + started: new Date(), + }; + + let painlessConfigResolver = null; + try { + painlessConfigResolver = configResolver(); + } catch (error) { + console.warn('Painless config resolver initialization error:'); + console.error(error); + throw error; + } + let config: any = null; + let configurationError: Error = null; + try { + config = await painlessConfigResolver.resolve(); + } catch (error) { + configurationError = error; + } + if (isJob) { + executionEnvironment.skipModules.add('web'); + } + try { + await call(executionEnvironment, config, configurationError); + } catch (startupError) { + console.error(`Startup error: ${startupError}`); + if (startupError.stack) { + console.error(startupError.stack); + } + process.exit(1); + } + + return executionEnvironment; +} diff --git a/interfaces/app.ts b/interfaces/app.ts index 7520ed409..ba5d2f2d0 100644 --- a/interfaces/app.ts +++ b/interfaces/app.ts @@ -3,14 +3,21 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Application } from 'express'; -import { IProviders } from './providers'; +import { Application, Response, NextFunction } from 'express'; -import type { RuntimeConfiguration } from './config'; +import type { IProviders } from './providers'; +import type { RuntimeConfiguration, SiteConfiguration } from './config'; +import type { ReposAppRequest } from './web'; -export interface IApplicationProfile { +export type ApplicationProfile = { applicationName: string; - customErrorHandlerRender?: (errorView: any, err: Error, req: any, res: any, next: any) => Promise; + customErrorHandlerRender?: ( + errorView: unknown, + err: Error, + req: ReposAppRequest, + res: Response, + next: NextFunction + ) => Promise; customRoutes?: () => Promise; logDependencies: boolean; serveClientAssets: boolean; @@ -19,7 +26,7 @@ export interface IApplicationProfile { startup?: (providers: IProviders) => Promise; sessions: boolean; webServer: boolean; -} +}; export interface IReposApplication extends Application { // Standard Express @@ -27,29 +34,50 @@ export interface IReposApplication extends Application { // Local things providers: IProviders; - config: any; + config: SiteConfiguration; isBackgroundJob: boolean; enableAllGitHubApps: boolean; runtimeConfiguration: RuntimeConfiguration; + executionEnvironment: ExecutionEnvironment; + startServer: () => Promise; - initializeApplication: (config: any, configurationError: Error) => Promise; - initializeJob: (config: any, configurationError: Error) => Promise; + initializeApplication: ( + executionEnvironment: ExecutionEnvironment, + config: SiteConfiguration, + configurationError: Error + ) => Promise; + startupApplication: () => Promise; - startupJob: () => Promise; runJob: ( job: (job: IReposJob) => Promise, options?: IReposJobOptions - ) => Promise; + ) => Promise; } +export type ExecutionEnvironment = { + isJob: boolean; + enableAllGitHubApps: boolean; + + expressApplication: IReposApplication | null; + + providers: IProviders; + skipModules: Set; + + entrypointName: string; + + started: Date; +}; + export interface IReposJob { app: IReposApplication; started: Date; providers: IProviders; parameters: any; args: string[]; + + executionEnvironment: ExecutionEnvironment; } export interface IReposJobResult { @@ -62,4 +90,5 @@ export interface IReposJobOptions { insightsPrefix?: string; parameters?: any; enableAllGitHubApps?: boolean; + name?: string; } diff --git a/interfaces/companySpecific/administration.ts b/interfaces/companySpecific/administration.ts index 9d138e664..d404b5275 100644 --- a/interfaces/companySpecific/administration.ts +++ b/interfaces/companySpecific/administration.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import { IDictionary } from '../../interfaces'; diff --git a/interfaces/companySpecific/events/index.ts b/interfaces/companySpecific/events/index.ts new file mode 100644 index 000000000..016caa017 --- /dev/null +++ b/interfaces/companySpecific/events/index.ts @@ -0,0 +1,12 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import type { ICompanySpecificEventsLinking } from './linking'; + +export * from './linking'; + +export interface ICompanySpecificEvents { + linking?: ICompanySpecificEventsLinking; +} diff --git a/interfaces/companySpecific/events/linking.ts b/interfaces/companySpecific/events/linking.ts new file mode 100644 index 000000000..6f6a55f99 --- /dev/null +++ b/interfaces/companySpecific/events/linking.ts @@ -0,0 +1,11 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import type { ICorporateLink, IProviders } from '../..'; + +export interface ICompanySpecificEventsLinking { + onLink?: (providers: IProviders, link: ICorporateLink) => Promise; + onUnlink?: (providers: IProviders, corporateId: string) => Promise; +} diff --git a/interfaces/companySpecific/features/augmentApiMetadata.ts b/interfaces/companySpecific/features/augmentApiMetadata.ts index 9dab4d716..9dc19e10c 100644 --- a/interfaces/companySpecific/features/augmentApiMetadata.ts +++ b/interfaces/companySpecific/features/augmentApiMetadata.ts @@ -3,13 +3,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Organization } from '../../../business'; -import { IProviders } from '../../../interfaces'; +import { Organization, Team } from '../../../business'; +import type { IProviders, TeamJsonFormat } from '../../../interfaces'; export interface ICompanySpecificAugmentApiMetadata { - augmentOrganizationClientJson: ( + augmentOrganizationClientJson?: ( providers: IProviders, organization: Organization, - standardJsonMetadata: any - ) => any; + standardJsonMetadata: object + ) => object; + + augmentTeamClientJson?: ( + providers: IProviders, + team: Team, + standardJsonMetadata: object, + jsonFormat: TeamJsonFormat + ) => Promise; } diff --git a/interfaces/companySpecific/features/firehose.ts b/interfaces/companySpecific/features/firehose.ts index 90c3213f0..63656249c 100644 --- a/interfaces/companySpecific/features/firehose.ts +++ b/interfaces/companySpecific/features/firehose.ts @@ -4,9 +4,10 @@ // import { IGitHubAppInstallation, IGitHubWebhookEnterprise, IProviders } from '../../../interfaces'; +import type { WebhookProcessor } from '../../../business/webhooks/organizationProcessor'; export interface ICompanySpecificFeatureFirehose { - processWebhook: ( + processWebhook?: ( providers: IProviders, body: any, eventType: string, @@ -14,4 +15,6 @@ export interface ICompanySpecificFeatureFirehose { installation: IGitHubAppInstallation, acknowledgeEvent: () => void ) => Promise; + + getAdditionalWebhookTasks?: (providers: IProviders) => Promise; } diff --git a/interfaces/companySpecific/features/index.ts b/interfaces/companySpecific/features/index.ts index 2c821d92b..1a3ca4f66 100644 --- a/interfaces/companySpecific/features/index.ts +++ b/interfaces/companySpecific/features/index.ts @@ -3,14 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { ICompanySpecificAugmentApiMetadata } from './augmentApiMetadata'; -import { ICompanySpecificFeatureDemo } from './demo'; -import { ICompanySpecificFeatureFirehose } from './firehose'; -import { ICompanySpecificFeatureMailProvider } from './mailProvider'; -import { ICompanySpecificFeatureOrganizationJoinAcl } from './organizationJoinAcl'; -import { ICompanySpecificFeatureOrganizationSudo } from './organizationSudo'; -import { ICompanySpecificFeaturePortalSudo } from './portalSudo'; -import { ICompanySpecificFeatureRepositoryState } from './repositoryActions'; +import type { ICompanySpecificAugmentApiMetadata } from './augmentApiMetadata'; +import type { ICompanySpecificFeatureDemo } from './demo'; +import type { ICompanySpecificFeatureFirehose } from './firehose'; +import type { ICompanySpecificFeatureMailProvider } from './mailProvider'; +import type { ICompanySpecificFeatureOrganizationJoinAcl } from './organizationJoinAcl'; +import type { ICompanySpecificFeatureOrganizationSudo } from './organizationSudo'; +import type { ICompanySpecificFeaturePortalSudo } from './portalSudo'; +import type { ICompanySpecificFeatureRepositoryState } from './repositoryActions'; export * from './organizationSudo'; export * from './portalSudo'; @@ -22,7 +22,7 @@ export * from './organizationJoinAcl'; export * from './augmentApiMetadata'; export interface ICompanySpecificFeatures { - augmentApiMetadata: ICompanySpecificAugmentApiMetadata; + augmentApiMetadata?: ICompanySpecificAugmentApiMetadata; organizationSudo?: ICompanySpecificFeatureOrganizationSudo; organizationJoinAcl?: ICompanySpecificFeatureOrganizationJoinAcl; portalSudo?: ICompanySpecificFeaturePortalSudo; diff --git a/interfaces/companySpecific/features/organizationSudo.ts b/interfaces/companySpecific/features/organizationSudo.ts index c7c25bc29..292df91e6 100644 --- a/interfaces/companySpecific/features/organizationSudo.ts +++ b/interfaces/companySpecific/features/organizationSudo.ts @@ -4,7 +4,7 @@ // import { Organization } from '../../../business'; -import { IOrganizationSudo } from '../../../features'; +import { IOrganizationSudo } from '../../../business/features'; import { IProviders } from '../../../interfaces'; export interface ICompanySpecificFeatureOrganizationSudo { diff --git a/interfaces/companySpecific/features/portalSudo.ts b/interfaces/companySpecific/features/portalSudo.ts index 71f6c25ad..07a704eb7 100644 --- a/interfaces/companySpecific/features/portalSudo.ts +++ b/interfaces/companySpecific/features/portalSudo.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IPortalSudo } from '../../../features'; +import { IPortalSudo } from '../../../business/features'; import { IProviders } from '../../../interfaces'; export interface ICompanySpecificFeaturePortalSudo { diff --git a/interfaces/companySpecific/index.ts b/interfaces/companySpecific/index.ts index 3bf21513e..fb311f15b 100644 --- a/interfaces/companySpecific/index.ts +++ b/interfaces/companySpecific/index.ts @@ -11,3 +11,4 @@ export * from './administration'; export * from './passport'; export * from './views'; export * from './urls'; +export * from './events'; diff --git a/interfaces/companySpecific/middleware.ts b/interfaces/companySpecific/middleware.ts index ceb754970..f7c9e5e50 100644 --- a/interfaces/companySpecific/middleware.ts +++ b/interfaces/companySpecific/middleware.ts @@ -9,6 +9,7 @@ import { IProviders, ReposAppRequest } from '../../interfaces'; import { IndividualContext } from '../../business/user'; import { IRequestTeamPermissions } from '../../middleware/github/teamPermissions'; import type { ApiClientGroupDisplay } from '../api'; +import { ITeamJoinRequestSubmitOutcome } from '../../routes/org/team'; export interface ICompanySpecificRepoPermissionsMiddlewareCalls { afterPermissionsInitialized?: ( @@ -36,6 +37,11 @@ export interface ICompanySpecificTeamPermissionsMiddlewareCalls { activeContext: IndividualContext, team: Team ) => Promise; + beforeJoinRequest?: ( + providers: IProviders, + activeContext: IndividualContext, + team: Team + ) => Promise; } export interface ICompanySpecificAuthenticationCalls { @@ -46,8 +52,8 @@ export interface ICompanySpecificAuthenticationCalls { export interface IAadAuthenticationValidator { isAuthorizedTenant(tenantId: string): Promise; getAudienceIdentities(): Promise; - getAuthorizedClientIdToken(clientId: string): Promise; - getAuthorizedObjectIdToken(objectId: string): Promise; + getAuthorizedClientIdToken(clientId: string): Promise; + getAuthorizedObjectIdToken(objectId: string): Promise; getScopes(tokenRepresentation: any): Promise; getDisplayValues(tokenRepresentation: any): Promise; } diff --git a/interfaces/companySpecific/passport.ts b/interfaces/companySpecific/passport.ts index 389e08065..478aa6c60 100644 --- a/interfaces/companySpecific/passport.ts +++ b/interfaces/companySpecific/passport.ts @@ -4,7 +4,7 @@ // import { PassportStatic } from 'passport'; -import { IAuthenticationHelperMethods } from '../../middleware/passport-routes'; +import type { IAuthenticationHelperMethods } from '../../middleware/passport-routes'; export interface ICompanySpecificPassportMiddleware { configure?: (app: any, config: any, passport: PassportStatic) => void; diff --git a/interfaces/companySpecific/routes/api/index.ts b/interfaces/companySpecific/routes/api/index.ts index a8c324252..0f5a5fae1 100644 --- a/interfaces/companySpecific/routes/api/index.ts +++ b/interfaces/companySpecific/routes/api/index.ts @@ -22,6 +22,7 @@ export interface IAttachCompanySpecificRoutesApiContextual { export interface IAttachCompanySpecificRoutesApiContextualOrganization { index?: ConnectRouter; repo?: ConnectRouter; + team?: ConnectRouter; } export interface IAttachCompanySpecificRoutesApiContextualAdministration { diff --git a/interfaces/companySpecific/routes/index.ts b/interfaces/companySpecific/routes/index.ts index 9e4560744..ddb835ff4 100644 --- a/interfaces/companySpecific/routes/index.ts +++ b/interfaces/companySpecific/routes/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import { IAttachCompanySpecificRoutesApi } from './api'; export * from './api'; diff --git a/interfaces/github/account.ts b/interfaces/github/account.ts index c57efafa5..f4bf943e3 100644 --- a/interfaces/github/account.ts +++ b/interfaces/github/account.ts @@ -5,6 +5,7 @@ export enum AccountJsonFormat { GitHub = 'github', + GitHubExtended = 'github+extended', UplevelWithLink = 'github+link', GitHubDetailedWithLink = 'detailed+link', } diff --git a/interfaces/github/collaborators.ts b/interfaces/github/collaborators.ts index 7e9fcf2c7..5ab70be9c 100644 --- a/interfaces/github/collaborators.ts +++ b/interfaces/github/collaborators.ts @@ -5,7 +5,8 @@ export interface IGitHubCollaboratorPermissions { admin: boolean; - pull: boolean; + maintain: boolean; push: boolean; - // triage and maintain do not appear today by the GitHub API (sigh), it's in V4 GraphQL but not in V3 REST + triage: boolean; + pull: boolean; } diff --git a/interfaces/github/operations.ts b/interfaces/github/operations.ts index e2998f3c6..4ac9c3ee8 100644 --- a/interfaces/github/operations.ts +++ b/interfaces/github/operations.ts @@ -3,9 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { CoreCapability, ICacheDefaultTimes, IPurposefulGetAuthorizationHeader, ICacheOptions } from '.'; +import { + CoreCapability, + ICacheDefaultTimes, + PurposefulGetAuthorizationHeader, + ICacheOptions, + GetAuthorizationHeader, +} from '.'; import { IProviders, ICorporateLink, ICachedEmployeeInformation } from '..'; -import { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; +import { IRepositoryMetadataProvider } from '../../business/entities/repositoryMetadata/repositoryMetadataProvider'; import { RestLibrary } from '../../lib/github'; import { Account } from '../../business'; @@ -26,18 +32,34 @@ export interface IOperationsProviders { providers: IProviders; } +export type LinkEvent = ICorporateLink & { + linkId: string; + correlationId: string; +}; + +export type UnlinkEvent = { + github: { + id: number; + login: string; + }; + aad: { + preferredName: string; + userPrincipalName: string; + id: string; + }; +}; + export interface IOperationsLinks { getLinks(options?: any): Promise; getLinkByThirdPartyId(thirdPartyId: string): Promise; getLinkByThirdPartyUsername(username: string): Promise; tryGetLink(login: string): Promise; - fireLinkEvent(value): Promise; - fireUnlinkEvent(value): Promise; + fireLinkEvent(value: LinkEvent): Promise; + fireUnlinkEvent(value: UnlinkEvent): Promise; } export interface IOperationsNotifications { getOperationsMailAddress(): string; - getInfrastructureNotificationsMail(): string; getLinksNotificationMailAddress(): string; getRepositoriesNotificationMailAddress(): string; } @@ -79,8 +101,9 @@ export interface IOperationsLockdownFeatureFlags { } export interface IOperationsCentralOperationsToken { - getCentralOperationsToken(): IPurposefulGetAuthorizationHeader; // IGetAuthorizationHeader ?; getAccountByUsername(username: string, options?: ICacheOptions): Promise; + getPublicReadOnlyStaticToken(): GetAuthorizationHeader; + getPublicAuthorizationToken(): GetAuthorizationHeader; } export function operationsIsCapable( diff --git a/interfaces/github/orgs.ts b/interfaces/github/orgs.ts index 52092fda5..b815b973e 100644 --- a/interfaces/github/orgs.ts +++ b/interfaces/github/orgs.ts @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { ICacheOptions, IPagedCacheOptions } from '.'; -import { ICorporateLink } from '..'; +import type { ICacheOptions, IPagedCacheOptions } from '.'; +import type { ICorporateLink } from '..'; import { OrganizationMember } from '../../business'; import { Repository } from '../../business/repository'; @@ -97,3 +97,24 @@ export interface IOrganizationMembership { organization: any; user: any; } + +export type GitHubSimpleAccount = { + login: string; + avatar_url: string; + id: number; +}; + +export type GitHubOrganizationInvite = { + created_at: string; + email: string; + failed_at: string; + failed_reason: string; + id: number; + invitation_source: string; // 'member' + invitation_teams_url: string; + inviter: GitHubSimpleAccount; + login: string; + node_id: string; + role: string; // 'direct_member' + team_count: number; +}; diff --git a/interfaces/github/repos.ts b/interfaces/github/repos.ts index 976f42b00..828af3ba5 100644 --- a/interfaces/github/repos.ts +++ b/interfaces/github/repos.ts @@ -4,18 +4,20 @@ // import type { ICacheOptions, IPagedCacheOptions, IAccountBasics, IGitHubTeamBasics } from '.'; +import type { IGitHubWebhookEnterprise } from './apps'; import { IPersonalizedUserAggregateRepositoryPermission, TeamRepositoryPermission, GraphManager, } from '../../business'; -import type { IRepositoryMetadataProvider } from '../../entities/repositoryMetadata/repositoryMetadataProvider'; +import type { IRepositoryMetadataProvider } from '../../business/entities/repositoryMetadata/repositoryMetadataProvider'; import { GitHubPullRequestState, GitHubPullRequestSort, GitHubSortDirection, } from '../../lib/github/collections'; import type { IRequestTeamPermissions } from '../../middleware/github/teamPermissions'; +import { CreateError } from '../../lib/transitional'; export enum GitHubRepositoryPermission { Pull = 'pull', @@ -174,7 +176,49 @@ export interface IGitHubBranchDetailed { }; } -export interface IRepositoryBranchAccessProtections { +export type RepositoryBranchAccessProtections = { + required_signatures: { + enabled: boolean; + }; + allow_fork_syncing: { + enabled: boolean; + }; + lock_branch: { + enabled: boolean; + }; + required_conversation_resolution: { + enabled: boolean; + }; + block_creations: { + enabled: boolean; + }; + required_pull_request_reviews: { + dismissal_restrictions: + | { + users: IAccountBasics[]; + teams: IGitHubTeamBasics[]; + apps: IGitHubWebhookEnterprise[]; + } + | Record; + dismiss_stale_reviews: boolean; + require_code_owner_reviews: boolean; + required_approving_review_count: number; + require_last_push_approval: boolean; + bypass_pull_request_allowances: { + users: IAccountBasics[]; + teams: IGitHubTeamBasics[]; + apps: IGitHubWebhookEnterprise[]; + }; + } | null; + required_status_checks: { + strict: boolean; + contexts: string[]; + checks: { + context: string; + app_id: number; + }[]; + } | null; + branch?: string; allow_deletions: { enabled: boolean; }; @@ -194,7 +238,7 @@ export interface IRepositoryBranchAccessProtections { apps: unknown[]; }; url: string; -} +}; export interface ITemporaryCommandOutput { error?: Error; @@ -219,7 +263,9 @@ export interface IRepositorySearchOptions { export enum GitHubCollaboratorPermissionLevel { Admin = 'admin', + Maintain = 'maintain', Write = 'write', + Triage = 'triage', Read = 'read', None = 'none', } @@ -232,13 +278,119 @@ export function ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermis return null; case GitHubCollaboratorPermissionLevel.Admin: return GitHubRepositoryPermission.Admin; + case GitHubCollaboratorPermissionLevel.Maintain: + return GitHubRepositoryPermission.Maintain; case GitHubCollaboratorPermissionLevel.Write: return GitHubRepositoryPermission.Push; + case GitHubCollaboratorPermissionLevel.Triage: + return GitHubRepositoryPermission.Triage; case GitHubCollaboratorPermissionLevel.Read: return GitHubRepositoryPermission.Pull; default: - throw new Error( - `ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermission unrecognized value ${level} cannot be translated` + throw CreateError.InvalidParameters( + `Unrecognized GitHub permission value ${level}, current value cannot be translated (ConvertGitHubCollaboratorPermissionLevelToGitHubRepositoryPermission)` ); } } + +export enum GitHubAdvancedSecurityFeatureState { + Enabled = 'enabled', + Disabled = 'disabled', +} + +export type GitHubAdvancedSecurityFeatureStatusValue = { + status: GitHubAdvancedSecurityFeatureState; +}; + +export type GitHubSecurityAnalysisFeatures = { + advanced_security: GitHubAdvancedSecurityFeatureStatusValue; + secret_scanning: GitHubAdvancedSecurityFeatureStatusValue; + secret_scanning_push_protection: GitHubAdvancedSecurityFeatureStatusValue; + dependabot_security_updates: GitHubAdvancedSecurityFeatureStatusValue; + secret_scanning_validity_checks: GitHubAdvancedSecurityFeatureStatusValue; +}; + +export enum GitHubRepositoryOwnerType { + Organization = 'Organization', + User = 'User', +} + +export type GitHubRepositoryOwner = { + login: string; + id: number; + node_id: string; + avatar_url: string; + url: string; + type: GitHubRepositoryOwnerType; +}; + +export type GitHubRepositoryLicense = { + key: string; + name: string; + spdx_id: string; + url: string; + node_id: string; +}; + +export type GitHubRepositoryDetails = { + id: number; + node_id: string; + name: string; + full_name: string; + private: boolean; + owner: GitHubRepositoryOwner; + html_url: string; + description: string; + fork: boolean; + url: string; + created_at: string; + updated_at: string; + pushed_at: string; + git_url: string; + ssh_url: string; + clone_url: string; + homepage: string | null; + size: number; + stargazers_count: number; + watchers_count: number; + language: string; + has_issues: boolean; + has_projects: boolean; + has_downloads: boolean; + has_wiki: boolean; + has_pages: boolean; + has_discussions: boolean; + forks_count: number; + archived: boolean; + disabled: boolean; + open_issues_count: number; + license?: GitHubRepositoryLicense; + allow_forking: boolean; + is_template: boolean; + web_commit_signoff_required: boolean; + topics: string[]; + visibility?: GitHubRepositoryVisibility; + forks: number; + open_issues: number; + watchers: number; + default_branch: string; + // permissions: admin / maintain / push / triage / pull + // temp_clone_token: ... + allow_squash_merge: boolean; + allow_merge_commit: boolean; + allow_rebase_merge: boolean; + allow_auto_merge: boolean; + delete_branch_on_merge: boolean; + allow_update_branch: boolean; + use_squash_pr_title_as_default: boolean; + squash_merge_commit_message: string; + squash_merge_commit_title: string; + merge_commit_message: string; + merge_commit_title: string; + template_repository: GitHubRepositoryDetails; + organization?: GitHubRepositoryOwner; + security_and_analysis?: GitHubSecurityAnalysisFeatures; + network_count: number; + subscribers_count: number; + parent?: GitHubRepositoryDetails; +}; diff --git a/interfaces/github/rest.ts b/interfaces/github/rest.ts index c8ed62096..9d43fc236 100644 --- a/interfaces/github/rest.ts +++ b/interfaces/github/rest.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { AppPurposeTypes } from '../../business/githubApps'; +import { AppPurposeTypes } from '../../lib/github/appPurposes'; export interface ICacheOptions { backgroundRefresh?: any | null | undefined; @@ -14,25 +14,29 @@ export interface ICacheOptionsWithPurpose extends ICacheOptions { purpose?: AppPurposeTypes; } +export type WithOptionalPurpose = { + purpose?: AppPurposeTypes; +}; + export interface IPagedCacheOptions extends ICacheOptions { pageRequestDelay?: number | null | undefined; // FUTURE: could be a function, too } -export interface IPurposefulGetAuthorizationHeader { - (purpose: AppPurposeTypes): Promise; -} +export type PagedCacheOptionsWithPurpose = IPagedCacheOptions & WithOptionalPurpose; -export interface IGetAuthorizationHeader { - (): Promise; -} +export type PurposefulGetAuthorizationHeader = ( + purpose: AppPurposeTypes +) => Promise; + +export type GetAuthorizationHeader = () => Promise; -export interface IAuthorizationHeaderValue { +export type AuthorizationHeaderValue = { value: string; purpose: AppPurposeTypes; source?: string; installationId?: number; organizationName?: string; -} +}; export interface ICacheDefaultTimes { orgReposStaleSeconds: number; @@ -58,6 +62,7 @@ export interface ICacheDefaultTimes { teamDetailStaleSeconds: number; orgRepoWebhooksStaleSeconds: number; teamRepositoryPermissionStaleSeconds: number; + defaultStaleSeconds: number; } // These "core capabilities" were created when the GitHub operations diff --git a/interfaces/github/teams.ts b/interfaces/github/teams.ts index 110ddb0f7..e6d8a417a 100644 --- a/interfaces/github/teams.ts +++ b/interfaces/github/teams.ts @@ -22,6 +22,29 @@ export interface IGitHubTeamBasics { slug: string; } +export enum GitHubTeamNotificationSetting { + Enabled = 'notification_enabled', + Disabled = 'notification_disabled', +} + +export type GitHubTeamDetails = IGitHubTeamBasics & { + node_id: string; + description: string; + privacy: GitHubTeamPrivacy; + notification_setting: GitHubTeamNotificationSetting; + url: string; + html_url: string; + members_url: string; + repositories_url: string; + // permission: ... + created_at: string; + updated_at: string; + members_count: number; + repos_count: number; + // organization: ... + parent: IGitHubTeamBasics; +}; + export enum GitHubRepositoryType { Sources = 'sources', } diff --git a/interfaces/index.ts b/interfaces/index.ts index 079d0b3d7..4d0713adc 100644 --- a/interfaces/index.ts +++ b/interfaces/index.ts @@ -16,22 +16,26 @@ export * from './providers'; export * from './web'; export * from './config'; -import { +import type { ExecutionEnvironment } from './app'; +import type { IAttachCompanySpecificRoutes, IAttachCompanySpecificMiddleware, ICorporationAdministrationSection, IAttachCompanySpecificStrings, ICompanySpecificFeatures, + ICompanySpecificEvents, IAttachCompanySpecificViews, IAttachCompanySpecificUrls, } from './companySpecific'; -import { ICompanySpecificPassportMiddleware } from './companySpecific/passport'; -import { IProviders } from './providers'; +import type { ICompanySpecificPassportMiddleware } from './companySpecific/passport'; +import type { SiteConfiguration } from './config'; +import type { IProviders } from './providers'; // We're great at long variable names! export interface ICompanySpecificStartupProperties { isCompanySpecific: true; + events?: ICompanySpecificEvents; routes?: IAttachCompanySpecificRoutes; middleware?: IAttachCompanySpecificMiddleware; administrationSection?: ICorporationAdministrationSection; @@ -42,6 +46,11 @@ export interface ICompanySpecificStartupProperties { urls?: IAttachCompanySpecificUrls; } -export type ICompanySpecificStartupFunction = (config: any, p: IProviders, rootdir: string) => Promise; +export type ICompanySpecificStartupFunction = ( + executionEnvironment: ExecutionEnvironment, + config: SiteConfiguration, + p: IProviders, + rootdir: string +) => Promise; export type ICompanySpecificStartup = ICompanySpecificStartupFunction & ICompanySpecificStartupProperties; diff --git a/interfaces/middleware.ts b/interfaces/middleware.ts new file mode 100644 index 000000000..8b8b44b2f --- /dev/null +++ b/interfaces/middleware.ts @@ -0,0 +1,11 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { UserSettings } from '../business/entities/userSettings'; +import type { ReposAppRequest } from './web'; + +export type ReposAppRequestWithUserSettings = ReposAppRequest & { + userSettings?: UserSettings; +}; diff --git a/interfaces/providers.ts b/interfaces/providers.ts index fbe0ae2e5..d438fbb1e 100644 --- a/interfaces/providers.ts +++ b/interfaces/providers.ts @@ -9,25 +9,25 @@ import redis, { RedisClientType } from 'redis'; import { Pool as PostgresPool } from 'pg'; import { - IApplicationProfile, + ApplicationProfile, ICorporationAdministrationSection, IReposApplication, SiteConfiguration, } from '.'; import { Operations } from '../business'; import QueryCache from '../business/queryCache'; -import { IAuditLogRecordProvider } from '../entities/auditLogRecord/auditLogRecordProvider'; -import { ILocalExtensionKeyProvider } from '../entities/localExtensionKey'; -import { IOrganizationMemberCacheProvider } from '../entities/organizationMemberCache/organizationMemberCacheProvider'; -import { IOrganizationSettingProvider } from '../entities/organizationSettings/organizationSettingProvider'; -import { IRepositoryCacheProvider } from '../entities/repositoryCache/repositoryCacheProvider'; -import { IRepositoryCollaboratorCacheProvider } from '../entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider'; -import { IRepositoryTeamCacheProvider } from '../entities/repositoryTeamCache/repositoryTeamCacheProvider'; -import { ITeamCacheProvider } from '../entities/teamCache/teamCacheProvider'; -import { IApprovalProvider } from '../entities/teamJoinApproval/approvalProvider'; -import { ITeamMemberCacheProvider } from '../entities/teamMemberCache/teamMemberCacheProvider'; -import { ITokenProvider } from '../entities/token'; -import { IUserSettingsProvider } from '../entities/userSettings'; +import { IAuditLogRecordProvider } from '../business/entities/auditLogRecord/auditLogRecordProvider'; +import { ILocalExtensionKeyProvider } from '../business/entities/localExtensionKey'; +import { IOrganizationMemberCacheProvider } from '../business/entities/organizationMemberCache/organizationMemberCacheProvider'; +import { IOrganizationSettingProvider } from '../business/entities/organizationSettings/organizationSettingProvider'; +import { IRepositoryCacheProvider } from '../business/entities/repositoryCache/repositoryCacheProvider'; +import { IRepositoryCollaboratorCacheProvider } from '../business/entities/repositoryCollaboratorCache/repositoryCollaboratorCacheProvider'; +import { IRepositoryTeamCacheProvider } from '../business/entities/repositoryTeamCache/repositoryTeamCacheProvider'; +import { ITeamCacheProvider } from '../business/entities/teamCache/teamCacheProvider'; +import { IApprovalProvider } from '../business/entities/teamJoinApproval/approvalProvider'; +import { ITeamMemberCacheProvider } from '../business/entities/teamMemberCache/teamMemberCacheProvider'; +import { ITokenProvider } from '../business/entities/token'; +import { IUserSettingsProvider } from '../business/entities/userSettings'; import { ICacheHelper } from '../lib/caching'; import BlobCache from '../lib/caching/blob'; import { ICampaignHelper } from '../lib/campaigns'; @@ -37,18 +37,18 @@ import { ILinkProvider } from '../lib/linkProviders'; import { IMailAddressProvider } from '../lib/mailAddressProvider'; import { IMailProvider } from '../lib/mailProvider'; import { IQueueProcessor } from '../lib/queues'; -import { ICustomizedNewRepositoryLogic, ICustomizedTeamPermissionsWebhookLogic } from '../transitional'; +import { ICustomizedNewRepositoryLogic, ICustomizedTeamPermissionsWebhookLogic } from '../lib/transitional'; import { IEntityMetadataProvider } from '../lib/entityMetadataProvider'; -import { IRepositoryProvider } from '../entities/repository'; +import { IRepositoryProvider } from '../business/entities/repository'; import { IKeyVaultSecretResolver } from '../lib/keyVaultResolver'; -import { IOrganizationAnnotationMetadataProvider } from '../entities/organizationAnnotation'; +import { IOrganizationAnnotationMetadataProvider } from '../business/entities/organizationAnnotation'; import type { IImmutableStorageProvider } from '../lib/immutable'; type ProviderGenerator = (value: string) => IEntityMetadataProvider; export interface IProviders { app: IReposApplication; - applicationProfile: IApplicationProfile; + applicationProfile: ApplicationProfile; authorizationCodeClient?: AuthorizationCode; corporateAdministrationProfile?: ICorporationAdministrationSection; corporateViews?: any; diff --git a/interfaces/queryCache.ts b/interfaces/queryCache.ts index 658775053..9a8486eca 100644 --- a/interfaces/queryCache.ts +++ b/interfaces/queryCache.ts @@ -10,11 +10,11 @@ import { GitHubRepositoryPermission, } from '.'; import { Team, Repository, Organization } from '../business'; -import { RepositoryCacheEntity } from '../entities/repositoryCache/repositoryCache'; -import { RepositoryCollaboratorCacheEntity } from '../entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; -import { RepositoryTeamCacheEntity } from '../entities/repositoryTeamCache/repositoryTeamCache'; -import { TeamCacheEntity } from '../entities/teamCache/teamCache'; -import { TeamMemberCacheEntity } from '../entities/teamMemberCache/teamMemberCache'; +import { RepositoryCacheEntity } from '../business/entities/repositoryCache/repositoryCache'; +import { RepositoryCollaboratorCacheEntity } from '../business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; +import { RepositoryTeamCacheEntity } from '../business/entities/repositoryTeamCache/repositoryTeamCache'; +import { TeamCacheEntity } from '../business/entities/teamCache/teamCache'; +import { TeamMemberCacheEntity } from '../business/entities/teamMemberCache/teamMemberCache'; export enum QueryCacheOperation { New = 'new', diff --git a/interfaces/web.ts b/interfaces/web.ts index 18448f877..4657f0082 100644 --- a/interfaces/web.ts +++ b/interfaces/web.ts @@ -4,7 +4,7 @@ // import { Session } from 'express-session'; -import { Request, Response } from 'express'; +import { NextFunction, Request, Response } from 'express'; import { AccessToken } from 'simple-oauth2'; import type { TelemetryClient } from 'applicationinsights'; @@ -36,8 +36,12 @@ export enum LocalApiRepoAction { Delete = 'delete', Archive = 'archive', UnArchive = 'unarchive', + Privatize = 'privatize', } +export type VoidedExpressRoute = (req: ReposAppRequest, res: Response, next: NextFunction) => Promise; +// req: Request>, res: Response, number>, next: NextFunction) => void | Promise<...> + export interface ReposAppRequest extends Request { // passport isAuthenticated(): boolean; @@ -56,9 +60,9 @@ export interface ReposAppRequest extends Request { correlationId?: string; scrubbedUrl?: string; - // FUTURE: apiContext: IndividualContext; individualContext: IndividualContext; + watchdogContextOverride?: IndividualContext; oauthAccessToken: AccessToken; } diff --git a/job.ts b/job.ts new file mode 100644 index 000000000..24e77ef08 --- /dev/null +++ b/job.ts @@ -0,0 +1,182 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { hostname } from 'os'; +import Debug from 'debug'; + +import type { + ExecutionEnvironment, + IProviders, + IReposJob, + IReposJobOptions, + IReposJobResult, + SiteConfiguration, +} from './interfaces'; +import { commonStartup } from '.'; +import { quitInTenSeconds } from './lib/utils'; +import initialize from './middleware/initialize'; + +export async function runJob( + job: (job: IReposJob) => Promise, + options?: IReposJobOptions +): Promise { + Debug.debug('startup')('starting job...'); + + options = options || {}; + // TODO: automatically track elapsed job time + const started = new Date(); + if (options.timeoutMinutes) { + setTimeout( + () => { + // TODO: insights metric and event, if a prefix exists + console.log(`Kill bit at ${options.timeoutMinutes}m`); + process.exit(1); + }, + 1000 * 60 * options.timeoutMinutes + ); + } + if (options.defaultDebugOutput && !process.env.DEBUG) { + process.env.DEBUG = options.defaultDebugOutput; + } + + let executionEnvironment: ExecutionEnvironment = null; + try { + executionEnvironment = await commonStartup( + initializeJob, + true /* job */, + options.enableAllGitHubApps, + null /* app */, + options.name + ); + } catch (startupError) { + console.error(`Job startup error before runJob: ${startupError}`); + quitInTenSeconds(false); + return; + } + const providers = executionEnvironment?.providers; + if (options.insightsPrefix && providers?.insights) { + try { + providers?.insights?.trackEvent({ + name: `${options.insightsPrefix}Started`, + properties: { + hostname: hostname(), + }, + }); + } catch (ignoreInsightsError) { + console.error(`insights error: ${ignoreInsightsError}`); + } + } + const jobObject = { + app: providers?.app, + executionEnvironment, + providers, + started, + parameters: options && options.parameters ? options.parameters : {}, + args: process.argv.length > 2 ? process.argv.slice(2) : [], + }; + let result: IReposJobResult = null; + try { + result = (await job.call(null, jobObject)) as IReposJobResult; + if (result?.successProperties && providers?.insights && options.insightsPrefix) { + try { + providers?.insights?.trackEvent({ + name: `${options.insightsPrefix}Success`, + properties: Object.assign( + { + hostname: hostname(), + }, + result.successProperties + ), + }); + } catch (ignoreInsightsError) { + console.error(`insights error: ${ignoreInsightsError}`); + } + } + } catch (jobError) { + console.error(`The job failed: ${jobError}`); + if (jobError.stack) { + console.error(jobError.stack); + } + // by default, let's not show the whole inner error + const simpleError = { ...jobError }; + simpleError?.cause && delete simpleError.cause; + console.dir(simpleError); + const config = providers?.config; + quitInTenSeconds(false, config); + if (options.insightsPrefix) { + try { + providers?.insights?.trackException({ + exception: jobError, + properties: { + name: `${options.insightsPrefix}Failure`, + }, + }); + } catch (ignoreInsightsError) { + console.error(`insights error: ${ignoreInsightsError}`); + } + } + trySilentInsightsFlush(providers); + return result; + } + // CONSIDER: insights metric for job time + trySilentInsightsFlush(providers); + console.log(); + console.log('The job was successful.'); + quitInTenSeconds(true); + return result; +} + +function trySilentInsightsFlush(providers: IProviders) { + try { + providers?.insights?.flush(); + } catch (ignored) { + console.warn(ignored); + } +} + +function initializeJob( + executionEnvironment: ExecutionEnvironment, + config: SiteConfiguration, + configurationError: Error +) { + if (!config || configurationError) { + console.warn(`Configuration did not resolve successfully`, configurationError); + } + return initialize( + executionEnvironment, + null /* app */, + null /* express */, + __dirname, + config, + configurationError + ); +} + +export const job = { + runBackgroundJob: async ( + script: (providers: IProviders, jobParameters?: IReposJob) => Promise, + options?: IReposJobOptions + ) => { + return runJob( + async function (jobParameters: IReposJob) { + return (await script(jobParameters.providers, jobParameters)) || {}; + }, + Object.assign({ enableAllGitHubApps: false }, options || {}) + ); + }, + run: async ( + script: (providers: IProviders, jobParameters?: IReposJob) => Promise, + options?: IReposJobOptions + ) => { + return runJob( + async function (jobParameters: IReposJob) { + return (await script(jobParameters.providers, jobParameters)) || {}; + }, + Object.assign({ enableAllGitHubApps: true }, options || {}) + ); + }, +}; + +export default job; diff --git a/jobs/cleanupBlobCache/task.ts b/jobs/cleanupBlobCache.ts similarity index 81% rename from jobs/cleanupBlobCache/task.ts rename to jobs/cleanupBlobCache.ts index cccf1bd0d..295326351 100644 --- a/jobs/cleanupBlobCache/task.ts +++ b/jobs/cleanupBlobCache.ts @@ -3,10 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import BlobCache from '../../lib/caching/blob'; -import { IReposJob } from '../../interfaces'; +// Job 17: Cleanup blob cache -export default async function go({ providers }: IReposJob): Promise { +import BlobCache from '../lib/caching/blob'; +import job from '../job'; +import { IProviders } from '../interfaces'; + +job.runBackgroundJob(cleanup); + +async function cleanup(providers: IProviders): Promise { for (const providerName in providers) { const provider = providers[providerName]; if (provider && provider['expiringBlobCache']) { diff --git a/jobs/cleanupBlobCache/index.ts b/jobs/cleanupBlobCache/index.ts deleted file mode 100644 index c359c26a1..000000000 --- a/jobs/cleanupBlobCache/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import Job from './task'; -import app from '../../app'; - -app.runJob(Job); diff --git a/jobs/cleanupInvites/task.ts b/jobs/cleanupInvites.ts similarity index 71% rename from jobs/cleanupInvites/task.ts rename to jobs/cleanupInvites.ts index 6da64f9a4..8d538c7f2 100644 --- a/jobs/cleanupInvites/task.ts +++ b/jobs/cleanupInvites.ts @@ -3,48 +3,50 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import moment from 'moment'; - -import { IReposJob } from '../../interfaces'; +// Job 16: cleanup invites // Organization invitations cleanup: remove any invitations that are older than a // set period of time from the organization. +import { GitHubOrganizationInvite, IProviders } from '../interfaces'; +import job from '../job'; +import { daysInMilliseconds } from '../lib/utils'; + const defaultMaximumInvitationAgeDays = 4; -export default async function cleanup({ providers }: IReposJob): Promise { +job.runBackgroundJob(cleanup, { + timeoutMinutes: 90, + insightsPrefix: 'JobOrganizationInvitationsCleanup', +}); + +async function cleanup(providers: IProviders) { const insights = providers.insights; let maximumInvitationAgeDays = defaultMaximumInvitationAgeDays; const { config, operations } = providers; - if ( - config.github && - config.github.jobs && - config.github.jobs.cleanup && - config.github.jobs.cleanup.maximumInvitationAgeDays - ) { + if (config?.github?.jobs?.cleanup?.maximumInvitationAgeDays) { maximumInvitationAgeDays = config.github.jobs.cleanup.maximumInvitationAgeDays; } - const maximumAgeMoment = moment().subtract(maximumInvitationAgeDays, 'days'); + const maximumAgeDate = new Date(new Date().getTime() - daysInMilliseconds(maximumInvitationAgeDays)); const organizations = operations.getOrganizations(); const removedInvitations = 0; for (const organization of organizations) { - let invitations: any[]; + let invitations: GitHubOrganizationInvite[]; try { invitations = await organization.getMembershipInvitations(); } catch (getInvitationsError) { - insights.trackException({ exception: getInvitationsError }); + insights?.trackException({ exception: getInvitationsError }); console.dir(getInvitationsError); continue; } if (!invitations || invitations.length === 0) { continue; } - const invitationsToRemove = []; + const invitationsToRemove: string[] = []; let emailInvitations = 0; for (let i = 0; i < invitations.length; i++) { const invite = invitations[i]; - const createdAt = moment(invite.created_at); - if (createdAt.isBefore(maximumAgeMoment)) { + const createdAt = new Date(invite.created_at); + if (createdAt < maximumAgeDate) { if (invite.login) { invitationsToRemove.push(invite.login); } else { @@ -52,8 +54,7 @@ export default async function cleanup({ providers }: IReposJob): Promise { console.warn(`An e-mail based invitation to ${invite.email} cannot be automatically canceled`); } const data = { - createdAt: createdAt.format(), - invitedAgo: createdAt.fromNow(), + createdAt: createdAt.toISOString(), login: invite.login, inviter: invite && invite.inviter && invite.inviter.login ? invite.inviter.login : undefined, role: invite.role, @@ -62,7 +63,7 @@ export default async function cleanup({ providers }: IReposJob): Promise { const eventName = invite.login ? 'JobOrganizationInviteCleanupInvitationNeeded' : 'JobOrganizationInviteCleanupInvitationNotUser'; - insights.trackEvent({ + insights?.trackEvent({ name: eventName, properties: data, }); @@ -80,8 +81,8 @@ export default async function cleanup({ providers }: IReposJob): Promise { try { await organization.removeMember(login); } catch (removeError) { - insights.trackException({ exception: removeError }); - insights.trackEvent({ + insights?.trackException({ exception: removeError }); + insights?.trackEvent({ name: 'JobOrganizationInvitationsCleanupInvitationFailed', properties: { login: login, @@ -92,5 +93,5 @@ export default async function cleanup({ providers }: IReposJob): Promise { } } console.log(`Job finishing. Removed ${removedInvitations} expired invitations.`); - insights.trackMetric({ name: 'JobOrganizationInvitationsExpired', value: removedInvitations }); + insights?.trackMetric({ name: 'JobOrganizationInvitationsExpired', value: removedInvitations }); } diff --git a/jobs/cleanupInvites/index.ts b/jobs/cleanupInvites/index.ts deleted file mode 100644 index 7d2e3f56d..000000000 --- a/jobs/cleanupInvites/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import Job from './task'; -import app from '../../app'; - -app.runJob(Job, { - timeoutMinutes: 90, - defaultDebugOutput: 'restapi', - insightsPrefix: 'JobOrganizationInvitationsCleanup', -}); diff --git a/jobs/cleanupKeys/index.ts b/jobs/cleanupKeys/index.ts deleted file mode 100644 index 8380b468f..000000000 --- a/jobs/cleanupKeys/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import Job from './task'; -import app from '../../app'; - -app.runJob(Job, { timeoutMinutes: 90, defaultDebugOutput: 'restapi', insightsPrefix: 'JobCleanupKeys' }); diff --git a/jobs/cleanupKeys/task.ts b/jobs/cleanupKeys/task.ts deleted file mode 100644 index 4e1d3b019..000000000 --- a/jobs/cleanupKeys/task.ts +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import throat from 'throat'; - -import { IReposJob, IReposJobResult } from '../../interfaces'; -import { sleep } from '../../utils'; -import { IGraphProvider } from '../../lib/graphProvider'; -import { LocalExtensionKey } from '../../entities/localExtensionKey/localExtensionKey'; - -async function lookupCorporateId( - graphProvider: IGraphProvider, - knownUsers: Map, - corporateId: string -): Promise { - const entry = knownUsers.get(corporateId); - if (entry === false) { - return false; - } else if (entry) { - return true; - } - - try { - const userDetails = await graphProvider.getUserById(corporateId); - if (!userDetails || !userDetails.userPrincipalName) { - knownUsers.set(corporateId, false); - return false; - } - knownUsers.set(corporateId, userDetails); - return true; - } catch (otherUserError) { - console.dir(otherUserError); - throw otherUserError; - } -} - -export default async function cleanup({ providers }: IReposJob): Promise { - const graphProvider = providers.graphProvider; - const localExtensionKeyProvider = providers.localExtensionKeyProvider; - const insights = providers.insights; - - console.log('reading all keys'); - const allKeys = await localExtensionKeyProvider.getAllKeys(); - console.log(`read ${allKeys.length}`); - - insights.trackEvent({ name: 'JobCleanupTokensKeysTokens', properties: { tokens: String(allKeys.length) } }); - - let errors = 0; - - let deleted = 0; - let okUserTokens = 0; - - const parallelUsers = 2; - const secondsDelayAfterSuccess = 0.25; - - const knownUsers = new Map(); - - const throttle = throat(parallelUsers); - await Promise.all( - allKeys.map((key: LocalExtensionKey) => - throttle(async () => { - const corporateId = key.corporateId; - const userStatus = await lookupCorporateId(graphProvider, knownUsers, corporateId); - if (!userStatus) { - try { - ++deleted; - console.log(`${deleted}: Deleting key for ${corporateId} that could not be found`); - await localExtensionKeyProvider.delete(key); - } catch (tokenDeleteError) { - --deleted; - console.dir(tokenDeleteError); - ++errors; - insights.trackException({ exception: tokenDeleteError }); - } - } else { - ++okUserTokens; - console.log(`${okUserTokens}: valid`); - } - - await sleep(secondsDelayAfterSuccess * 1000); - }) - ) - ); - - console.log(`deleted: ${deleted}`); - console.log(`okUserTokens: ${okUserTokens}`); - console.log(); - - return { - successProperties: { - deleted, - okUserTokens, - errors, - }, - }; -} diff --git a/jobs/cleanupTeamRequests.ts b/jobs/cleanupTeamRequests.ts new file mode 100644 index 000000000..99bbc59db --- /dev/null +++ b/jobs/cleanupTeamRequests.ts @@ -0,0 +1,65 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +// Job 18: cleanup team requests + +// Remove any team requests made by people who are no longer linked. + +import { IProviders } from '../interfaces'; +import job from '../job'; +import { TeamApprovalDecision } from '../routes/org/team/approval'; +import { CreateError } from '../lib/transitional'; + +job.runBackgroundJob(cleanup, { + timeoutMinutes: 5, + insightsPrefix: 'JobTeamRequestsCleanup', +}); + +async function cleanup(providers: IProviders) { + const { approvalProvider, insights, linkProvider } = providers; + if (!approvalProvider) { + throw CreateError.InvalidParameters('No approval provider instance available'); + } + + const linkedCorporateIds = await linkProvider.getAllCorporateIds(); + + let approvals = await approvalProvider.queryAllApprovals(); + approvals = approvals.filter((approval) => approval.active === true && approval.corporateId); + + const orphanApprovals = approvals.filter((approval) => !linkedCorporateIds.includes(approval.corporateId)); + + let removedRequests = 0; + let i = 0; + for (const approval of orphanApprovals) { + ++i; + try { + approval.active = false; + approval.decision = TeamApprovalDecision.Deny; + approval.decisionMessage = 'Requestor not linked'; + await approvalProvider.updateTeamApprovalEntity(approval); + insights?.trackEvent({ + name: 'JobTeamRequestsCleanupApprovalUpdate', + properties: { + approvalId: approval.approvalId, + }, + }); + console.log( + `Denied former linked user request ${approval.approvalId} (${i} of ${orphanApprovals.length})` + ); + ++removedRequests; + } catch (error) { + insights?.trackException({ + exception: error, + properties: { + eventName: 'JobTeamRequestsCleanupApprovalUpdateFailed', + approvalId: approval.approvalId, + }, + }); + console.warn(`Error ${error.message} updating approval ${approval.approvalId}`); + } + } + console.log(`Job finishing. Removed ${removedRequests} requests from former linked users.`); + insights?.trackMetric({ name: 'JobFormerRequestsDenied', value: removedRequests }); +} diff --git a/jobs/cleanupTokens/index.ts b/jobs/cleanupTokens/index.ts deleted file mode 100644 index 2b59c4a5d..000000000 --- a/jobs/cleanupTokens/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import Job from './task'; -import app from '../../app'; - -app.runJob(Job, { timeoutMinutes: 90, defaultDebugOutput: 'restapi', insightsPrefix: 'JobCleanupTokens' }); diff --git a/jobs/cleanupTokens/task.ts b/jobs/cleanupTokens/task.ts deleted file mode 100644 index 2bcd443e9..000000000 --- a/jobs/cleanupTokens/task.ts +++ /dev/null @@ -1,142 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import throat from 'throat'; -import { IReposJob, IReposJobResult } from '../../interfaces'; - -// Revoke tokens of users that no longer resolve in the corporate graph and -// delete tokens that have been expired 30 days. - -const expiredTokenDeleteThresholdDays = 30; - -import { PersonalAccessToken } from '../../entities/token/token'; -import { sleep } from '../../utils'; -import { IGraphProvider } from '../../lib/graphProvider'; - -async function lookupCorporateId( - graphProvider: IGraphProvider, - knownUsers: Map, - corporateId: string -): Promise { - const entry = knownUsers.get(corporateId); - if (entry === false) { - return false; - } else if (entry) { - return true; - } - - try { - const userDetails = await graphProvider.getUserById(corporateId); - if (!userDetails || !userDetails.userPrincipalName) { - knownUsers.set(corporateId, false); - return false; - } - knownUsers.set(corporateId, userDetails); - return true; - } catch (otherUserError) { - console.dir(otherUserError); - throw otherUserError; - } -} - -export default async function cleanup({ providers }: IReposJob): Promise { - const insights = providers.insights; - const graphProvider = providers.graphProvider; - const tokenProvider = providers.tokenProvider; - - console.log('reading all tokens'); - const allTokens = await tokenProvider.getAllTokens(); - console.log(`read ${allTokens.length}`); - - insights.trackEvent({ - name: 'JobCleanupTokensReadTokens', - properties: { tokens: String(allTokens.length) }, - }); - - let errors = 0; - - let revokedUnresolved = 0; - let deleted = 0; - let serviceTokens = 0; - let okUserTokens = 0; - - const parallelUsers = 1; - const secondsDelayAfterSuccess = 0.25; - - const now = new Date(); - const monthAgo = new Date(now.getTime() - 1000 * 60 * 60 * 24 * expiredTokenDeleteThresholdDays); - - const knownUsers = new Map(); - - const throttle = throat(parallelUsers); - await Promise.all( - allTokens.map((pat: PersonalAccessToken) => - throttle(async () => { - const isGuidMeansADash = pat.corporateId && pat.corporateId.includes('-'); - let wasUser = false; - if (isGuidMeansADash) { - wasUser = true; - - const userStatus = await lookupCorporateId(graphProvider, knownUsers, pat.corporateId); - if (!userStatus && pat.active !== false) { - pat.active = false; - console.log( - `Revoking key for ${pat.getIdentifier()} - employee ${pat.corporateId} could not be found` - ); - try { - await tokenProvider.updateToken(pat); - ++revokedUnresolved; - } catch (tokenUpdateError) { - console.dir(tokenUpdateError); - ++errors; - insights.trackException({ exception: tokenUpdateError }); - } - } - } else { - ++serviceTokens; - } - - if (pat.isExpired()) { - const dateExpired = pat.expires; - if (dateExpired < monthAgo) { - console.log(`Deleting key for ${pat.getIdentifier()} that expired ${dateExpired}`); - try { - await tokenProvider.deleteToken(pat); - ++deleted; - } catch (tokenDeleteError) { - console.dir(tokenDeleteError); - ++errors; - insights.trackException({ exception: tokenDeleteError }); - } - } else { - console.log( - `Expired key, keeping around ${pat.getIdentifier()} that expired ${dateExpired} for user notification purposes` - ); - } - } else if (wasUser) { - ++okUserTokens; - } - - await sleep(secondsDelayAfterSuccess * 1000); - }) - ) - ); - - console.log(`deleted: ${deleted}`); - console.log(`revokedUnresolved: ${revokedUnresolved}`); - console.log(`okUserTokens: ${okUserTokens}`); - console.log(`serviceTokens: ${serviceTokens}`); - console.log(); - - return { - successProperties: { - deleted, - revokedUnresolved, - okUserTokens, - serviceTokens, - errors, - }, - }; -} diff --git a/jobs/refreshQueryCache/deletedRepositories.ts b/jobs/deletedRepositoriesCache.ts similarity index 91% rename from jobs/refreshQueryCache/deletedRepositories.ts rename to jobs/deletedRepositoriesCache.ts index 46eaac0ac..d68573113 100644 --- a/jobs/refreshQueryCache/deletedRepositories.ts +++ b/jobs/deletedRepositoriesCache.ts @@ -1,14 +1,21 @@ -import app from '../../app'; -import { Organization } from '../../business/organization'; -import { RepositoryCollaboratorCacheEntity } from '../../entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; -import { RepositoryTeamCacheEntity } from '../../entities/repositoryTeamCache/repositoryTeamCache'; -import { IProviders, IReposJob, IReposJobResult } from '../../interfaces'; -import { ErrorHelper } from '../../transitional'; -import { sleep } from '../../utils'; +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +// Job: Consistency: Deleted repos (7) + +import job from '../job'; +import { Organization } from '../business/organization'; +import { RepositoryCollaboratorCacheEntity } from '../business/entities/repositoryCollaboratorCache/repositoryCollaboratorCache'; +import { RepositoryTeamCacheEntity } from '../business/entities/repositoryTeamCache/repositoryTeamCache'; +import { IProviders, IReposJobResult } from '../interfaces'; +import { ErrorHelper } from '../lib/transitional'; +import { sleep } from '../lib/utils'; const killBitHours = 8; -app.runJob(byUserJob, { +job.runBackgroundJob(byUserJob, { defaultDebugOutput: 'qcuser', timeoutMinutes: 60 * killBitHours, insightsPrefix: 'JobRefreshUserQC', @@ -202,7 +209,7 @@ async function processDeletedRepositories(providers: IProviders): Promise console.log(`removed collaborator repos: ${removedCollaboratorRepositories}`); } -export default async function byUserJob({ providers, args }: IReposJob): Promise { +async function byUserJob(providers: IProviders): Promise { const { config } = providers; if (config?.jobs?.refreshWrites !== true) { console.log('job is currently disabled to avoid metadata refresh/rewrites'); diff --git a/jobs/firehose/task.ts b/jobs/firehose.ts similarity index 89% rename from jobs/firehose/task.ts rename to jobs/firehose.ts index e4acde7e4..6f4db5af7 100644 --- a/jobs/firehose/task.ts +++ b/jobs/firehose.ts @@ -7,24 +7,31 @@ import os from 'os'; import { DateTime } from 'luxon'; -import App from '../../app'; -import ProcessOrganizationWebhook, { IGitHubWebhookProperties } from '../../webhooks/organizationProcessor'; + +import ProcessOrganizationWebhook, { + IGitHubWebhookProperties, +} from '../business/webhooks/organizationProcessor'; import { IGitHubAppInstallation, IGitHubWebhookEnterprise, IProviders, IReposJob, IReposJobResult, -} from '../../interfaces'; -import { sleep } from '../../utils'; -import { IQueueMessage } from '../../lib/queues'; -import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; +} from '../interfaces'; +import { sleep } from '../lib/utils'; +import { IQueueMessage } from '../lib/queues'; +import getCompanySpecificDeployment from '../middleware/companySpecificDeployment'; +import job from '../job'; const runningAsOngoingDeployment = true; const hardAbortMs = 1000 * 60 * 5; // 5 minutes -export default async function firehose({ providers, started }: IReposJob): Promise { +job.run(firehose, { + insightsPrefix: 'JobFirehose', +}); + +async function firehose(providers: IProviders, { started }: IReposJob): Promise { const processedEventTypes = {}; const interestingEvents = 0; let processedEvents = 0; @@ -89,28 +96,24 @@ export default async function firehose({ providers, started }: IReposJob): Promi console.log( `Parallelism for this run will be ${parallelism} logical threads, offset by ${sliceDelayPerThread}s` ); - // const insights = app.settings.appInsightsClient; - if (insights) { - insights.trackEvent({ - name: 'JobFirehoseStarted', - properties: { - hostname: os.hostname(), - // queue: serviceBusConfig.queue, - // subscription: serviceBusConfig.subscriptionName, - // messagesInQueue: messagesInQueue.toString(), - // deadLetters: deadLetters.toString(), - }, - }); - // insights.trackMetric({ name: 'FirehoseMessagesInQueue', value: messagesInQueue }); - // insights.trackMetric({ name: 'FirehoseDeadLetters', value: deadLetters }); - } + insights?.trackEvent({ + name: 'JobFirehoseStarted', + properties: { + hostname: os.hostname(), + // queue: serviceBusConfig.queue, + // subscription: serviceBusConfig.subscriptionName, + // messagesInQueue: messagesInQueue.toString(), + // deadLetters: deadLetters.toString(), + }, + }); + // insights.trackMetric({ name: 'FirehoseMessagesInQueue', value: messagesInQueue }); + // insights.trackMetric({ name: 'FirehoseDeadLetters', value: deadLetters }); const threads: Promise[] = []; let delay = 0; for (let i = 0; i < parallelism; i++) { - threads.push(createThread(App, providers, i, delay)); + threads.push(createThread(providers, i, delay)); delay += sliceDelayPerThread; } - const ok = true; await Promise.all(threads); console.warn('Forever execution thread has completed.'); @@ -119,7 +122,6 @@ export default async function firehose({ providers, started }: IReposJob): Promi // -- end of job startup -- async function createThread( - app, providers: IProviders, threadNumber: number, startupDelay: number @@ -136,7 +138,7 @@ export default async function firehose({ providers, started }: IReposJob): Promi await iterate(providers, threadNumber); } } catch (error) { - const insights = app.settings.appInsightsClient; + const insights = providers.insights; insights.trackException({ exception: error }); insights.trackEvent({ name: 'JobFirehoseFatalError', diff --git a/jobs/firehose/index.ts b/jobs/firehose/index.ts deleted file mode 100644 index 9ac3820d6..000000000 --- a/jobs/firehose/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import Job from './task'; -import app from '../../app'; - -app.runJob(Job, { - defaultDebugOutput: 'redis,restapi,querycache', - insightsPrefix: 'JobFirehose', - enableAllGitHubApps: true, -}); diff --git a/jobs/permissions.ts b/jobs/permissions.ts new file mode 100644 index 000000000..93031a4fc --- /dev/null +++ b/jobs/permissions.ts @@ -0,0 +1,214 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +// Job 15: System Team Permissions + +import { shuffle } from 'lodash'; +import throat from 'throat'; + +import job from '../job'; +import { TeamPermission } from '../business/teamPermission'; +import { GitHubRepositoryPermission, IProviders, IReposJobResult } from '../interfaces'; +import AutomaticTeamsWebhookProcessor from '../business/webhooks/tasks/automaticTeams'; +import { sleep } from '../lib/utils'; +import { ErrorHelper } from '../lib/transitional'; +import { Organization } from '../business'; + +// Permissions processing: visit all repos and make sure that any designated read, write, admin +// teams for the organization are present on every repo. This job is designed to be run relatively +// regularly but is not looking to answer "the truth" - it will use the cache of repos and other +// assets to not abuse GitHub and its API exhaustively. Over time repos will converge to having +// the right permissions. +// +// If a repository is "compliance locked", the system teams are not enforced until the lock is removed. + +const maxParallelism = 3; +const delayBetweenSeconds = 1; + +let updatedPermissions = 0; +let updatedRepos = 0; + +const missingTeams = new Set(); + +job.runBackgroundJob(permissionsRun, { + insightsPrefix: 'JobPermissions', +}); + +async function permissionsRun(providers: IProviders): Promise { + const { config, insights, operations } = providers; + if (config?.jobs?.refreshWrites !== true) { + console.log('job is currently disabled to avoid metadata refresh/rewrites'); + return; + } + + const throttle = throat(maxParallelism); + + const organizations = shuffle(Array.from(operations.organizations.values())); + + await Promise.allSettled( + organizations.map((organization, index) => + throttle(async () => { + return reviewOrganizationSystemTeams(providers, organization, index, organizations.length); + }) + ) + ); + + console.log(`Updated ${updatedPermissions} permissions across ${organizations.length} organizations`); + insights?.trackMetric({ name: 'JobSystemTeamsUpdatedPermissions', value: updatedPermissions }); + + console.log(`Updated ${updatedRepos} repos across ${organizations.length} organizations`); + insights?.trackMetric({ name: 'JobSystemTeamsUpdatedRepos', value: updatedRepos }); + + return {}; +} + +async function reviewOrganizationSystemTeams( + providers: IProviders, + organization: Organization, + index: number, + count: number +) { + const { insights } = providers; + const prefix = `${index}/${count}: ${organization.name}: `; + + console.log(`${prefix} Reviewing permissions for all repos in ${organization.name}...`); + try { + const repos = await organization.getRepositories(); + console.log(`Repos in the ${organization.name} org: ${repos.length}`); + const automaticTeams = new AutomaticTeamsWebhookProcessor(); + for (const repo of repos) { + let thisRepoUpdated = false; + console.log(`${organization.name}/${repo.name}`); + sleep(1000 * delayBetweenSeconds); + const cacheOptions = { + maxAgeSeconds: 10 * 60 /* 10m */, + backgroundRefresh: false, + }; + const { specialTeamIds, specialTeamLevels } = automaticTeams.processOrgSpecialTeams(repo.organization); + let permissions: TeamPermission[] = null; + try { + permissions = await repo.getTeamPermissions(cacheOptions); + } catch (getError) { + if (ErrorHelper.IsNotFound(getError)) { + console.log(`Repo gone: ${repo.organization.name}/${repo.name}`); + } else { + console.log( + `There was a problem getting the permissions for the repo ${repo.name} from ${repo.organization.name}` + ); + console.dir(getError); + } + continue; + } + let shouldSkipEnforcement = false; + const { customizedTeamPermissionsWebhookLogic } = providers; + if (customizedTeamPermissionsWebhookLogic) { + shouldSkipEnforcement = await customizedTeamPermissionsWebhookLogic.shouldSkipEnforcement(repo); + } + const currentPermissions = new Map(); + permissions.forEach((entry) => { + currentPermissions.set(Number(entry.team.id), entry.getAsPermission()); + }); + const teamsToSet = new Set(); + specialTeamIds.forEach((specialTeamId) => { + if (!currentPermissions.has(specialTeamId)) { + teamsToSet.add(specialTeamId); + } else if ( + isAtLeastPermissionLevel( + currentPermissions.get(specialTeamId), + specialTeamLevels.get(specialTeamId) + ) + ) { + // The team permission is already acceptable + } else { + console.log( + `Permission level for ${specialTeamId} is not good enough, expected ${specialTeamLevels.get( + specialTeamId + )} but currently ${currentPermissions.get(specialTeamId)}` + ); + teamsToSet.add(specialTeamId); + } + }); + const setArray = Array.from(teamsToSet.values()); + for (const teamId of setArray) { + const newPermission = specialTeamLevels.get(teamId); + if ( + shouldSkipEnforcement && + (newPermission as GitHubRepositoryPermission) !== GitHubRepositoryPermission.Pull + ) { + console.log( + `should add ${teamId} team with permission ${newPermission} to the repo ${repo.name}, but compliance lock prevents non-read system teams` + ); + insights?.trackEvent({ + name: 'JobSystemTeamsSkipped', + properties: { + org: organization.name, + repo: repo.name, + teamId, + reason: 'compliance lock', + newPermission, + }, + }); + } else { + try { + if (!missingTeams.has(teamId)) { + await repo.setTeamPermission(teamId, newPermission as GitHubRepositoryPermission); + ++updatedPermissions; + thisRepoUpdated = true; + insights?.trackEvent({ + name: 'JobSystemTeamsUpdated', + properties: { + org: organization.name, + repo: repo.name, + teamId, + newPermission, + }, + }); + } + } catch (error) { + if (ErrorHelper.IsNotFound(error)) { + missingTeams.add(teamId); + console.log( + `the team ID ${teamId} could not be found when setting to repo ${repo.name} in org ${organization.name} and should likely be removed from config...` + ); + } else { + console.log(`${repo.name}`); + console.dir(error); + throw error; + } + } + } + } + if (thisRepoUpdated) { + ++updatedRepos; + } + } + console.log(`Finished with repos in ${organization.name} organization`); + } catch (processOrganizationError) { + console.dir(processOrganizationError); + console.log(`moving past ${organization.name} processing due to error...`); + } +} + +function isAtLeastPermissionLevel(value, expected) { + if (value !== 'admin' && value !== 'push' && value !== 'pull') { + throw new Error(`The permission type ${value} is not understood by isAtLeastPermissionLevel`); + } + if (value === expected) { + return true; + } + // Admin always wins + if (value === 'admin') { + return true; + } else if (expected === 'admin') { + return false; + } + if (expected === 'write' && value === expected) { + return true; + } + if (expected === 'read') { + return true; + } + return false; +} diff --git a/jobs/permissions/index.ts b/jobs/permissions/index.ts deleted file mode 100644 index 40b4097e0..000000000 --- a/jobs/permissions/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -// Job: System Team Permissions - -import Job from './task'; -import app from '../../app'; - -app.runJob(Job, { - insightsPrefix: 'JobPermissions', - defaultDebugOutput: 'cache,restapi', -}); diff --git a/jobs/permissions/task.ts b/jobs/permissions/task.ts deleted file mode 100644 index 311e60711..000000000 --- a/jobs/permissions/task.ts +++ /dev/null @@ -1,155 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -// Job: System Team Permissions - -import { shuffle } from 'lodash'; - -import { TeamPermission } from '../../business/teamPermission'; -import { GitHubRepositoryPermission, IReposJob, IReposJobResult } from '../../interfaces'; -import AutomaticTeamsWebhookProcessor from '../../webhooks/tasks/automaticTeams'; -import { sleep } from '../../utils'; -import { ErrorHelper } from '../../transitional'; - -// Permissions processing: visit all repos and make sure that any designated read, write, admin -// teams for the organization are present on every repo. This job is designed to be run relatively -// regularly but is not looking to answer "the truth" - it will use the cache of repos and other -// assets to not abuse GitHub and its API exhaustively. Over time repos will converge to having -// the right permissions. -// -// If a repository is "compliance locked", the system teams are not enforced until the lock is removed. - -const maxParallelism = 1; - -const delayBetweenSeconds = 1; - -export default async function permissionsRun({ providers }: IReposJob): Promise { - const { config, operations } = providers; - if (config?.jobs?.refreshWrites !== true) { - console.log('job is currently disabled to avoid metadata refresh/rewrites'); - return; - } - - for (const organization of shuffle(Array.from(operations.organizations.values()))) { - console.log(`Reviewing permissions for all repos in ${organization.name}...`); - try { - const repos = await organization.getRepositories(); - console.log(`Repos in the ${organization.name} org: ${repos.length}`); - let z = 0; - const automaticTeams = new AutomaticTeamsWebhookProcessor(); - for (const repo of repos) { - console.log(`${repo.organization.name}/${repo.name}`); - sleep(1000 * delayBetweenSeconds); - const cacheOptions = { - maxAgeSeconds: 10 * 60 /* 10m */, - backgroundRefresh: false, - }; - ++z; - if (z % 250 === 1) { - console.log('. ' + z); - } - const { specialTeamIds, specialTeamLevels } = automaticTeams.processOrgSpecialTeams( - repo.organization - ); - let permissions: TeamPermission[] = null; - try { - permissions = await repo.getTeamPermissions(cacheOptions); - } catch (getError) { - if (getError.status == /* loose */ 404) { - console.log(`Repo gone: ${repo.organization.name}/${repo.name}`); - } else { - console.log( - `There was a problem getting the permissions for the repo ${repo.name} from ${repo.organization.name}` - ); - console.dir(getError); - } - continue; - } - let shouldSkipEnforcement = false; - const { customizedTeamPermissionsWebhookLogic } = providers; - if (customizedTeamPermissionsWebhookLogic) { - shouldSkipEnforcement = await customizedTeamPermissionsWebhookLogic.shouldSkipEnforcement(repo); - } - const currentPermissions = new Map(); - permissions.forEach((entry) => { - currentPermissions.set(Number(entry.team.id), entry.permission); - }); - const teamsToSet = new Set(); - specialTeamIds.forEach((specialTeamId) => { - if (!currentPermissions.has(specialTeamId)) { - teamsToSet.add(specialTeamId); - } else if ( - isAtLeastPermissionLevel( - currentPermissions.get(specialTeamId), - specialTeamLevels.get(specialTeamId) - ) - ) { - // The team permission is already acceptable - } else { - console.log( - `Permission level for ${specialTeamId} is not good enough, expected ${specialTeamLevels.get( - specialTeamId - )} but currently ${currentPermissions.get(specialTeamId)}` - ); - teamsToSet.add(specialTeamId); - } - }); - const setArray = Array.from(teamsToSet.values()); - for (const teamId of setArray) { - const newPermission = specialTeamLevels.get(teamId); - if ( - shouldSkipEnforcement && - (newPermission as GitHubRepositoryPermission) !== GitHubRepositoryPermission.Pull - ) { - console.log( - `should add ${teamId} team with permission ${newPermission} to the repo ${repo.name}, but compliance lock prevents non-read system teams` - ); - } else { - try { - await repo.setTeamPermission(teamId, newPermission as GitHubRepositoryPermission); - } catch (error) { - if (ErrorHelper.IsNotFound(error)) { - console.log( - `the team ID ${teamId} could not be found when setting to repo ${repo.name} in org ${organization.name} and should likely be removed from config...` - ); - } else { - console.log(`${repo.name}`); - console.dir(error); - throw error; - } - } - } - } - } - console.log(`Finished with repos in ${organization.name} organization`); - } catch (processOrganizationError) { - console.dir(processOrganizationError); - console.log(`moving past ${organization.name} processing due to error...`); - } - } - return {}; -} - -function isAtLeastPermissionLevel(value, expected) { - if (value !== 'admin' && value !== 'push' && value !== 'pull') { - throw new Error(`The permission type ${value} is not understood by isAtLeastPermissionLevel`); - } - if (value === expected) { - return true; - } - // Admin always wins - if (value === 'admin') { - return true; - } else if (expected === 'admin') { - return false; - } - if (expected === 'write' && value === expected) { - return true; - } - if (expected === 'read') { - return true; - } - return false; -} diff --git a/jobs/refreshQueryCache/task.ts b/jobs/refreshQueryCache.ts similarity index 97% rename from jobs/refreshQueryCache/task.ts rename to jobs/refreshQueryCache.ts index 18baa46e8..c4d589fda 100644 --- a/jobs/refreshQueryCache/task.ts +++ b/jobs/refreshQueryCache.ts @@ -6,7 +6,17 @@ import throat from 'throat'; import { shuffle } from 'lodash'; -import { permissionsObjectToValue } from '../../transitional'; +const killBitHours = 48; + +import job from '../job'; + +job.runBackgroundJob(refreshQueryCache, { + defaultDebugOutput: 'querycache', + timeoutMinutes: 60 * killBitHours, + insightsPrefix: 'JobRefreshQueryCache', +}); + +import { projectCollaboratorPermissionsObjectToGitHubRepositoryPermission } from '../lib/transitional'; import { Collaborator, Operations, @@ -16,9 +26,9 @@ import { Team, TeamMember, TeamPermission, -} from '../../business'; -import { sleep, addArrayToSet } from '../../utils'; -import QueryCache from '../../business/queryCache'; +} from '../business'; +import { sleep, addArrayToSet } from '../lib/utils'; +import QueryCache from '../business/queryCache'; import { IPagedCacheOptions, ICacheOptions, @@ -37,7 +47,8 @@ import { QueryCacheOperation, IReposJob, IReposJobResult, -} from '../../interfaces'; + IProviders, +} from '../interfaces'; interface IConsistencyStats { new: number; @@ -247,7 +258,6 @@ async function refreshOrganization( const repositories = await organization.getRepositories(slowRequestCacheOptions); console.log(`${organizationIndex}: ${repositories.length} repositories in ${organization.name}`); const repoIds = new Set(repositories.map((repo) => repo.id.toString())); - for (let i = 0; i < repositories.length; i++) { try { const repository = repositories[i]; @@ -375,7 +385,7 @@ async function cacheRepositoryTeams( const repositoryId = repository.id.toString(); for (const teamPermission of repoTeamPermissions) { const teamId = teamPermission.team.id.toString(); - const permission = teamPermission.permission; + const permission = teamPermission.getAsPermission(); const isPrivate = repository.private as boolean; const repoName = repository.name as string; ops.push( @@ -610,7 +620,9 @@ async function cacheRepositoryCollaborators( const operations = []; const repositoryId = repository.id.toString(); for (const collaborator of repoCollaborators) { - const permission = permissionsObjectToValue(collaborator.permissions); + const permission = projectCollaboratorPermissionsObjectToGitHubRepositoryPermission( + collaborator.permissions + ); operations.push( await queryCache.addOrUpdateCollaborator( organizationId, @@ -628,7 +640,7 @@ async function cacheRepositoryCollaborators( return operations.filter((real) => real); } -export default async function refresh({ providers, args }: IReposJob): Promise { +async function refreshQueryCache(providers: IProviders, { args }: IReposJob): Promise { const { config } = providers; if (config?.jobs?.refreshWrites !== true) { console.log('job is currently disabled to avoid metadata refresh/rewrites'); diff --git a/jobs/refreshQueryCache/index.ts b/jobs/refreshQueryCache/index.ts deleted file mode 100644 index 714cb72d2..000000000 --- a/jobs/refreshQueryCache/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -// -// Copyright (c) Microsoft. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -import Job from './task'; -import app from '../../app'; - -const killBitHours = 48; - -app.runJob(Job, { - defaultDebugOutput: 'querycache', - timeoutMinutes: 60 * killBitHours, - insightsPrefix: 'JobRefreshQueryCache', -}); diff --git a/jobs/refreshUsernames/index.ts b/jobs/refreshUsernames.ts similarity index 67% rename from jobs/refreshUsernames/index.ts rename to jobs/refreshUsernames.ts index c36d7da88..275edc1d8 100644 --- a/jobs/refreshUsernames/index.ts +++ b/jobs/refreshUsernames.ts @@ -6,28 +6,29 @@ // Job: Backfill aliases (3) // Job: User attributes hygiene - alias backfills (4) -import app from '../../app'; +import job from '../job'; import throat from 'throat'; import { shuffle } from 'lodash'; -import { sleep } from '../../utils'; -import { IReposJob, IReposJobResult, UnlinkPurpose } from '../../interfaces'; +import { sleep } from '../lib/utils'; +import { IProviders, IReposJobResult, UnlinkPurpose } from '../interfaces'; +import { ErrorHelper } from '../lib/transitional'; -const backfillAliasesOnly = process.env.BACKFILL_ALIASES === '1'; - -app.runJob(refresh, { - defaultDebugOutput: 'cache,restapi', +job.runBackgroundJob(refresh, { insightsPrefix: 'JobRefreshUsernames', }); -async function refresh({ providers }: IReposJob): Promise { +async function refresh(providers: IProviders): Promise { const { config, operations, insights, linkProvider, graphProvider } = providers; if (config?.jobs?.refreshWrites !== true) { console.log('job is currently disabled to avoid metadata refresh/rewrites'); return; } + const backfillAliasesOnly = config.process.get('BACKFILL_ALIASES') === '1'; + const terminateLinksAndMemberships = config.process.get('REFRESH_USERNAMES_TERMINATE_ACCOUNTS') === '1'; + console.log('reading all links'); let allLinks = shuffle(await linkProvider.getAll()); console.log(`READ: ${allLinks.length} links`); @@ -67,6 +68,9 @@ async function refresh({ providers }: IReposJob): Promise { allLinks.map((link) => throttle(async () => { ++i; + if (i % 100 === 0) { + console.log(`${i}/${allLinks.length}; total updates=${updates}, errors=${errors}`); + } // Refresh GitHub username for the ID const id = link.thirdPartyId; @@ -96,7 +100,19 @@ async function refresh({ providers }: IReposJob): Promise { ++updatedAvatars; } } catch (githubError) { - console.dir(githubError); + if (ErrorHelper.IsNotFound(githubError)) { + console.warn( + `Deleted GitHub account, id=${id}, username_was=${link.thirdPartyUsername}; https://api.github.com/users/${link.thirdPartyUsername}` + ); + insights.trackMetric({ name: 'JobRefreshUsernamesMissingGitHubAccounts', value: 1 }); + insights.trackEvent({ + name: 'JobRefreshUsernamesGitHubAccountNotFound', + properties: { githubid: id, error: githubError.message }, + }); + } else { + console.dir(githubError); + } + throw githubError; } try { @@ -129,7 +145,17 @@ async function refresh({ providers }: IReposJob): Promise { } } catch (graphLookupError) { // Ignore graph lookup issues, other jobs handle terminated employees - console.dir(graphLookupError); + if (ErrorHelper.IsNotFound(graphLookupError)) { + console.warn(`Deleted AAD account, id=${id}, username_was=${link.corporateUsername}`); + insights.trackMetric({ name: 'JobRefreshUsernamesMissingCorporateAccounts', value: 1 }); + insights.trackEvent({ + name: 'JobRefreshUsernamesCorporateAccountNotFound', + properties: { githubid: id, error: graphLookupError.message }, + }); + } else { + console.dir(graphLookupError); + } + throw graphLookupError; } if (changed) { @@ -138,28 +164,31 @@ async function refresh({ providers }: IReposJob): Promise { ++updates; } } catch (getDetailsError) { - if (getDetailsError.status == /* loose compare */ '404') { + if (ErrorHelper.IsNotFound(getDetailsError)) { ++notFoundErrors; insights.trackEvent({ name: 'JobRefreshUsernamesNotFound', - properties: { githubid: id, error: getDetailsError.message }, + properties: { githubid: id, aadId: link.corporateId, error: getDetailsError.message }, }); - try { - await operations.terminateLinkAndMemberships(id, { purpose: UnlinkPurpose.Deleted }); - insights.trackEvent({ - name: 'JobRefreshUsernamesUnlinkDelete', - properties: { githubid: id, error: getDetailsError.message }, - }); - } catch (unlinkDeletedAccountError) { - console.dir(unlinkDeletedAccountError); - insights.trackException({ - exception: unlinkDeletedAccountError, - properties: { githubid: id, event: 'JobRefreshUsernamesDeleteError' }, - }); + if (terminateLinksAndMemberships) { + try { + await operations.terminateLinkAndMemberships(id, { purpose: UnlinkPurpose.Deleted }); + insights.trackEvent({ + name: 'JobRefreshUsernamesUnlinkDelete', + properties: { githubid: id, error: getDetailsError.message }, + }); + } catch (unlinkDeletedAccountError) { + console.dir(unlinkDeletedAccountError); + insights.trackException({ + exception: unlinkDeletedAccountError, + properties: { githubid: id, event: 'JobRefreshUsernamesDeleteError' }, + }); + } } } else { console.dir(getDetailsError); ++errors; + insights.trackMetric({ name: 'JobRefreshUsernamesErrors', value: 1 }); insights.trackException({ exception: getDetailsError, properties: { name: 'JobRefreshUsernamesError' }, @@ -188,8 +217,8 @@ async function refresh({ providers }: IReposJob): Promise { console.log(`Updates: ${updates}`); console.log(`GitHub username changes: ${updatedUsernames}`); console.log(`GitHub avatar changes: ${updatedAvatars}`); - console.log(`AAD name changes: ${updatedAadNames}`); - console.log(`AAD username changes: ${updatedAadUpns}`); + console.log(`Corporate name changes: ${updatedAadNames}`); + console.log(`Corporate username changes: ${updatedAadUpns}`); console.log(`Updated corporate mails: ${updatedCorporateMails}`); return { diff --git a/jobs/repositories.ts b/jobs/repositories.ts index 6c2a306cc..f8e86427e 100644 --- a/jobs/repositories.ts +++ b/jobs/repositories.ts @@ -3,28 +3,27 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -// JOB 13: refresh repository data -// This is very similar to the query cache, but using proper Postgres type entities, and -// not being used by the app today. +// Job 13: refresh repository data -// Implementation is initial and not as robust (will refresh everything, even things not touched -// since the last update; limited telemetry.) +// This is very similar to the query cache, but using proper Postgres type entities, and +// not being used by the app today at runtime. Possible optimizations include only +// targeting refreshes based on last-cached times. The act of refreshing these entities +// also helps keep the standard GitHub repository cache up to date. import throat from 'throat'; -import app from '../app'; +import job from '../job'; import { Organization, sortByRepositoryDate } from '../business'; -import { IRepositoryProvider, RepositoryEntity } from '../entities/repository'; -import { IProviders, IReposJob, IReposJobResult } from '../interfaces'; -import { ErrorHelper } from '../transitional'; -import { sleep } from '../utils'; +import { RepositoryEntity, tryGetRepositoryEntity } from '../business/entities/repository'; +import { IProviders, IReposJobResult } from '../interfaces'; +import { sleep } from '../lib/utils'; -const sleepBetweenReposMs = 125; +const sleepBetweenReposMs = 110; const maxParallel = 6; const shouldUpdateCached = true; -async function refreshRepositories({ providers }: IReposJob): Promise { +async function refreshRepositories(providers: IProviders): Promise { const { config, operations } = providers; if (config?.jobs?.refreshWrites !== true) { console.log('job is currently disabled to avoid metadata refresh/rewrites'); @@ -32,7 +31,7 @@ async function refreshRepositories({ providers }: IReposJob): Promise 0 ? ' continues' : ''})`); + } try { let repositoryEntity = await tryGetRepositoryEntity(repositoryProvider, repo.id); if (await repo.isDeleted()) { @@ -73,28 +76,33 @@ async function processOrganization( continue; } const entity = repo.getEntity(); - let update = false; + let updatedFields: string[] = null; + let replace = false; if (!repositoryEntity) { repositoryEntity = new RepositoryEntity(); - setFields(repositoryProvider, repositoryEntity, entity); + setFields(repositoryEntity, entity, true); await repositoryProvider.insert(repositoryEntity); console.log(`${prefix}inserted ${organization.name}/${repositoryEntity.name}`); continue; } else { - setFields(repositoryProvider, repositoryEntity, entity); - // not detecting changes now - update = true; + updatedFields = setFields(repositoryEntity, entity, false /* not new */); + replace = updatedFields?.length > 0; } - if (!update && shouldUpdateCached) { - update = true; + if (updatedFields.length === 0 && shouldUpdateCached) { + replace = true; repositoryEntity.cached = new Date(); } - if (update) { + if (replace) { await repositoryProvider.replace(repositoryEntity); - console.log(`${prefix}Updated all fields for ${organization.name}/${repo.name}`); + updatedFields.length > 0 && + console.log( + `${prefix}Updated ${updatedFields.length} field${updatedFields.length === 1 ? '' : 's'} for ${ + organization.name + }/${repo.name} [${updatedFields.join(', ')}]` + ); } } catch (error) { - console.warn(`${prefix}repo error: ${repo.name} in organization ${organization.name}`); + console.warn(`${prefix}repo error: ${repo.name} in organization ${organization.name}: ${error}`); } await sleep(sleepBetweenReposMs); @@ -106,70 +114,237 @@ async function processOrganization( return {}; } -function setFields(repositoryProvider: IRepositoryProvider, repositoryEntity: RepositoryEntity, entity: any) { - repositoryEntity.repositoryId = entity.id; - repositoryEntity.archived = entity.archived; - repositoryEntity.cached = new Date(); +function setFields(repositoryEntity: RepositoryEntity, entity: any, isNew: boolean) { + const changed: string[] = []; + if ( + (repositoryEntity.repositoryId || entity.id) && + String(repositoryEntity.repositoryId) !== String(entity.id) + ) { + repositoryEntity.repositoryId = parseInt(entity.id, 10); + changed.push('id'); + } + if ((entity.archived || repositoryEntity.archived) && repositoryEntity.archived !== entity.archived) { + repositoryEntity.archived = entity.archived; + changed.push('archived'); + } if (entity.created_at) { - repositoryEntity.createdAt = new Date(entity.created_at); - } - repositoryEntity.defaultBranch = entity.default_branch; - repositoryEntity.description = entity.description; - repositoryEntity.disabled = entity.disabled; - repositoryEntity.fork = entity.fork; - repositoryEntity.forksCount = entity.forks_count; - repositoryEntity.hasDownloads = entity.has_downloads; - repositoryEntity.hasIssues = entity.has_issues; - repositoryEntity.hasPages = entity.has_pages; - repositoryEntity.hasProjects = entity.has_projects; - repositoryEntity.hasWiki = entity.has_wiki; - repositoryEntity.homepage = entity.homepage; - repositoryEntity.language = entity.language; - repositoryEntity.license = entity.license?.spdx_id; - repositoryEntity.fullName = entity.full_name; - repositoryEntity.organizationId = entity.organization?.id; - repositoryEntity.organizationLogin = entity.organization?.login; - repositoryEntity.name = entity.name; - repositoryEntity.networkCount = entity.network_count; - repositoryEntity.openIssuesCount = entity.open_issues_count; - repositoryEntity.organizationId = entity.organization?.id; - repositoryEntity.parentId = entity.parent?.id; - repositoryEntity.parentName = entity.parent?.login; - repositoryEntity.parentOrganizationId = entity.parent?.organization?.id; - repositoryEntity.parentOrganizationName = entity.parent?.organization?.login; - repositoryEntity.private = entity.private; + const createdAt = new Date(entity.created_at); + const currentCreatedAt = repositoryEntity.createdAt ? new Date(repositoryEntity.createdAt) : null; + if (currentCreatedAt && createdAt && currentCreatedAt.toISOString() !== createdAt.toISOString()) { + repositoryEntity.pushedAt = createdAt; + changed.push('created_at'); + } else if (!currentCreatedAt && createdAt) { + repositoryEntity.createdAt = createdAt; + changed.push('created_at'); + } + } + if ( + (entity.default_branch || repositoryEntity.defaultBranch) && + entity.default_branch !== repositoryEntity.defaultBranch + ) { + repositoryEntity.defaultBranch = entity.default_branch; + changed.push('default_branch'); + } + if ( + (entity.description || repositoryEntity.description) && + entity.description !== repositoryEntity.description + ) { + repositoryEntity.description = entity.description; + changed.push('description'); + } + if ((entity.disabled || repositoryEntity.disabled) && entity.disabled !== repositoryEntity.disabled) { + repositoryEntity.disabled = entity.disabled; + changed.push('disabled'); + } + if ((entity.fork || repositoryEntity.fork) && entity.fork !== repositoryEntity.fork) { + repositoryEntity.fork = entity.fork; + changed.push('fork'); + } + if ( + (entity.forks_count || repositoryEntity.forksCount) && + String(entity.forks_count) !== String(repositoryEntity.forksCount) + ) { + repositoryEntity.forksCount = parseInt(entity.forks_count, 10); + changed.push('forks_count'); + } + if ( + (entity.has_downloads || repositoryEntity.hasDownloads) && + entity.has_downloads !== repositoryEntity.hasDownloads + ) { + repositoryEntity.hasDownloads = entity.has_downloads; + changed.push('has_downloads'); + } + if ((entity.has_issues || repositoryEntity.hasIssues) && entity.has_issues !== repositoryEntity.hasIssues) { + repositoryEntity.hasIssues = entity.has_issues; + changed.push('has_issues'); + } + if ((entity.has_pages || repositoryEntity.hasPages) && entity.has_pages !== repositoryEntity.hasPages) { + repositoryEntity.hasPages = entity.has_pages; + changed.push('has_pages'); + } + if ( + (entity.has_projects || repositoryEntity.hasProjects) && + entity.has_projects !== repositoryEntity.hasProjects + ) { + repositoryEntity.hasProjects = entity.has_projects; + changed.push('has_projects'); + } + if ((entity.has_wiki || repositoryEntity.hasWiki) && entity.has_wiki !== repositoryEntity.hasWiki) { + repositoryEntity.hasWiki = entity.has_wiki; + changed.push('has_wiki'); + } + if ((entity.homepage || repositoryEntity.homepage) && entity.homepage !== repositoryEntity.homepage) { + repositoryEntity.homepage = entity.homepage; + changed.push('homepage'); + } + if ((entity.language || repositoryEntity.language) && entity.language !== repositoryEntity.language) { + repositoryEntity.language = entity.language; + changed.push('language'); + } + if (entity.license?.spdx_id !== repositoryEntity.license) { + repositoryEntity.license = entity.license?.spdx_id; + changed.push('license.spdx_id'); + } + if ((entity.full_name || repositoryEntity.fullName) && entity.full_name !== repositoryEntity.fullName) { + repositoryEntity.fullName = entity.full_name; + changed.push('full_name'); + } + if ( + (entity.organization?.id || repositoryEntity.organizationId) && + String(entity.organization?.id) !== String(repositoryEntity.organizationId) + ) { + repositoryEntity.organizationId = parseInt(entity.organization?.id, 10); + changed.push('organization.id'); + } + if (entity.organization?.login !== repositoryEntity.organizationLogin) { + repositoryEntity.organizationLogin = entity.organization?.login; + changed.push('organization.login'); + } + if ((entity.name || repositoryEntity.name) && entity.name !== repositoryEntity.name) { + repositoryEntity.name = entity.name; + changed.push('name'); + } + if ( + (entity.network_count || repositoryEntity.networkCount) && + String(entity.network_count) !== String(repositoryEntity.networkCount) + ) { + repositoryEntity.networkCount = parseInt(entity.network_count, 10); + changed.push('network_count'); + } + if ( + (entity.open_issues_count || repositoryEntity.openIssuesCount) && + String(entity.open_issues_count) !== String(repositoryEntity.openIssuesCount) + ) { + repositoryEntity.openIssuesCount = parseInt(entity.open_issues_count, 10); + changed.push('open_issues_count'); + } + if ( + (entity.parent?.id || repositoryEntity.parentId) && + String(entity.parent?.id) !== String(repositoryEntity.parentId) + ) { + repositoryEntity.parentId = parseInt(entity.parent?.id, 10); + changed.push('parent.id'); + } + if ( + (entity.parent?.login || repositoryEntity.parentName) && + entity.parent?.login !== repositoryEntity.parentName + ) { + repositoryEntity.parentName = entity.parent?.login; + changed.push('parent.login'); + } + if ( + (entity?.parent?.organization?.id || repositoryEntity.parentOrganizationId) && + String(entity?.parent?.organization?.id) !== String(repositoryEntity.parentOrganizationId) + ) { + repositoryEntity.parentOrganizationId = parseInt(entity.parent?.organization?.id, 10); + changed.push('parent.organization.id'); + } + if ( + (entity?.parent?.organization?.login || repositoryEntity.parentOrganizationName) && + entity?.parent?.organization?.login !== repositoryEntity.parentOrganizationName + ) { + repositoryEntity.parentOrganizationName = entity.parent?.organization?.login; + changed.push('parent.organization.login'); + } + if ((entity.private || repositoryEntity.private) && entity.private !== repositoryEntity.private) { + repositoryEntity.private = entity.private; + changed.push('private'); + } if (entity.pushed_at) { - repositoryEntity.pushedAt = new Date(entity.pushed_at); + const pushedAt = new Date(entity.pushed_at); + const currentPushedAt = repositoryEntity.pushedAt ? new Date(repositoryEntity.pushedAt) : null; + if (currentPushedAt && pushedAt && currentPushedAt.toISOString() !== pushedAt.toISOString()) { + repositoryEntity.pushedAt = pushedAt; + changed.push('pushed_at'); + } else if (!currentPushedAt && pushedAt) { + repositoryEntity.pushedAt = pushedAt; + changed.push('pushed_at'); + } } - repositoryEntity.size = entity.size; - repositoryEntity.stargazersCount = entity.stargazers_count; - repositoryEntity.subscribersCount = entity.subscribers_count; - repositoryEntity.topics = entity.topics; - if (entity.updated_at) { - repositoryEntity.updatedAt = new Date(entity.updated_at); + if ((entity.size || repositoryEntity.size) && String(entity.size) !== String(repositoryEntity.size)) { + repositoryEntity.size = parseInt(entity.size, 10); + changed.push('size'); } - repositoryEntity.visibility = entity.visibility; - repositoryEntity.watchersCount = entity.watchers_count; - return repositoryEntity; -} - -async function tryGetRepositoryEntity( - repositoryProvider: IRepositoryProvider, - repositoryId: number -): Promise { - try { - const repositoryEntity = await repositoryProvider.get(repositoryId); - return repositoryEntity; - } catch (error) { - if (ErrorHelper.IsNotFound(error)) { - return null; + if ( + (entity.stargazers_count || repositoryEntity.stargazersCount) && + String(entity.stargazers_count) !== String(repositoryEntity.stargazersCount) + ) { + repositoryEntity.stargazersCount = parseInt(entity.stargazers_count, 10); + changed.push('stargazers_count'); + } + if ( + (entity.subscribers_count || repositoryEntity.subscribersCount) && + String(entity.subscribers_count) !== String(repositoryEntity.subscribersCount) + ) { + repositoryEntity.subscribersCount = parseInt(entity.subscribers_count, 10); + changed.push('subscribers_count'); + } + if (entity.topics && !repositoryEntity.topics) { + repositoryEntity.topics = entity.topics; + changed.push('topics'); + } else if (!entity.topics && repositoryEntity.topics) { + repositoryEntity.topics = null; + changed.push('topics'); + } else { + const storedTopics = [...(repositoryEntity.topics || [])].sort(); + const entityTopics = [...(entity.topics || [])].sort(); + if (storedTopics.join(',') !== entityTopics.join(',')) { + repositoryEntity.topics = entity.topics; + changed.push('topics'); } - throw error; } + if (entity.updated_at) { + const updatedAt = new Date(entity.updated_at); + const currentUpdatedAt = repositoryEntity.updatedAt ? new Date(repositoryEntity.updatedAt) : null; + if (currentUpdatedAt && updatedAt && currentUpdatedAt.toISOString() !== updatedAt.toISOString()) { + repositoryEntity.updatedAt = updatedAt; + changed.push('updated_at'); + } else if (!currentUpdatedAt && updatedAt) { + repositoryEntity.updatedAt = updatedAt; + changed.push('updated_at'); + } + } + if ( + (entity.visibility || repositoryEntity.visibility) && + entity.visibility !== repositoryEntity.visibility + ) { + repositoryEntity.visibility = entity.visibility; + changed.push('visibility'); + } + if ( + (entity.watchers_count || repositoryEntity.watchersCount) && + String(entity.watchers_count) !== String(repositoryEntity.watchersCount) + ) { + repositoryEntity.watchersCount = parseInt(entity.watchers_count, 10); + changed.push('watchers_count'); + } + if (changed.length > 0 || isNew) { + repositoryEntity.cached = new Date(); + } + return changed; } -app.runJob(refreshRepositories, { - timeoutMinutes: 320, - defaultDebugOutput: 'restapi', +job.run(refreshRepositories, { + timeoutMinutes: 600, insightsPrefix: 'JobRefreshRepositories', }); diff --git a/lib/caching/blob.ts b/lib/caching/blob.ts index 71c49a90b..7dfeada39 100644 --- a/lib/caching/blob.ts +++ b/lib/caching/blob.ts @@ -14,7 +14,7 @@ import { } from '@azure/storage-blob'; import { ICacheHelper } from '.'; -import { gunzipBuffer, gzipString } from '../../utils'; +import { gunzipBuffer, gzipString } from '../utils'; import Debug from 'debug'; const debug = Debug.debug('cache'); diff --git a/lib/caching/cosmosdb.ts b/lib/caching/cosmosdb.ts index 9eb9eb0b9..4406daa51 100644 --- a/lib/caching/cosmosdb.ts +++ b/lib/caching/cosmosdb.ts @@ -6,8 +6,8 @@ import { ICacheHelper } from '.'; import { CosmosClient, Database, Container } from '@azure/cosmos'; import BlobCache, { IBlobCacheOptions } from './blob'; -import { sleep } from '../../utils'; -import { ErrorHelper, sha256 } from '../../transitional'; +import { sleep } from '../utils'; +import { ErrorHelper, getSafeCosmosResourceKey, sha256 } from '../transitional'; import Debug from 'debug'; const debug = Debug.debug('cache'); @@ -55,7 +55,7 @@ export default class CosmosCache implements ICacheHelper { } private safetyKey(str: string) { - return str.replace(/[%:\\/?#]/g, ''); + return getSafeCosmosResourceKey(str); } private key(key: string) { diff --git a/lib/caching/redis.ts b/lib/caching/redis.ts index 53ed8fa55..0b6b8035e 100644 --- a/lib/caching/redis.ts +++ b/lib/caching/redis.ts @@ -10,8 +10,8 @@ import Debug from 'debug'; const debug = Debug.debug('redis'); const debugCrossOrganization = Debug.debug('redis-cross-org'); -import { ICacheHelper } from '.'; -import { gunzipBuffer, gzipString } from '../../utils'; +import type { ICacheHelper } from '.'; +import { gunzipBuffer, gzipString } from '../utils'; export interface ISetCompressedOptions { minutesToExpire?: number; diff --git a/lib/campaigns.ts b/lib/campaigns.ts index 1d3418cf2..5835611cc 100644 --- a/lib/campaigns.ts +++ b/lib/campaigns.ts @@ -3,6 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { getSafeCosmosResourceKey } from './transitional'; import CosmosHelper from './cosmosHelper'; export interface ICampaignUserState { @@ -160,9 +161,9 @@ export class StatefulCampaignProvider implements ICampaignHelper { } private key(corporateId: string, campaignGroupId: string, campaignId?: string) { - return campaignId - ? `${campaignGroupId}-${campaignId}-${corporateId}` - : `${campaignGroupId}-${corporateId}`; + return getSafeCosmosResourceKey( + campaignId ? `${campaignGroupId}-${campaignId}-${corporateId}` : `${campaignGroupId}-${corporateId}` + ); } private baseObject(corporateId: string, campaignGroupId: string, campaignId?: string) { diff --git a/lib/config/painlessConfigAsCode.ts b/lib/config/painlessConfigAsCode.ts index de5aeb95b..998ef8c67 100644 --- a/lib/config/painlessConfigAsCode.ts +++ b/lib/config/painlessConfigAsCode.ts @@ -10,6 +10,7 @@ import path from 'path'; import walkBack from 'walk-back'; import { InnerError, IPainlessConfigGet, IProviderOptions } from '.'; import { processEnvironmentProvider } from './environmentConfigurationResolver'; +import { CreateError } from '../transitional'; const debug = Debug.debug('config'); @@ -70,10 +71,14 @@ function configurePackageEnvironments( try { values = environmentPackage(environment); } catch (problemCalling) { - const asText = problemCalling.toString(); - throw new Error( - `While calling the environment package "${npmName}" for the "${environment}" environment an error was thrown: ${asText}`, - { cause: problemCalling } + const asText = problemCalling.toString() as string; + let suggestion = ''; + if (asText.includes('Unable to require environment') && asText.includes('dist')) { + suggestion = 'Consider deleting and rebuilding the `dist` directory. '; + } + throw CreateError.ServerError( + `${suggestion}While calling the environment package "${npmName}" for the "${environment}" environment an error was thrown: ${asText}`, + problemCalling ); } } else if (typeof environmentPackage === 'object') { diff --git a/lib/cosmosSession/index.ts b/lib/cosmosSession/index.ts index d1eb0a313..a457a8da3 100644 --- a/lib/cosmosSession/index.ts +++ b/lib/cosmosSession/index.ts @@ -7,7 +7,7 @@ import { CosmosClient, Database, Container } from '@azure/cosmos'; import { Store } from 'express-session'; import { IAppSession } from '../../interfaces'; -import { ErrorHelper } from '../../transitional'; +import { ErrorHelper } from '../transitional'; export interface ICosmosSessionProviderOptions { endpoint: string; diff --git a/lib/entityMetadataProvider/entityMetadataProvider.ts b/lib/entityMetadataProvider/entityMetadataProvider.ts index 190943c08..6693c9ff0 100644 --- a/lib/entityMetadataProvider/entityMetadataProvider.ts +++ b/lib/entityMetadataProvider/entityMetadataProvider.ts @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IEntityMetadata, EntityMetadataType } from './entityMetadata'; -import { IEntityMetadataFixedQuery } from './query'; -import { swapMap } from '../../utils'; +import { type IEntityMetadata, EntityMetadataType } from './entityMetadata'; +import type { IEntityMetadataFixedQuery } from './query'; +import { swapMap } from '../utils'; export enum EntityField { Type = 'entityType', diff --git a/lib/entityMetadataProvider/postgres.ts b/lib/entityMetadataProvider/postgres.ts index 9928d9153..3a274c165 100644 --- a/lib/entityMetadataProvider/postgres.ts +++ b/lib/entityMetadataProvider/postgres.ts @@ -22,7 +22,7 @@ import { MetadataMappingDefinition, MetadataMappingDefinitionBase, } from './declarations'; -import { CreateError } from '../../transitional'; +import { CreateError } from '../transitional'; import { IDictionary } from '../../interfaces'; const MetadataColumnName = 'metadata'; @@ -34,6 +34,12 @@ const MapMetadataPropertiesToFields: any = { entityType: 'entitytype', }; +export enum PostgresColumnTranslations { + None = 'none', + Lowercase = 'lowercase', + LowercaseUnderscores = 'lowercase_underscores', +} + class PostgresMetadataDefinition extends MetadataMappingDefinitionBase { constructor(name: string) { super(name); @@ -194,6 +200,23 @@ class PostgresInternals { } } +function translateName(key: string, translations: PostgresColumnTranslations) { + switch (translations) { + case PostgresColumnTranslations.None: { + return key; + } + case PostgresColumnTranslations.Lowercase: { + return key.toLowerCase(); + } + case PostgresColumnTranslations.LowercaseUnderscores: { + return key.replace(/([A-Z])/g, '_$1').toLowerCase(); + } + default: { + throw CreateError.InvalidParameters(`Invalid column translation type: ${translations}`); + } + } +} + export class PostgresConfiguration { static IdentifyNativeFields(type: EntityMetadataType, fieldNames: string[]) { PostgresInternals.instance(type).nativeFieldNames = fieldNames; @@ -206,11 +229,12 @@ export class PostgresConfiguration { static MapFieldsToColumnNames( type: EntityMetadataType, map: Map, - lowercaseColumnNamesAutomatically?: boolean + columnTranslations: PostgresColumnTranslations = PostgresColumnTranslations.None ) { const dest = PostgresInternals.instance(type).mapFieldsToColumnNames; for (const [key, value] of map.entries()) { - dest.set(key, lowercaseColumnNamesAutomatically ? value.toLowerCase() : value); + const translatedValue = translateName(value, columnTranslations); + dest.set(key, translatedValue); } } @@ -230,7 +254,19 @@ export class PostgresConfiguration { return [fieldName, fieldName]; }) ), - true + PostgresColumnTranslations.Lowercase + ); + } + + static MapFieldsToColumnNamesFromListUnderscoreLowercased(type: EntityMetadataType, fieldNames: string[]) { + PostgresConfiguration.MapFieldsToColumnNames( + type, + new Map( + fieldNames.map((fieldName) => { + return [fieldName, fieldName]; + }) + ), + PostgresColumnTranslations.LowercaseUnderscores ); } @@ -652,18 +688,18 @@ export class PostgresEntityMetadataProvider implements IEntityMetadataProvider { } } - private metadataToRowMetadata(metadata: IEntityMetadata): any { - const shallowClone = Object.assign({}, metadata); - delete shallowClone.entityCreated; - delete shallowClone.entityFieldNames; - delete shallowClone.entityId; - delete shallowClone.entityType; - return shallowClone; - } + // private metadataToRowMetadata(metadata: IEntityMetadata): any { + // const shallowClone = Object.assign({}, metadata); + // delete shallowClone.entityCreated; + // delete shallowClone.entityFieldNames; + // delete shallowClone.entityId; + // delete shallowClone.entityType; + // return shallowClone; + // } - private stripEntityIdentities(type: EntityMetadataType, entity: any) { - return stripEntityIdentities(type, entity); - } + // private stripEntityIdentities(type: EntityMetadataType, entity: any) { + // return stripEntityIdentities(type, entity); + // } private rowToMetadataObject(type: EntityMetadataType, row: any): IEntityMetadata { return rowToMetadataObject(type, row); diff --git a/lib/entityMetadataProvider/query.ts b/lib/entityMetadataProvider/query.ts index c902218e6..6c9af613a 100644 --- a/lib/entityMetadataProvider/query.ts +++ b/lib/entityMetadataProvider/query.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IEntityMetadataProvider } from './entityMetadataProvider'; +import type { IEntityMetadataProvider } from './entityMetadataProvider'; import { EntityMetadataType, EntityMetadataBase } from './entityMetadata'; // Newer "entity" implementations have fully decoupled and no longer use this single query type. diff --git a/lib/entityMetadataProvider/table.ts b/lib/entityMetadataProvider/table.ts index 4ec002995..5980472ec 100644 --- a/lib/entityMetadataProvider/table.ts +++ b/lib/entityMetadataProvider/table.ts @@ -50,7 +50,7 @@ import { MetadataMappingDefinitionBase, } from './declarations'; import { encryptTableEntity, decryptTableEntity, ITableEncryptionOperationOptions } from './tableEncryption'; -import { CreateError, ErrorHelper } from '../../transitional'; +import { CreateError, ErrorHelper } from '../transitional'; import { IKeyVaultSecretResolver } from '../keyVaultResolver'; export interface ITableEncryptionOptions { diff --git a/lib/github/appPurposes.ts b/lib/github/appPurposes.ts new file mode 100644 index 000000000..4373de395 --- /dev/null +++ b/lib/github/appPurposes.ts @@ -0,0 +1,277 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { ExecutionEnvironment } from '../../interfaces'; +import { CreateError } from '../transitional'; + +import Debug from 'debug'; +import { GitHubTokenManager } from './tokenManager'; +import GitHubApplication from '../../business/application'; +import { Operations, OperationsCore } from '../../business'; + +const debug = Debug('github:tokens'); + +export enum AppPurpose { + Data = 'Data', + CustomerFacing = 'CustomerFacing', + Operations = 'Operations', + BackgroundJobs = 'BackgroundJobs', // "secondary" / "default" fallback + Updates = 'Updates', + Security = 'Security', + ActionsData = 'ActionsData', +} + +export interface ICustomAppPurpose { + isCustomAppPurpose: boolean; // basic type check + id: string; + name: string; + getForOrganizationName?(organizationName: string): IGitHubAppConfiguration; + getApplicationConfigurationForInitialization?(): IGitHubAppConfiguration; +} + +export type AppPurposeTypes = AppPurpose | ICustomAppPurpose; + +export type CustomAppPurposeWithGetApplications = ICustomAppPurpose & { + getGitHubAppInstances: () => GitHubApplication[]; +}; + +export abstract class CustomAppPurpose implements ICustomAppPurpose { + get isCustomAppPurpose() { + return true; + } + constructor( + public id: string, + public name: string + ) {} +} + +export class CustomAppPurposeOrganizationVariance extends CustomAppPurpose { + private _appsByAppId = new Map(); + + fallbackIfNotConfiguredOrganizationName = false; + + constructor( + private operations: Operations, + public id: string, + public name: string, + private configurations: IGitHubAppConfiguration[] + ) { + super(id, name); + } + + getForOrganizationName(organizationName: string) { + const configuration = this.configurations.find( + (c) => c.specificOrganizationName.toLowerCase() === organizationName.toLowerCase() + ); + if (!configuration && this.fallbackIfNotConfiguredOrganizationName === false) { + throw CreateError.NotFound(`No configuration found for organization ${organizationName}`); + } + return configuration || this.configurations[0]; + } + + getGitHubAppInstances() { + const uniqueAppIds = new Set(this.configurations.map((c) => c.appId).filter((id) => !!id)); + const appInstances: GitHubApplication[] = []; + for (const appId of uniqueAppIds) { + let instance = this._appsByAppId.get(appId); + if (!instance) { + instance = createGitHubAppInstance( + this.operations, + this.configurations.find((c) => c.appId === appId), + this + ); + this._appsByAppId.set(appId, instance); + } + appInstances.push(instance); + } + return appInstances; + } +} + +export class CustomAppPurposeSingleConfiguration extends CustomAppPurpose { + private _appInstance: GitHubApplication; + + constructor( + private operations: Operations, + public id: string, + public name: string, + private configuration: IGitHubAppConfiguration + ) { + super(id, name); + } + + getApplicationConfigurationForInitialization() { + return this.configuration; + } + + getGitHubAppInstances() { + if (!this._appInstance) { + this._appInstance = createGitHubAppInstance(this.operations, this.configuration, this); + } + return this._appInstance; + } +} + +function createGitHubAppInstance( + operations: Operations, + configuration: IGitHubAppConfiguration, + customPurpose: AppPurposeTypes +) { + const app = new GitHubApplication( + operations, + configuration.appId, + configuration.slug, + configuration.description || configuration.slug, + getAppAuthorizationHeader.bind(this, operations, configuration, customPurpose) + ); + return app; +} + +async function getAppAuthorizationHeader( + operations: Operations, + configuration: IGitHubAppConfiguration, + purpose: AppPurposeTypes +): Promise { + const appId = configuration.appId; + const tokenManager = GitHubTokenManager.TryGetTokenManagerForOperations(operations); + const appTokens = await tokenManager.ensureConfigurationAppInitialized(purpose, configuration); + if (!appTokens) { + CreateError.InvalidParameters(`No app tokens found configured for app ID ${appId} in tokens instance.`); + } + const jwt = await appTokens.getAppAuthenticationToken(); + const value = `bearer ${jwt}`; + return value; +} + +export const DefinedAppPurposes = [ + AppPurpose.Data, + AppPurpose.CustomerFacing, + AppPurpose.Operations, + AppPurpose.BackgroundJobs, + AppPurpose.Updates, + AppPurpose.Security, + AppPurpose.ActionsData, +]; + +// export const GitHubAppPurposesExemptFromAllRepositoriesSelection = [AppPurpose.Onboarding]; + +const appPurposeToConfigurationName = { + [AppPurpose.Data]: 'data', + [AppPurpose.CustomerFacing]: 'ui', + [AppPurpose.Operations]: 'operations', + [AppPurpose.BackgroundJobs]: 'jobs', + [AppPurpose.Updates]: 'updates', + [AppPurpose.Security]: 'security', + [AppPurpose.ActionsData]: 'actions', +}; + +export function getAppPurposeId(purpose: AppPurposeTypes) { + if (!purpose) { + return 'n/a'; + } + if ((purpose as ICustomAppPurpose).isCustomAppPurpose === true) { + return (purpose as ICustomAppPurpose).id; + } + const asPurpose = purpose as AppPurpose; + const id = appPurposeToConfigurationName[asPurpose]; + if (!id) { + throw new Error(`No configuration name for purpose ${asPurpose}`); + } + return id; +} + +export function tryGetAppPurposeAppConfiguration(purpose: AppPurposeTypes, organizationName: string) { + if ( + (purpose as ICustomAppPurpose).isCustomAppPurpose === true && + (purpose as ICustomAppPurpose).getForOrganizationName + ) { + return (purpose as ICustomAppPurpose).getForOrganizationName(organizationName); + } +} + +export function tryGetAppPurposeGitHubAppInstances(purpose: AppPurposeTypes) { + if ( + (purpose as ICustomAppPurpose).isCustomAppPurpose === true && + (purpose as CustomAppPurposeWithGetApplications).getGitHubAppInstances + ) { + return (purpose as CustomAppPurposeWithGetApplications).getGitHubAppInstances(); + } + const operations = GitHubAppPurposes.GetOperationsInstanceForBuiltInPurposes(); + const tokenManager = GitHubTokenManager.TryGetTokenManagerForOperations(operations); + const appTokens = tokenManager.getAppForPurpose(purpose); + if (!appTokens) { + throw CreateError.InvalidParameters(`No app tokens found configured for purpose ${purpose}`); + } + const appId = appTokens.appId; + if (!appId) { + throw CreateError.InvalidParameters(`No app ID found configured for purpose ${purpose}`); + } + return [operations.getApplicationById(appId)]; +} + +export class GitHubAppPurposes { + private _operations: Operations; + private static _instance: GitHubAppPurposes = new GitHubAppPurposes(); + + static get AllAvailableAppPurposes() { + debug(`Retrieving all available purposes (${this._instance._purposes.length})`); + return this._instance._purposes; + } + + static RegisterOperationsInstanceForBuiltInPurposes(operations: Operations) { + this._instance._operations = operations; + } + + static GetOperationsInstanceForBuiltInPurposes() { + return this._instance._operations; + } + + static RegisterCustomPurpose(purpose: ICustomAppPurpose) { + debug(`Registering custom purpose ${purpose.id} (${purpose.name})`); + if (purpose.isCustomAppPurpose !== true) { + throw new Error('Purpose must have `isCustomAppPurpose` set to true'); + } + if ( + (this._instance._purposes as ICustomAppPurpose[]) + .filter((p) => (p as ICustomAppPurpose)?.isCustomAppPurpose === true) + .find((p) => p.id === purpose.id) + ) { + throw new Error(`Purpose with ID ${purpose.id} already registered`); + } + this._instance._purposes.push(purpose); + } + + private _purposes: AppPurposeTypes[]; + + constructor() { + this._purposes = [...DefinedAppPurposes]; + } +} + +export enum GitHubAppAuthenticationType { + ForceSpecificInstallation = 'force', + BestAvailable = 'best', +} + +export interface IGitHubAppConfiguration { + clientId?: string; + clientSecret?: string; + appId?: number; + appKey?: string; + appKeyFile?: string; + webhookSecret?: string; + slug?: string; + description?: string; + baseUrl?: string; + + specificOrganizationName?: string; +} + +export interface IGitHubAppsOptions { + operations: OperationsCore; + // app: IReposApplication; + configurations: Map; + executionEnvironment: ExecutionEnvironment; +} diff --git a/business/githubApps/appTokens.ts b/lib/github/appTokens.ts similarity index 76% rename from business/githubApps/appTokens.ts rename to lib/github/appTokens.ts index 7811be3c4..6e75bf780 100644 --- a/business/githubApps/appTokens.ts +++ b/lib/github/appTokens.ts @@ -7,10 +7,11 @@ import { request } from '@octokit/request'; import { createAppAuth, InstallationAccessTokenAuthentication } from '@octokit/auth-app'; import { AppAuthentication, AuthInterface } from '@octokit/auth-app/dist-types/types'; -import { AppPurposeTypes, ICustomAppPurpose } from '.'; -import { IAuthorizationHeaderValue } from '../../interfaces'; +import { AppPurposeTypes, ICustomAppPurpose } from './appPurposes'; +import { AuthorizationHeaderValue } from '../../interfaces'; import Debug from 'debug'; +import { CreateError } from '../transitional'; const debug = Debug('github:tokens'); interface IInstallationToken { @@ -27,6 +28,45 @@ interface IInstallationToken { const InstallationTokenLifetimeMilliseconds = 1000 * 60 * 60; const ValidityOffsetAfterNowMilliseconds = 1000 * 120; // how long to require validity in the future +export enum GitHubTokenType { + PersonalAccessToken = 'ghp', + OAuthAccessToken = 'gho', + UserToServerToken = 'ghu', + ServerToServerToken = 'ghs', + RefreshToken = 'ghr', + FineGrainedPersonalAccessToken = 'github_pat', +} + +export const GitHubTokenTypes = [ + GitHubTokenType.PersonalAccessToken, + GitHubTokenType.OAuthAccessToken, + GitHubTokenType.UserToServerToken, + GitHubTokenType.ServerToServerToken, + GitHubTokenType.RefreshToken, + GitHubTokenType.FineGrainedPersonalAccessToken, +]; + +export function getGitHubTokenTypeFromValue(value: string | AuthorizationHeaderValue): GitHubTokenType { + if (!value) { + throw CreateError.ParameterRequired('value'); + } + if (typeof value === 'object') { + value = value.value; + } else if (typeof value !== 'string') { + throw CreateError.InvalidParameters('value must be a string or AuthorizationHeaderValue'); + } + if (!value.startsWith('token ')) { + throw CreateError.InvalidParameters('value must start with "token "'); + } + const tokenValue = value.substr(6); + for (const tokenType of GitHubTokenTypes) { + if (tokenValue.startsWith(tokenType)) { + return tokenType; + } + } + throw CreateError.InvalidParameters('value does not appear to be a GitHub token'); +} + export class GitHubAppTokens { #privateKey: string; private _appId: number; @@ -39,23 +79,25 @@ export class GitHubAppTokens { static CreateFromBase64EncodedFileString( purpose: AppPurposeTypes, + slug: string, friendlyName: string, applicationId: number, fileContents: string, baseUrl?: string ): GitHubAppTokens { const keyContents = Buffer.from(fileContents, 'base64').toString('utf8').replace(/\r\n/g, '\n'); - return new GitHubAppTokens(purpose, friendlyName, applicationId, keyContents, baseUrl); + return new GitHubAppTokens(purpose, slug, friendlyName, applicationId, keyContents, baseUrl); } static CreateFromString( purpose: AppPurposeTypes, + slug: string, friendlyName: string, applicationId: number, value: string, baseUrl?: string ): GitHubAppTokens { - return new GitHubAppTokens(purpose, friendlyName, applicationId, value, baseUrl); + return new GitHubAppTokens(purpose, slug, friendlyName, applicationId, value, baseUrl); } get appId() { @@ -68,6 +110,7 @@ export class GitHubAppTokens { constructor( purpose: AppPurposeTypes, + public slug: string, public friendlyName: string, appId: number, privateKey: string, @@ -114,7 +157,7 @@ export class GitHubAppTokens { async getInstallationToken( installationId: number, organizationName: string - ): Promise { + ): Promise { const now = new Date(); const requiredValidityPeriod = new Date(now.getTime() + ValidityOffsetAfterNowMilliseconds); const latestToken = this.getLatestValidToken(installationId, requiredValidityPeriod); @@ -213,8 +256,12 @@ function sortByLatestToken(a: IInstallationToken, b: IInstallationToken) { function tokenValidFilter(timeTokenMustBeValid: Date, token: IInstallationToken) { const isValid = token.expires > timeTokenMustBeValid; if (!isValid) { + const header = token.headerValue.substr(6); + const subset = (header.length > 12 ? header.substr(0, 8) : '') + '*'.repeat(4); console.log( - `invalid or expired token being removed: expires=${token.expires} install_id=${token.installationId} org=${token.organizationName}` + `token expired: redacted=${subset}, expires=${token.expires.toISOString()}, install_id=${ + token.installationId + }, org=${token.organizationName}` ); return false; } diff --git a/lib/github/collections.ts b/lib/github/collections.ts index cb18c7215..228ac649c 100644 --- a/lib/github/collections.ts +++ b/lib/github/collections.ts @@ -9,20 +9,30 @@ import Debug from 'debug'; const debug = Debug.debug('restapi'); import cost from './cost'; -import { IRestResponse, flattenData } from './core'; +import { RestResponse, flattenData } from './core'; import { CompositeApiContext, CompositeIntelligentEngine } from './composite'; import { Collaborator } from '../../business/collaborator'; import { Team } from '../../business/team'; -import { IPagedCacheOptions, IGetAuthorizationHeader, IDictionary } from '../../interfaces'; +import { IPagedCacheOptions, GetAuthorizationHeader, IDictionary } from '../../interfaces'; import { RestLibrary } from '.'; -import { sleep } from '../../utils'; +import { sleep } from '../utils'; import GitHubApplication from '../../business/application'; import { RepositoryPrimaryProperties } from '../../business/primaryProperties'; +import { RepositoryInvitation } from '../../business/repositoryInvitation'; export interface IGetAppInstallationsParameters { app_id: string; } +type WithPage = T & { page?: number }; + +type WithOctokitRequest = T & { octokitRequest?: string }; + +export type CollectionCopilotSeatsOptions = { + org: string; + per_page?: number; +}; + export enum GitHubPullRequestState { Open = 'open', Closed = 'closed', @@ -51,23 +61,45 @@ export interface IListPullsParameters { direction?: GitHubSortDirection; } +const mostBasicAccountProperties = ['id', 'login', 'avatar_url']; + const branchDetailsToCopy = ['name', 'commit', 'protected']; const repoDetailsToCopy = RepositoryPrimaryProperties; const teamDetailsToCopy = Team.PrimaryProperties; const memberDetailsToCopy = Collaborator.PrimaryProperties; const appInstallDetailsToCopy = GitHubApplication.PrimaryInstallationProperties; const contributorsDetailsToCopy = [...Collaborator.PrimaryProperties, 'contributions']; +const repoInviteDetailsToCopy = RepositoryInvitation.PrimaryProperties; -const teamPermissionsToCopy = [ - 'id', +type SubReducerProperties = Record; + +type WithSubPropertyReducer = any[] & { subPropertiesToReduce?: SubReducerProperties }; + +const copilotSeatPropertiesToCopy: WithSubPropertyReducer = [ + 'created_at', + 'updated_at', + 'last_activity_at', + 'last_activity_editor', + 'assignee', // id, login; mostBasicAccountProperties +]; +copilotSeatPropertiesToCopy.subPropertiesToReduce = { + assignee: mostBasicAccountProperties, +}; + +const teamPermissionsToCopyForRepository = [ 'name', + 'id', 'slug', 'description', - 'members_count', - 'repos_count', + // 'members_count', + // 'repos_count', 'privacy', - 'permission', + // 'notification_setting', + 'permission', // custom role name at times + 'permissions', // array of booleans for admin, maintain, push, triage, pull + 'parent', // large object for a parent team, if present ]; + const teamRepoPermissionsToCopy = [ 'id', 'name', @@ -76,7 +108,9 @@ const teamRepoPermissionsToCopy = [ 'private', 'fork', 'permissions', + 'role_name', ]; + const pullDetailsToCopy = [ 'id', 'number', @@ -123,8 +157,56 @@ export class RestCollections { this.githubCall = githubCall; } + collectAllPages( + token: string | GetAuthorizationHeader, + collectionCacheKey: string, + octokitApiName: string, + parameters: ParametersType, + cacheOptions: IPagedCacheOptions, + fieldNamesToKeep?: string[] | WithSubPropertyReducer, + arrayReducePropertyName?: string + ): Promise { + return this.generalizedCollectionWithFilter( + collectionCacheKey, + octokitApiName, + fieldNamesToKeep, + token, + parameters, + cacheOptions, + arrayReducePropertyName + ); + } + + collectAllPagesViaHttpGet( + token: string | GetAuthorizationHeader, + collectionCacheKey: string, + getRestUrl: string, + parameters: ParametersType, + cacheOptions: IPagedCacheOptions, + fieldNamesToKeep?: string[] | WithSubPropertyReducer, + arrayReducePropertyName?: string + ): Promise { + const expandedOptions: WithOctokitRequest = Object.assign( + { + octokitRequest: getRestUrl.startsWith('GET ') ? getRestUrl.substr(4) : getRestUrl, + }, + parameters + ); + return this.collectAllPages( + token, + collectionCacheKey, + 'request', + expandedOptions, + cacheOptions, + fieldNamesToKeep, + arrayReducePropertyName + ); + } + + // --- + getOrgRepos( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -139,7 +221,7 @@ export class RestCollections { } getOrgTeams( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -154,7 +236,7 @@ export class RestCollections { } getTeamChildTeams( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -169,7 +251,7 @@ export class RestCollections { } getUserActivity( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -184,7 +266,7 @@ export class RestCollections { } getOrgMembers( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -198,8 +280,33 @@ export class RestCollections { ); } + getOrganizationCopilotSeats( + token: string | GetAuthorizationHeader, + options: CollectionCopilotSeatsOptions, + cacheOptions: IPagedCacheOptions + ): Promise { + // technically type CopilotSeatData + const orgName = options.org; + delete options.org; + const params = Object.assign( + { + octokitRequest: `GET /orgs/${orgName}/copilot/billing/seats`, + }, + options + ); + return this.generalizedCollectionWithFilter( + 'orgCopilotSeats', + 'request', + copilotSeatPropertiesToCopy, + token, + params, + cacheOptions, + 'seats' + ); + } + getAppInstallations( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, parameters: IGetAppInstallationsParameters, cacheOptions: IPagedCacheOptions ): Promise { @@ -220,7 +327,7 @@ export class RestCollections { } getRepoIssues( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -235,7 +342,7 @@ export class RestCollections { } getRepoProjects( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -250,14 +357,14 @@ export class RestCollections { } getRepoTeams( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { return this.generalizedCollectionWithFilter( 'repoTeamPermissions', 'repos.listTeams', - teamPermissionsToCopy, + teamPermissionsToCopyForRepository, token, options, cacheOptions @@ -265,7 +372,7 @@ export class RestCollections { } getRepoContributors( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -280,7 +387,7 @@ export class RestCollections { } getRepoCollaborators( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -294,8 +401,23 @@ export class RestCollections { ); } + getRepoInvitations( + token: string | GetAuthorizationHeader, + options, + cacheOptions: IPagedCacheOptions + ): Promise { + return this.generalizedCollectionWithFilter( + 'repoInvitations', + 'repos.listInvitations', + repoInviteDetailsToCopy, + token, + options, + cacheOptions + ); + } + getRepoBranches( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -310,7 +432,7 @@ export class RestCollections { } getRepoPullRequests( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options: IListPullsParameters, cacheOptions: IPagedCacheOptions ): Promise { @@ -325,7 +447,7 @@ export class RestCollections { } getTeamMembers( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -340,7 +462,7 @@ export class RestCollections { } getTeamRepos( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, options, cacheOptions: IPagedCacheOptions ): Promise { @@ -354,11 +476,12 @@ export class RestCollections { ); } - private async getGithubCollection( - token: string | IGetAuthorizationHeader, - methodName, - options, - cacheOptions: IPagedCacheOptions + private async getGithubCollection( + token: string | GetAuthorizationHeader, + methodName: string, + options: OptionsType, + cacheOptions: IPagedCacheOptions, + arrayReducePropertyName?: string ): Promise { const hasNextPage = this.libraryContext.hasNextPage; const githubCall = this.githubCall; @@ -368,14 +491,14 @@ export class RestCollections { const requests = []; let pages = 0; let currentPage = 0; - const pageLimit = options.pageLimit || cacheOptions['pageLimit'] || Number.MAX_VALUE; + const pageLimit = (options as any)?.pageLimit || cacheOptions['pageLimit'] || Number.MAX_VALUE; const pageRequestDelay = cacheOptions.pageRequestDelay || null; while (!done) { const method = githubCall; const args = []; const currentToken = typeof token === 'string' ? token : await token(); args.push(currentToken); - const clonedOptions = Object.assign({}, options); + const clonedOptions: WithPage = Object.assign({}, options); if (++currentPage > 1) { clonedOptions.page = currentPage; } @@ -384,6 +507,19 @@ export class RestCollections { let result = null; try { result = await (method as any).apply(null, args); + if ( + arrayReducePropertyName && + result[arrayReducePropertyName] && + Array.isArray(result[arrayReducePropertyName]) + ) { + const originalResultProperties = { + headers: result?.headers, + cost: result?.cost, + }; + result = result[arrayReducePropertyName]; + result.headers = originalResultProperties.headers; + result.cost = originalResultProperties.cost; + } recentResult = result; if (result) { ++pages; @@ -432,17 +568,26 @@ export class RestCollections { return { data, requests }; } - private async getFilteredGithubCollection( - token: string | IGetAuthorizationHeader, - methodName, - options, + private async getFilteredGithubCollection( + token: string | GetAuthorizationHeader, + methodName: string, + options: OptionsType, cacheOptions: IPagedCacheOptions, - propertiesToKeep + propertiesToKeep: string[], + arrayReducePropertyName?: string ): Promise { const keepAll = !propertiesToKeep; + const subReductionProperties = + propertiesToKeep && (propertiesToKeep as WithSubPropertyReducer).subPropertiesToReduce; try { // IRequestWithData - const getCollectionResponse = await this.getGithubCollection(token, methodName, options, cacheOptions); + const getCollectionResponse = await this.getGithubCollection( + token, + methodName, + options, + cacheOptions, + arrayReducePropertyName + ); if (!getCollectionResponse) { throw new Error('No response'); } @@ -462,6 +607,14 @@ export class RestCollections { const r = {}; _.forOwn(doNotModify, (value, key) => { if (keepAll || propertiesToKeep.indexOf(key) >= 0) { + if (subReductionProperties && subReductionProperties[key]) { + const validSubKeys = new Set(subReductionProperties[key]); + for (const subKey of Object.getOwnPropertyNames(value)) { + if (!validSubKeys.has(subKey)) { + delete value[subKey]; + } + } + } r[key] = value; } }); @@ -480,21 +633,23 @@ export class RestCollections { } } - private async getFilteredGithubCollectionWithMetadataAnalysis( - token: string | IGetAuthorizationHeader, - methodName, - options, + private async getFilteredGithubCollectionWithMetadataAnalysis( + token: string | GetAuthorizationHeader, + methodName: string, + options: OptionsType, cacheOptions: IPagedCacheOptions, - propertiesToKeep - ): Promise { - const collectionResults = await this.getFilteredGithubCollection( + propertiesToKeep: string[], + arrayReducePropertyName?: string + ): Promise { + const collectionResults = await this.getFilteredGithubCollection( token, methodName, options, cacheOptions, - propertiesToKeep + propertiesToKeep, + arrayReducePropertyName ); - const results = collectionResults.data as IRestResponse; + const results = collectionResults.data as RestResponse; const requests = collectionResults.requests; const pages = []; let dirty = false; @@ -531,12 +686,12 @@ export class RestCollections { } private generalizedCollectionMethod( - token: string | IGetAuthorizationHeader, + token: string | GetAuthorizationHeader, apiName: string, method, options, cacheOptions: IPagedCacheOptions - ): Promise { + ): Promise { const apiContext = new CompositeApiContext(apiName, method, options); apiContext.maxAgeSeconds = cacheOptions.maxAgeSeconds || 600; apiContext.overrideToken(token); @@ -548,37 +703,47 @@ export class RestCollections { return compositeEngine.execute(apiContext); } - private getCollectionAndFilter( - token: string | IGetAuthorizationHeader, - options, + private getCollectionAndFilter( + token: string | GetAuthorizationHeader, + options: OptionsType, cacheOptions: IPagedCacheOptions, - githubClientMethod, - propertiesToKeep + githubClientMethod: string, + propertiesToKeep: string[], + arrayReducePropertyName?: string ) { const capturedThis = this; - return function (token, options) { - return capturedThis.getFilteredGithubCollectionWithMetadataAnalysis( + return function (token: string | GetAuthorizationHeader, options: OptionsType) { + return capturedThis.getFilteredGithubCollectionWithMetadataAnalysis( token, githubClientMethod, options, cacheOptions, - propertiesToKeep + propertiesToKeep, + arrayReducePropertyName ); }; } - private async generalizedCollectionWithFilter( - name, - githubClientMethod, - propertiesToKeep, - token, - options, - cacheOptions: IPagedCacheOptions - ): Promise { + private async generalizedCollectionWithFilter( + name: string, + githubClientMethod: string, + propertiesToKeep: string[], + token: string | GetAuthorizationHeader, + options: OptionsType, + cacheOptions: IPagedCacheOptions, + arrayReducePropertyName?: string + ): Promise { const rows = await this.generalizedCollectionMethod( token, name, - this.getCollectionAndFilter(token, options, cacheOptions, githubClientMethod, propertiesToKeep), + this.getCollectionAndFilter( + token, + options, + cacheOptions, + githubClientMethod, + propertiesToKeep, + arrayReducePropertyName + ), options, cacheOptions ); diff --git a/lib/github/composite.ts b/lib/github/composite.ts index ab9ae1d6a..21bfa9551 100644 --- a/lib/github/composite.ts +++ b/lib/github/composite.ts @@ -13,16 +13,16 @@ import Debug from 'debug'; const debug = Debug.debug('restapi'); import { - IShouldServeCache, + ShouldServeCache, ApiContext, IntelligentEngine, IApiContextRedisKeys, IApiContextCacheValues, ApiContextType, - IRestMetadata, - IRestResponse, + RestMetadata, + RestResponse, } from './core'; -import { IGetAuthorizationHeader } from '../../interfaces'; +import { GetAuthorizationHeader } from '../../interfaces'; import appPackage from '../../package.json'; @@ -34,7 +34,7 @@ const acceleratedExpirationMinutes = 60; // 1 hour export class CompositeApiContext extends ApiContext { private _apiMethod: any; private _apiTypePrefix: string; - private _token: string | IGetAuthorizationHeader; + private _token: string | GetAuthorizationHeader; private _cacheValues: IApiContextCacheValues; private _redisKeys: IApiContextRedisKeys; @@ -74,11 +74,11 @@ export class CompositeApiContext extends ApiContext { return this._cacheValues; } - get token(): string | IGetAuthorizationHeader { + get token(): string | GetAuthorizationHeader { return this._token; } - overrideToken(token: string | IGetAuthorizationHeader) { + overrideToken(token: string | GetAuthorizationHeader) { this._token = token; } @@ -98,12 +98,12 @@ export class CompositeApiContext extends ApiContext { export class CompositeIntelligentEngine extends IntelligentEngine { withMetadataShouldCacheBeServed( apiContext: ApiContext, - metadata: IRestMetadata - ): boolean | IShouldServeCache { + metadata: RestMetadata + ): boolean | ShouldServeCache { // result can be falsy OR an object; { cache: true, refresh: true } // cache: whether to use the cache, if available // refresh: whether to refresh in the background for a newer value - let shouldServeCache: IShouldServeCache | boolean = false; + let shouldServeCache: ShouldServeCache | boolean = false; const maxAgeSeconds = apiContext.maxAgeSeconds; const updatedIso = metadata ? metadata.updated : null; const refreshingIso = metadata ? metadata.refreshing : null; @@ -173,7 +173,7 @@ export class CompositeIntelligentEngine extends IntelligentEngine { return shouldServeCache; } - withResponseShouldCacheBeServed(apiContext: ApiContext, response: IRestResponse) { + withResponseShouldCacheBeServed(apiContext: ApiContext, response: RestResponse) { if (typeof response === 'function') { throw new Error('The response must not be a function'); } @@ -198,16 +198,16 @@ export class CompositeIntelligentEngine extends IntelligentEngine { return shouldUseCache; } - optionalStripResponse(apiContext: ApiContext, response: IRestResponse): IRestResponse { + optionalStripResponse(apiContext: ApiContext, response: RestResponse): RestResponse { // Composite does not strip any results further before caching return response; } - withResponseUpdateMetadata(apiContext: ApiContext, response: IRestResponse) { + withResponseUpdateMetadata(apiContext: ApiContext, response: RestResponse) { return response; } - reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: IRestResponse) { + reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: RestResponse) { // No reduction for object type metadata. // Store the app version in case it is needed for a future // schema update or cache invalidation @@ -217,7 +217,7 @@ export class CompositeIntelligentEngine extends IntelligentEngine { } } - async callApi(apiContext: CompositeApiContext): Promise { + async callApi(apiContext: CompositeApiContext): Promise { const args = []; const apiMethod = apiContext.apiMethod; if (apiContext.token) { @@ -232,10 +232,10 @@ export class CompositeIntelligentEngine extends IntelligentEngine { } catch (applyError) { throw applyError; } - return unknown as IRestResponse; + return unknown as RestResponse; } - getResponseMetadata(apiContext: CompositeApiContext, response: IRestResponse): IRestMetadata { + getResponseMetadata(apiContext: CompositeApiContext, response: RestResponse): RestMetadata { const headers = response.headers || {}; const calledTime = apiContext.calledTime ? apiContext.calledTime.toISOString() : new Date().toISOString(); headers.updated = calledTime; @@ -251,7 +251,7 @@ export class CompositeIntelligentEngine extends IntelligentEngine { return headers; } - processMetadataBeforeCall(apiContext: CompositeApiContext, metadata: IRestMetadata) { + processMetadataBeforeCall(apiContext: CompositeApiContext, metadata: RestMetadata) { if (metadata && !metadata.av) { // Old version of metadata, no package version, which is required for all composite metadata now metadata = undefined; diff --git a/lib/github/core.ts b/lib/github/core.ts index 94acc778f..2dbc8cd43 100644 --- a/lib/github/core.ts +++ b/lib/github/core.ts @@ -8,11 +8,11 @@ import { randomUUID } from 'crypto'; import moment from 'moment'; import { RestLibrary } from '.'; -import { IAuthorizationHeaderValue } from '../../interfaces'; -import { sleep } from '../../utils'; +import { AuthorizationHeaderValue } from '../../interfaces'; +import { sleep } from '../utils'; import cost from './cost'; -import { ErrorHelper } from '../../transitional'; +import { ErrorHelper } from '../transitional'; import Debug from 'debug'; const debug = Debug.debug('restapi'); @@ -43,7 +43,7 @@ const headerKeysWanted = [ 'x-ratelimit-used', ]; -export interface IInterestingHeaders { +export type GitHubRestInterestingHeaders = { etag?: string; ['last-modified']?: string; ['x-github-request-id']?: string; @@ -51,9 +51,13 @@ export interface IInterestingHeaders { ['x-ratelimit-remaining']?: string; ['x-ratelimit-reset']?: string; ['x-ratelimit-used']?: string; -} +}; + +export type WithGitHubRestHeaders = T & { + headers?: GitHubRestInterestingHeaders; +}; -export interface ISpecializedCollectionHeaders { +export type GitHubRestSpecializedCollectionHeaders = { // really, these are the metadata fields, no headers at all... dirty?: boolean; pages?: string[]; @@ -63,34 +67,34 @@ export interface ISpecializedCollectionHeaders { updated?: string; changed?: string; ['last-modified']?: string; -} +}; -export interface IRestMetadata { +export type RestMetadata = { etag?: string; av?: string; updated?: string; changed?: string; refreshing?: string; - headers?: ISpecializedCollectionHeaders; // IDictionary; + headers?: GitHubRestSpecializedCollectionHeaders; // IDictionary; status?: number; pages?: string[]; -} +}; -export interface IRestResponse { - headers?: ISpecializedCollectionHeaders; +export type RestResponse = { + headers?: GitHubRestSpecializedCollectionHeaders; status?: number; data: unknown; cost?: unknown; notModified?: boolean; -} +}; -export interface IIntelligentCacheResponseArray extends Array, IRestResponse {} +export interface IIntelligentCacheResponseArray extends Array, RestResponse {} -export interface IShouldServeCache { +export type ShouldServeCache = { cache?: boolean; remaining?: string; refresh?: boolean; -} +}; export abstract class ApiContext { private _log: string[]; @@ -99,7 +103,7 @@ export abstract class ApiContext { libraryContext: RestLibrary; etag?: string; - tokenSource: IAuthorizationHeaderValue; + tokenSource: AuthorizationHeaderValue; abstract get apiTypePrefix(): string; abstract get cacheValues(): IApiContextCacheValues; @@ -122,7 +126,10 @@ export abstract class ApiContext { return this._cost; } - constructor(public api: any, public options: any) { + constructor( + public api: any, + public options: any + ) { this._log = []; if (!this._calledTime) { this._calledTime = new Date(); @@ -135,7 +142,7 @@ export abstract class ApiContext { maxAgeSeconds?: number; backgroundRefresh?: boolean; - metadata?: IRestMetadata; + metadata?: RestMetadata; generatedRefreshId?: string; } @@ -164,23 +171,23 @@ export abstract class IntelligentEngine { } // was in api context: - abstract processMetadataBeforeCall(apiContext: ApiContext, metadata: IRestMetadata): IRestMetadata; - abstract callApi(apiContext: ApiContext, optionalMessage?: string): Promise; - abstract withResponseUpdateMetadata(apiContext: ApiContext, response: IRestResponse): IRestResponse; + abstract processMetadataBeforeCall(apiContext: ApiContext, metadata: RestMetadata): RestMetadata; + abstract callApi(apiContext: ApiContext, optionalMessage?: string): Promise; + abstract withResponseUpdateMetadata(apiContext: ApiContext, response: RestResponse): RestResponse; abstract withResponseShouldCacheBeServed( apiContext: ApiContext, - response: IRestResponse - ): boolean | IShouldServeCache; + response: RestResponse + ): boolean | ShouldServeCache; abstract withMetadataShouldCacheBeServed( apiContext: ApiContext, - metadata: IRestMetadata - ): boolean | IShouldServeCache; - abstract reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: IRestResponse): IRestMetadata; - abstract getResponseMetadata(apiContext: ApiContext, response: IRestResponse): IRestMetadata; - abstract optionalStripResponse(apiContext: ApiContext, response: IRestResponse): IRestResponse; + metadata: RestMetadata + ): boolean | ShouldServeCache; + abstract reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: RestResponse): RestMetadata; + abstract getResponseMetadata(apiContext: ApiContext, response: RestResponse): RestMetadata; + abstract optionalStripResponse(apiContext: ApiContext, response: RestResponse): RestResponse; - protected async cacheResponseAsync(apiContext: ApiContext, response: IRestResponse) { + protected async cacheResponseAsync(apiContext: ApiContext, response: RestResponse) { const backgroundAsyncWork = async () => { try { await this.storeResult(apiContext, response); @@ -197,7 +204,7 @@ export abstract class IntelligentEngine { return this.finalizeResult(apiContext, response); } - protected finalizeResult(apiContext: ApiContext, response: IRestResponse): IRestResponse { + protected finalizeResult(apiContext: ApiContext, response: RestResponse): RestResponse { if (!response || !response.data) { // This was a warning in the past, but to try and improve the underlying library, this should be an error if (response.headers.av) { @@ -218,11 +225,9 @@ export abstract class IntelligentEngine { return response; } - protected async tryGetCachedResult(apiContext: ApiContext): Promise { + protected async tryGetCachedResult(apiContext: ApiContext): Promise { const key = this.redisKeyBodyVersion(apiContext); - const response = (await apiContext.libraryContext.cacheProvider.getObjectCompressed( - key - )) as IRestResponse; + const response = (await apiContext.libraryContext.cacheProvider.getObjectCompressed(key)) as RestResponse; this.recordRedisCost(apiContext, 'get', response); return response; } @@ -230,8 +235,8 @@ export abstract class IntelligentEngine { protected async getCachedResult( apiContext: ApiContext, optionalCacheDecisions?, - notModifiedHeaders?: IInterestingHeaders - ): Promise { + notModifiedHeaders?: GitHubRestInterestingHeaders + ): Promise { const result = await this.tryGetCachedResult(apiContext); if (result && result.data) { // use the context metadata over any headers in the stored response, + any headers from 304 @@ -310,7 +315,7 @@ export abstract class IntelligentEngine { protected async reduceObjectExpirationWindow( apiContext: ApiContext, - response: IRestResponse + response: RestResponse ): Promise { if (!apiContext.etag || (apiContext.etag && apiContext.etag === response.headers.etag)) { return; @@ -345,7 +350,7 @@ export abstract class IntelligentEngine { this.recordRedisCost(apiContext, 'expire', cost); } - protected async storeMetadata(apiContext: ApiContext, response: IRestResponse): Promise { + protected async storeMetadata(apiContext: ApiContext, response: RestResponse): Promise { const reducedMetadata = this.reduceMetadataToCacheFromResponse(apiContext, response); const cost = await apiContext.libraryContext.cacheProvider.setObjectWithExpire( apiContext.redisKey.metadata, @@ -355,7 +360,7 @@ export abstract class IntelligentEngine { this.recordRedisCost(apiContext, 'set', cost); } - protected async storeResult(apiContext: ApiContext, response: IRestResponse): Promise { + protected async storeResult(apiContext: ApiContext, response: RestResponse): Promise { let key = null; try { key = this.redisKeyBodyVersion(apiContext, response.headers.etag); @@ -399,23 +404,23 @@ export abstract class IntelligentEngine { return object; } - public async execute(apiContext: ApiContext): Promise { + public async execute(apiContext: ApiContext): Promise { let metadata = await this.getCachedMetadata(apiContext); metadata = this.processMetadataBeforeCall(apiContext, metadata); - const shouldCacheBeServedImmediately: boolean | IShouldServeCache = this.withMetadataShouldCacheBeServed( + const shouldCacheBeServedImmediately: boolean | ShouldServeCache = this.withMetadataShouldCacheBeServed( apiContext, metadata ); const displayKey = apiContext.redisKey ? apiContext.redisKey.root + ' ' : ''; if ( shouldCacheBeServedImmediately === true || - (shouldCacheBeServedImmediately as IShouldServeCache).cache === true + (shouldCacheBeServedImmediately as ShouldServeCache).cache === true ) { debug('Cache should be served immediately.'); if (metadata) { const innerMessage = - shouldCacheBeServedImmediately && (shouldCacheBeServedImmediately as IShouldServeCache).remaining - ? (shouldCacheBeServedImmediately as IShouldServeCache).remaining + shouldCacheBeServedImmediately && (shouldCacheBeServedImmediately as ShouldServeCache).remaining + ? (shouldCacheBeServedImmediately as ShouldServeCache).remaining : ''; debug(`Cache ${displayKey}data: ${innerMessage}`); } @@ -429,9 +434,9 @@ export abstract class IntelligentEngine { await sleep(delayBeforeRefreshMilliseconds); } debug('Directly calling the function or REST API'); - let response: IRestResponse = undefined; + let response: RestResponse = undefined; try { - response = (await this.callApi(apiContext, `GET: ${displayKey}`)) as IRestResponse; + response = (await this.callApi(apiContext, `GET: ${displayKey}`)) as RestResponse; } catch (error) { if (error && error.status && error.status === 304) { const liveHeaders = error.response?.headers || {}; @@ -452,7 +457,7 @@ export abstract class IntelligentEngine { return response; } - private async processResponse(apiContext: ApiContext, response: IRestResponse): Promise { + private async processResponse(apiContext: ApiContext, response: RestResponse): Promise { this.withResponseUpdateMetadata(apiContext, response); const isCacheOk = this.withResponseShouldCacheBeServed(apiContext, response); if (isCacheOk === true) { @@ -474,7 +479,7 @@ export abstract class IntelligentEngine { } } - private async getCachedMetadata(apiContext: ApiContext): Promise { + private async getCachedMetadata(apiContext: ApiContext): Promise { if (apiContext.metadata || apiContext.etag) { debug('Shortcut: apiContext.metadata or apiContext.etag are set'); return; @@ -483,9 +488,9 @@ export abstract class IntelligentEngine { if (!redisKey) { throw new Error('No Redis key provided in apiContext.redisKey.metadata'); } - const cachedMetadata: IRestMetadata = (await apiContext.libraryContext.cacheProvider.getObject( + const cachedMetadata: RestMetadata = (await apiContext.libraryContext.cacheProvider.getObject( redisKey - )) as IRestMetadata; + )) as RestMetadata; // debug('Cached metadata retrieved'); this.recordRedisCost(apiContext, 'get', cachedMetadata); return cachedMetadata; diff --git a/lib/github/crossOrganization.ts b/lib/github/crossOrganization.ts index a1e72dde1..4024d0d17 100644 --- a/lib/github/crossOrganization.ts +++ b/lib/github/crossOrganization.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IRestResponse, IIntelligentCacheResponseArray, flattenData } from './core'; +import { RestResponse, IIntelligentCacheResponseArray, flattenData } from './core'; import { CompositeApiContext } from './composite'; import { RestLibrary } from '.'; import { RestCollections } from './collections'; @@ -11,16 +11,16 @@ import { ICacheOptions, IGetOrganizationMembersOptions, IPagedCrossOrganizationCacheOptions, - IPurposefulGetAuthorizationHeader, + PurposefulGetAuthorizationHeader, ITeamMembershipOptions, } from '../../interfaces'; -import { AppPurpose } from '../../business/githubApps'; +import { AppPurpose } from './appPurposes'; -interface IOrganizationsResponse extends IRestResponse { +interface IOrganizationsResponse extends RestResponse { orgs?: any; } -interface ICrossOrganizationDataResponse extends IRestResponse { +interface ICrossOrganizationDataResponse extends RestResponse { // data?: any; } @@ -42,7 +42,7 @@ export class CrossOrganizationCollator { } async orgMembers( - orgsAndTokens: Map, + orgsAndTokens: Map, options: IGetOrganizationMembersOptions, cacheOptions: ICacheOptions ): Promise { @@ -57,13 +57,13 @@ export class CrossOrganizationCollator { return flattenData(data); } - async teams(orgsAndTokens: Map, options, cacheOptions) { + async teams(orgsAndTokens: Map, options, cacheOptions) { const allTeams = await this.getAllTeams(orgsAndTokens, options, cacheOptions); return flattenData(allTeams); } async teamMembers( - orgsAndTokens: Map, + orgsAndTokens: Map, options: ITeamMembershipOptions, cacheOptions: ICacheOptions ): Promise { @@ -90,7 +90,7 @@ export class CrossOrganizationCollator { } async repos( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: ICacheOptions ): Promise { @@ -99,7 +99,7 @@ export class CrossOrganizationCollator { } async repoCollaborators( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: ICacheOptions ): Promise { @@ -126,7 +126,7 @@ export class CrossOrganizationCollator { } async repoTeams( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: ICacheOptions ): Promise { @@ -173,7 +173,7 @@ export class CrossOrganizationCollator { } private async getCrossOrganizationMethod( - orgsAndTokens: Map, + orgsAndTokens: Map, apiName: string, methodName: string, options, @@ -242,7 +242,7 @@ export class CrossOrganizationCollator { private crossOrganizationCollection( capturedThis: CrossOrganizationCollator, - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: IPagedCrossOrganizationCacheOptions, innerKeyType, @@ -303,7 +303,7 @@ export class CrossOrganizationCollator { const localOptions = Object.assign(localOptionsTarget, options); delete localOptions.maxAgeSeconds; delete localOptions.backgroundRefresh; - const token = orgsAndTokens.get(orgName.toLowerCase()) as IPurposefulGetAuthorizationHeader; + const token = orgsAndTokens.get(orgName.toLowerCase()) as PurposefulGetAuthorizationHeader; if (!token) { throw new Error(`No token available for the organization ${orgName}`); } @@ -348,7 +348,7 @@ export class CrossOrganizationCollator { } private async getAllTeams( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: IPagedCrossOrganizationCacheOptions ): Promise { @@ -364,7 +364,7 @@ export class CrossOrganizationCollator { } private async getAllRepos( - orgsAndTokens: Map, + orgsAndTokens: Map, options, cacheOptions: IPagedCrossOrganizationCacheOptions ): Promise { diff --git a/lib/github/index.ts b/lib/github/index.ts index 923b0fc81..f9269ca6a 100644 --- a/lib/github/index.ts +++ b/lib/github/index.ts @@ -13,17 +13,26 @@ import { CompositeIntelligentEngine } from './composite'; import { RestCollections } from './collections'; import { CrossOrganizationCollator } from './crossOrganization'; import { LinkMethods } from './links'; -import { IGetAuthorizationHeader, IAuthorizationHeaderValue } from '../../interfaces'; +import { GetAuthorizationHeader, AuthorizationHeaderValue } from '../../interfaces'; import { ICacheHelper } from '../caching'; -import { ICustomAppPurpose } from '../../business/githubApps'; +import { ICustomAppPurpose } from './appPurposes'; +import { CreateError } from '../transitional'; export enum CacheMode { ValidateCache = 'ValidateCache', BackgroundRefresh = 'BackgroundRefresh', } +export enum HttpMethod { + Get = 'GET', + Post = 'POST', + Put = 'PUT', + Patch = 'PATCH', + Delete = 'DELETE', +} + export interface IGitHubPostFunction { - (awaitToken: IGetAuthorizationHeader, api: string, parameters: any): Promise; + (awaitToken: GetAuthorizationHeader, api: string, parameters: any): Promise; } export type OctokitGraphqlOptions = { @@ -128,25 +137,27 @@ export class RestLibrary { hasNextPage?: (any) => boolean; private async resolveAuthorizationHeader( - authorizationHeader: IGetAuthorizationHeader | IAuthorizationHeaderValue | string - ): Promise { + authorizationHeader: GetAuthorizationHeader | AuthorizationHeaderValue | string + ): Promise { let authorizationValue = null; try { - if (typeof authorizationHeader === 'string') { + if (!authorizationHeader) { + throw CreateError.InvalidParameters('No authorization header'); + } else if (typeof authorizationHeader === 'string') { authorizationValue = authorizationHeader as string; } else if (typeof authorizationHeader === 'function') { - let asFunc = authorizationHeader as IGetAuthorizationHeader; - let resolved = asFunc.call(null) as Promise; + let asFunc = authorizationHeader as GetAuthorizationHeader; + let resolved = asFunc.call(null) as Promise; authorizationValue = await resolved; if (typeof resolved === 'function') { - asFunc = resolved as IGetAuthorizationHeader; - resolved = asFunc.call(null) as Promise; + asFunc = resolved as GetAuthorizationHeader; + resolved = asFunc.call(null) as Promise; authorizationValue = await resolved; } } else if (authorizationHeader && authorizationHeader['value']) { - authorizationValue = authorizationHeader as IAuthorizationHeaderValue; + authorizationValue = authorizationHeader as AuthorizationHeaderValue; } else { - throw new Error('Invalid resolveAuthorizationHeader'); + throw CreateError.InvalidParameters('Unknown resolveAuthorizationHeader type'); } } catch (getTokenError) { console.dir(getTokenError); @@ -156,7 +167,7 @@ export class RestLibrary { } async call( - awaitToken: IGetAuthorizationHeader | IAuthorizationHeaderValue | string, + awaitToken: GetAuthorizationHeader | AuthorizationHeaderValue | string, api: string, options, cacheOptions = null @@ -181,20 +192,32 @@ export class RestLibrary { return result; } - request(token, restEndpoint, parameters: any, cacheOptions): Promise { + request(token: GetAuthorizationHeader | string, restEndpoint, parameters: any, cacheOptions): Promise { parameters = parameters || {}; parameters['octokitRequest'] = restEndpoint; return this.call(token, 'request', parameters, cacheOptions); } - requestAsPost(token, restEndpoint, parameters: any): Promise { + requestAsPost(token: GetAuthorizationHeader | string, restEndpoint, parameters: any): Promise { parameters = parameters || {}; parameters['octokitRequest'] = restEndpoint; return this.post(token, 'request', parameters); } + restApi( + token: GetAuthorizationHeader | string, + httpMethod: HttpMethod, + restEndpoint: string, + parameters: any + ): Promise { + const requestUrlValue = `${httpMethod} ${restEndpoint}`; + return httpMethod === HttpMethod.Get + ? this.request(token, requestUrlValue, parameters, {}) + : this.requestAsPost(token, requestUrlValue, parameters); + } + graphql( - token, + token: GetAuthorizationHeader | string, query: string, parameters: any, graphqlOptions: OctokitGraphqlOptions = {} @@ -203,7 +226,7 @@ export class RestLibrary { } graphqlIteration( - token, + token: GetAuthorizationHeader | string, query: string, parameters: any, graphqlOptions: OctokitGraphqlOptions = {} @@ -228,7 +251,7 @@ export class RestLibrary { return this.post(token, api, parameters); } - async post(awaitToken: IGetAuthorizationHeader | string, api: string, options: any): Promise { + async post(awaitToken: GetAuthorizationHeader | string, api: string, options: any): Promise { const method = restApi.IntelligentGitHubEngine.findLibraryMethod(this.github, api); if (!options.headers) { options.headers = {}; @@ -239,14 +262,14 @@ export class RestLibrary { delete options.allowEmptyResponse; massageData = noDataMassage; } - let diagnosticHeaderInformation: IAuthorizationHeaderValue = null; + let diagnosticHeaderInformation: AuthorizationHeaderValue = null; if (!options.headers.authorization) { const value = await this.resolveAuthorizationHeader(awaitToken); - if ((value as IAuthorizationHeaderValue)?.purpose) { - diagnosticHeaderInformation = value as IAuthorizationHeaderValue; + if ((value as AuthorizationHeaderValue)?.purpose) { + diagnosticHeaderInformation = value as AuthorizationHeaderValue; } options.headers.authorization = - typeof value === 'string' ? (value as string) : (value as IAuthorizationHeaderValue).value; + typeof value === 'string' ? (value as string) : (value as AuthorizationHeaderValue).value; } const diagnostic: Record = {}; try { @@ -283,8 +306,15 @@ export class RestLibrary { return finalized; } catch (error) { console.log(`API ${api} POST error: ${error.message}`); - if (error?.message?.includes('Resource not accessible by integration')) { - console.error('Options:'); + if (error?.message?.includes('Unexpected end of JSON input')) { + console.log('Usually a unicorn and bad GitHub 500'); + console.dir(error); + } + if ( + error?.message?.includes('Resource not accessible by integration') || + error?.message?.includes('Not Found') + ) { + console.error('\tOptions:'); { const options = Object.getOwnPropertyNames(diagnostic.options).length > 0 ? diagnostic.options : null; @@ -297,17 +327,17 @@ export class RestLibrary { if (key === 'headers') { const headers = value as Record; const headersKeys = Object.getOwnPropertyNames(headers); - console.log('Headers:'); + console.log('\t\tHeaders:'); for (let j = 0; j < headersKeys.length; j++) { const headerKey = headersKeys[j]; const headerValue = headerKey.toLocaleLowerCase() === 'authorization' ? headers[headerKey].substring(0, 13) + '***' : headers[headerKey]; - console.log(` - ${headerKey}: ${headerValue}`); + console.log(`\t\t - ${headerKey}: ${headerValue}`); } } else { - console.log(`Option: ${key}: ${value}`); + console.log(`\t\tOption: ${key}: ${value}`); } } } @@ -316,38 +346,39 @@ export class RestLibrary { for (let i = 0; i < remainingKeys.length; i++) { const key = remainingKeys[i]; const value = diagnostic[key]; - console.log(`${key}: ${value}`); + console.log(`\t\t${key}: ${value}`); } } } if (diagnosticHeaderInformation) { - console.error('Authorization selection information:'); + console.error('\tAuthorization selection information:'); const { installationId, organizationName, purpose, source } = diagnosticHeaderInformation; - organizationName && console.error(`Header resolved for organization: ${organizationName}`); + organizationName && console.error(`\t\tHeader resolved for organization: ${organizationName}`); const customPurpose = purpose as ICustomAppPurpose; purpose && customPurpose?.isCustomAppPurpose === true && - console.error(`Custom purpose: ${customPurpose.id}`); - purpose && !customPurpose?.isCustomAppPurpose && console.error(`Purpose: ${purpose}`); - installationId && console.error(`Installation ID: ${installationId}`); - source && console.error(`Source: ${source}`); + console.error(`\t\tCustom purpose: ${customPurpose.id}`); + purpose && !customPurpose?.isCustomAppPurpose && console.error(`\t\tPurpose: ${purpose}`); + installationId && console.error(`\t\tInstallation ID: ${installationId}`); + source && console.error(`\t\tSource: ${source}`); } } if (error.status) { - console.log(`Status: ${error.status}`); + console.log(`\tStatus: ${error.status}`); } if (error?.response?.headers && error?.response?.headers['x-github-request-id']) { - console.log(`Request ID: ${error.response.headers['x-github-request-id']}`); + console.log(`\tRequest ID: ${error.response.headers['x-github-request-id']}`); } if (error?.response?.headers && error?.response?.headers['x-ratelimit-remaining']) { - console.log(`Rate limit remaining: ${error.response.headers['x-ratelimit-remaining']}`); + console.log(`\tRate limit remaining: ${error.response.headers['x-ratelimit-remaining']}`); } if (error?.response?.headers && error?.response?.headers['x-ratelimit-used']) { - console.log(`Rate limit used: ${error.response.headers['x-ratelimit-used']}`); + console.log(`\tRate limit used: ${error.response.headers['x-ratelimit-used']}`); } if (shouldErrorShowRequest && error?.request) { console.dir(error.request); } + console.log(); throw error; } } diff --git a/lib/github/restApi.ts b/lib/github/restApi.ts index 7687f2bed..0c1e3f2e7 100644 --- a/lib/github/restApi.ts +++ b/lib/github/restApi.ts @@ -14,19 +14,26 @@ const debugShowStandardBehavior = false; const debugOutputUnregisteredEntityApis = true; import { - IShouldServeCache, + ShouldServeCache, IntelligentEngine, ApiContext, IApiContextCacheValues, IApiContextRedisKeys, ApiContextType, - IRestResponse, - IRestMetadata, + RestResponse, + RestMetadata, } from './core'; import { getEntityDefinitions, GitHubResponseType, ResponseBodyType } from './endpointEntities'; import appPackage from '../../package.json'; -import { IGetAuthorizationHeader, IAuthorizationHeaderValue } from '../../interfaces'; +import { ErrorHelper } from '../transitional'; + +import type { GetAuthorizationHeader, AuthorizationHeaderValue } from '../../interfaces'; +import { + type IGitHubAppConfiguration, + getAppPurposeId, + tryGetAppPurposeAppConfiguration, +} from './appPurposes'; const appVersion = appPackage.version; @@ -70,7 +77,7 @@ export class IntelligentGitHubEngine extends IntelligentEngine { return method; } - async callApi(apiContext: GitHubApiContext, optionalMessage?: string): Promise { + async callApi(apiContext: GitHubApiContext, optionalMessage?: string): Promise { const token = apiContext.token; // CONSIDER: rename apiContext.token *to* something like apiContext.authorization if ( @@ -101,10 +108,11 @@ export class IntelligentGitHubEngine extends IntelligentEngine { } } } + const purpose = apiContext?.tokenSource?.purpose ? getAppPurposeId(apiContext.tokenSource.purpose) : null; if (optionalMessage) { let apiTypeSuffix = apiContext.tokenSource && apiContext.tokenSource.purpose - ? ' [' + apiContext.tokenSource.purpose + ']' + ? ' [' + (purpose || apiContext.tokenSource.purpose) + ']' : ''; if (!apiTypeSuffix && apiContext.tokenSource && apiContext.tokenSource.source) { apiTypeSuffix = ` [token source=${apiContext.tokenSource.source}]`; @@ -139,11 +147,41 @@ export class IntelligentGitHubEngine extends IntelligentEngine { args.push(argOptions); } const thisArgument = apiMethod.thisInstance || null; - const response = await apiMethod.apply(thisArgument, args); - return response; + try { + const response = await apiMethod.apply(thisArgument, args); + return response; + } catch (error) { + const asAny = error as any; + if ( + ErrorHelper.IsNotAuthorized(error) && + asAny?.message === 'Resource not accessible by integration' && + apiContext.tokenSource + ) { + let appConfig: IGitHubAppConfiguration = null; + if (apiContext?.tokenSource?.purpose && apiContext?.tokenSource?.organizationName) { + appConfig = tryGetAppPurposeAppConfiguration( + apiContext.tokenSource.purpose, + apiContext.tokenSource.organizationName + ); + } + asAny.source = apiContext.tokenSource.source; + const additional: string[] = []; + purpose && additional.push(`purpose=${purpose}`); + appConfig?.appId && additional.push(`appId=${appConfig.appId}`); + appConfig?.slug && additional.push(`slug=${appConfig.slug}`); + apiContext?.tokenSource?.installationId && + additional.push(`installationId=${apiContext.tokenSource.installationId}`); + apiContext?.tokenSource?.organizationName && + additional.push(`organization=${apiContext.tokenSource.organizationName}`); + const extra = ' ' + additional.join(', '); + debug(`Additional installation context added to message for 403: ${extra}`); + asAny.message += extra; + } + throw error; + } } - processMetadataBeforeCall(apiContext: ApiContext, metadata: IRestMetadata) { + processMetadataBeforeCall(apiContext: ApiContext, metadata: RestMetadata) { if ( metadata && metadata.av && @@ -165,11 +203,11 @@ export class IntelligentGitHubEngine extends IntelligentEngine { return metadata; } - withResponseUpdateMetadata(apiContext: ApiContext, response: IRestResponse) { + withResponseUpdateMetadata(apiContext: ApiContext, response: RestResponse) { return response; } - optionalStripResponse(apiContext: ApiContext, response: IRestResponse): IRestResponse { + optionalStripResponse(apiContext: ApiContext, response: RestResponse): RestResponse { const clonedResponse = Object.assign({}, response); if (response.headers) { const clonedHeaders = StripGitHubEntity( @@ -257,7 +295,7 @@ export class IntelligentGitHubEngine extends IntelligentEngine { return clonedResponse; } - reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: IRestResponse): any { + reduceMetadataToCacheFromResponse(apiContext: ApiContext, response: RestResponse): any { const headers = response ? response.headers : null; if (headers?.etag) { const reduced: IReducedGitHubMetadata = { @@ -282,8 +320,8 @@ export class IntelligentGitHubEngine extends IntelligentEngine { withResponseShouldCacheBeServed( apiContext: ApiContext, - response: IRestResponse - ): boolean | IShouldServeCache { + response: RestResponse + ): boolean | ShouldServeCache { if (response === undefined) { throw new Error('The response was undefined and unable to process.'); } @@ -320,8 +358,8 @@ export class IntelligentGitHubEngine extends IntelligentEngine { return cacheOk; } - getResponseMetadata(apiContext: ApiContext, response: IRestResponse): IRestMetadata { - const md: IRestMetadata = { + getResponseMetadata(apiContext: ApiContext, response: RestResponse): RestMetadata { + const md: RestMetadata = { headers: response.headers, status: response.status, }; @@ -330,12 +368,12 @@ export class IntelligentGitHubEngine extends IntelligentEngine { withMetadataShouldCacheBeServed( apiContext: ApiContext, - metadata: IRestMetadata - ): boolean | IShouldServeCache { + metadata: RestMetadata + ): boolean | ShouldServeCache { // result can be falsy OR an object; { cache: true, refresh: true } // cache: whether to use the cache, if available // refresh: whether to refresh in the background for a newer value - let shouldServeCache: IShouldServeCache | boolean = false; + let shouldServeCache: ShouldServeCache | boolean = false; const maxAgeSeconds = apiContext.maxAgeSeconds; const updatedIso = metadata ? metadata.updated : null; const refreshingIso = metadata ? metadata.refreshing : null; @@ -408,7 +446,7 @@ export class GitHubApiContext extends ApiContext { private _apiMethod: any; private _redisKeys: IApiContextRedisKeys; private _cacheValues: IApiContextCacheValues; - private _token: string | IGetAuthorizationHeader | IAuthorizationHeaderValue; + private _token: string | GetAuthorizationHeader | AuthorizationHeaderValue; public fakeLink?: IGitHubLink; @@ -434,7 +472,7 @@ export class GitHubApiContext extends ApiContext { }; } - get token(): string | IGetAuthorizationHeader | IAuthorizationHeaderValue { + get token(): string | GetAuthorizationHeader | AuthorizationHeaderValue { return this._token; } @@ -473,9 +511,9 @@ export class GitHubApiContext extends ApiContext { this.libraryContext = libraryContext; } - overrideToken(token: string | IGetAuthorizationHeader | IAuthorizationHeaderValue) { + overrideToken(token: string | GetAuthorizationHeader | AuthorizationHeaderValue) { if (token && token['value']) { - const asPair = token as IAuthorizationHeaderValue; + const asPair = token as AuthorizationHeaderValue; this._token = asPair.value; this.tokenSource = asPair; } else if (typeof token === 'string') { diff --git a/business/githubApps/tokenManager.ts b/lib/github/tokenManager.ts similarity index 65% rename from business/githubApps/tokenManager.ts rename to lib/github/tokenManager.ts index 560ba6e7f..413b4940e 100644 --- a/business/githubApps/tokenManager.ts +++ b/lib/github/tokenManager.ts @@ -15,20 +15,21 @@ import { GitHubAppPurposes, AppPurposeTypes, getAppPurposeId, -} from '.'; +} from './appPurposes'; import { GitHubAppTokens } from './appTokens'; -import { IAuthorizationHeaderValue, NoCacheNoBackground } from '../../interfaces'; -import { OrganizationSetting } from '../../entities/organizationSettings/organizationSetting'; -import { readFileToText } from '../../utils'; -import { Operations, OperationsCore, Organization } from '..'; -import { CreateError } from '../../transitional'; +import { AuthorizationHeaderValue, GetAuthorizationHeader, NoCacheNoBackground } from '../../interfaces'; +import { OrganizationSetting } from '../../business/entities/organizationSettings/organizationSetting'; +import { readFileToText } from '../utils'; +import { Operations, OperationsCore, Organization } from '../../business'; +import { CreateError } from '../transitional'; +import { shuffle } from 'lodash'; -export interface IGitHubRateLimit { +export type GitHubRateLimit = { limit: number; remaining: number; reset: number; used: number; -} +}; // Installation redirect format: // /setup/app/APP_ID?installation_id=INSTALLATION_ID&setup_action=install @@ -53,7 +54,7 @@ export class GitHubTokenManager { private _forceInstanceTokensToPurpose: AppPurposeTypes; private _allowReadOnlyFallbackToOtherInstallations: boolean; - static RegisterManagerForOperations(operations: OperationsCore, manager: GitHubTokenManager) { + private static RegisterManagerForOperations(operations: OperationsCore, manager: GitHubTokenManager) { GitHubTokenManager._managersForOperations.set(operations, manager); } @@ -65,9 +66,15 @@ export class GitHubTokenManager { if (!options) { throw new Error('options required'); } + const executionEnvironment = options.executionEnvironment; this.#options = options; GitHubTokenManager._forceBackgroundTokens = - options.app.isBackgroundJob && !options.app.enableAllGitHubApps; + executionEnvironment.isJob && !executionEnvironment.enableAllGitHubApps; + GitHubTokenManager.RegisterManagerForOperations(options.operations, this); + } + + private operations() { + return this.#options.operations as Operations; } private getFallbackList(input: AppPurposeTypes[]) { @@ -146,6 +153,8 @@ export class GitHubTokenManager { } private getPurposeDisplayId(purpose: AppPurposeTypes) { + // is this identical to the method getAppPurposeId? + const asCustom = purpose as ICustomAppPurpose; if (asCustom?.isCustomAppPurpose === true) { return asCustom.id; @@ -161,14 +170,38 @@ export class GitHubTokenManager { return null; } + async ensureConfigurationAppInitialized( + customPurpose: AppPurposeTypes, + customPurposeConfiguration: IGitHubAppConfiguration + ): Promise { + const appId = customPurposeConfiguration.appId; + const asCustomPurpose = this.getCustomPurpose(customPurpose); + if (!asCustomPurpose?.isCustomAppPurpose) { + throw CreateError.InvalidParameters(`The purpose ${customPurpose} is not a custom app purpose`); + } + let app = this._appsById.get(appId); + if (!app) { + debug(`initializing app for custom purpose ${asCustomPurpose.id} with custom configuration`); + app = await this.initializeApp(asCustomPurpose, customPurposeConfiguration); + } + if (!app) { + throw CreateError.InvalidParameters( + `Error initializing purpose ${this.getPurposeDisplayId(customPurpose)}` + ); + } + return app; + } + async getOrganizationAuthorizationHeader( organizationName: string, preferredPurpose: AppPurposeTypes, organizationSettings: OrganizationSetting, appAuthenticationType: GitHubAppAuthenticationType - ): Promise { + ): Promise { debug( - `getOrganizationAuthorizationHeader(${organizationName}, ${preferredPurpose}, ${appAuthenticationType})` + `getOrganizationAuthorizationHeader(${organizationName}, ${this.getPurposeDisplayId( + preferredPurpose + )}, ${appAuthenticationType})` ); const installationIdPair = this.getPrioritizedOrganizationInstallationId( preferredPurpose, @@ -177,8 +210,10 @@ export class GitHubTokenManager { appAuthenticationType ); if (!installationIdPair) { - throw new Error( - `GitHubTokenManager: organization ${organizationName} does not have a configured GitHub App installation, or, the installation information is not in this environment. The API preferred purpose was ${preferredPurpose} with the selection type ${appAuthenticationType}.` + throw CreateError.InvalidParameters( + `GitHubTokenManager: organization ${organizationName} does not have a configured GitHub App installation, or, the installation information is not in this environment. The API preferred purpose was ${getAppPurposeId( + preferredPurpose + )} with the selection type ${appAuthenticationType}.` ); } if ( @@ -232,16 +267,18 @@ export class GitHubTokenManager { ); const value = await app.getInstallationToken(installationIdPair.installationId, organizationName); debug( - `returned installation ID pair: installationId=${value?.installationId}, source=${value?.source}, purpose=${value?.purpose}` + `returned installation ID pair: installationId=${value?.installationId}, source=${value?.source}, purpose=${this.getPurposeDisplayId( + value?.purpose + )}` ); return value; } - async getInstallationAuthorizationHeader( + getInstallationAuthorizationHeader( appId: number, installationId: number, organizationName: string - ): Promise { + ): Promise { const app = this._appsById.get(appId); if (!app) { throw new Error(`App ID=${appId} is not configured in this application instance`); @@ -249,10 +286,52 @@ export class GitHubTokenManager { return app.getInstallationToken(installationId, organizationName); } - getAppForPurpose(purpose: AppPurposeTypes) { + getAppForPurpose(purpose: AppPurposeTypes, organizationName?: string) { + const asCustomPurpose = this.getCustomPurpose(purpose); + if (asCustomPurpose?.getForOrganizationName) { + const configForOrganization = asCustomPurpose.getForOrganizationName(organizationName); + const appId = configForOrganization.appId; + if (appId) { + return this._appsById.get(appId); + } + } else if (asCustomPurpose?.getApplicationConfigurationForInitialization) { + const config = asCustomPurpose.getApplicationConfigurationForInitialization(); + const appId = config.appId; + if (appId) { + return this._appsById.get(appId); + } + } return this._apps.get(purpose); } + getAnyConfiguredInstallationIdForAppId(operations: Operations, appId: number) { + const orgs = operations.getOrganizations(); + for (const org of orgs) { + const settings = org.getDynamicSettings(); + if (settings?.installations) { + for (const { appId: appConfiguredId, installationId } of settings.installations) { + if (appConfiguredId === appId) { + return { installationId, organizationName: org.name }; + } + } + } + } + } + + getAnyConfiguredInstallationIdForAnyApp(operations: Operations) { + const orgs = shuffle(operations.getOrganizations()); + for (const org of orgs) { + const settings = org.getDynamicSettings(); + if (settings?.installations) { + const installs = shuffle(settings.installations); + const configuredInstalls = installs.filter((i) => this._appsById.has(i.appId)); + for (const { installationId, appId } of configuredInstalls) { + return { installationId, organizationName: org.name, appId }; + } + } + } + } + getInstallationIdForOrganization(purpose: AppPurposeTypes, organization: Organization) { const settings = organization.getDynamicSettings(); if (settings?.installations) { @@ -263,7 +342,18 @@ export class GitHubTokenManager { } } } - // CONSIDER: custom purposes could expose the installation ID here + const asCustomPurpose = this.getCustomPurpose(purpose); + if (asCustomPurpose?.getForOrganizationName) { + const configForOrganization = asCustomPurpose.getForOrganizationName(organization.name); + if (configForOrganization.slug) { + throw CreateError.NotImplemented( + `While a custom purpose is configured for the "${organization.name}" with the app ${configForOrganization.slug}, the installation ID is not yet available with this call. This is a known limitation.` + ); + } + throw CreateError.NotImplemented( + `This custom purpose is not configured for the "${organization.name}" org with the app ${configForOrganization.slug}, the installation ID is not yet available with this call. This is a known limitation.` + ); + } if (!organization.hasDynamicSettings) { throw CreateError.InvalidParameters( `Organization ${organization.name} does not have dynamic settings or purpose-directed configuration` @@ -271,6 +361,73 @@ export class GitHubTokenManager { } } + getAuthorizationHeaderForAnyApp(): Promise { + const anyConfigured = this.getAnyConfiguredInstallationIdForAnyApp(this.operations()); + if (anyConfigured) { + return this.getInstallationAuthorizationHeader( + anyConfigured.appId, + anyConfigured.installationId, + anyConfigured.organizationName + ); + } + throw CreateError.InvalidParameters('No configured applications available.'); + } + + async getAppInformation(purpose: AppPurposeTypes, organizationName?: string) { + const appTokens = this.getAppForPurpose(purpose, organizationName); + if (!appTokens) { + throw CreateError.InvalidParameters(`No app configured yet for purpose ${purpose}`); + } + const slug = appTokens.slug; + if (!slug) { + throw CreateError.InvalidParameters(`No slug configured for purpose ${purpose}`); + } + return this.getAppInformationBySlug(this.operations(), slug); + } + + async getAppInformationBySlug(operations: Operations, slug: string) { + let appId: number = null; + for (const entry of this._appSlugs.entries()) { + if (entry[1] === slug) { + appId = entry[0]; + break; + } + } + let authorizationHeader: GetAuthorizationHeader = null; + // Have the app call itself via the slug-based API (works if it's a private single-org app) + if (appId) { + const anyConfiguredForApp = this.getAnyConfiguredInstallationIdForAppId(operations, appId); + if (anyConfiguredForApp) { + authorizationHeader = this.getInstallationAuthorizationHeader.bind( + this, + appId, + anyConfiguredForApp.installationId, + anyConfiguredForApp.organizationName + ); + } + } + // Call using any configured app + if (!authorizationHeader) { + const anyConfigured = this.getAnyConfiguredInstallationIdForAnyApp(operations); + if (anyConfigured) { + authorizationHeader = this.getInstallationAuthorizationHeader.bind( + this, + anyConfigured.appId, + anyConfigured.installationId, + anyConfigured.organizationName + ); + } + } + // Fallback to a static token + if (!authorizationHeader) { + authorizationHeader = operations.getPublicReadOnlyStaticToken.bind(operations); + } + const value = await operations.github.post(authorizationHeader, 'apps.getBySlug', { + app_slug: slug, + }); + return value; + } + async getRateLimitInformation(purpose: AppPurposeTypes, organization: Organization) { const settings = organization.getDynamicSettings(); if (settings?.installations) { @@ -289,7 +446,7 @@ export class GitHubTokenManager { NoCacheNoBackground ); if (value?.rate) { - return value.rate as IGitHubRateLimit; + return value.rate as GitHubRateLimit; } console.warn(value); throw CreateError.InvalidParameters('No rate limit information returned'); @@ -325,12 +482,18 @@ export class GitHubTokenManager { const allPurposes = GitHubAppPurposes.AllAvailableAppPurposes; const fallbackPurposePriorities = this.getFallbackList(allPurposes); const customPurposes = allPurposes.filter((p) => (p as ICustomAppPurpose).isCustomAppPurpose === true); + const matchingCustomPurposes = + (preferredPurpose as ICustomAppPurpose)?.isCustomAppPurpose === true + ? customPurposes.filter( + (cp) => (cp as ICustomAppPurpose).id === (preferredPurpose as ICustomAppPurpose).id + ) + : customPurposes; let order = this.isForcingBackgroundJobType() === true ? fallbackPurposePriorities : [preferredPurpose, ...fallbackPurposePriorities]; if (appAuthenticationType === GitHubAppAuthenticationType.ForceSpecificInstallation) { - order = [preferredPurpose, ...customPurposes]; + order = [preferredPurpose, ...matchingCustomPurposes]; } for (const purpose of order) { let customAppPurpose = purpose as ICustomAppPurpose; @@ -383,11 +546,12 @@ export class GitHubTokenManager { // Not base64-encoded, use the CreateFromString method. skipDecodingBase64 = true; } + const slug = appConfig.slug; const friendlyName = customPurpose?.name || appConfig.description || 'Unknown'; const baseUrl = appConfig.baseUrl; const app = skipDecodingBase64 - ? GitHubAppTokens.CreateFromString(purpose, friendlyName, appId, key, baseUrl) - : GitHubAppTokens.CreateFromBase64EncodedFileString(purpose, friendlyName, appId, key, baseUrl); + ? GitHubAppTokens.CreateFromString(purpose, slug, friendlyName, appId, key, baseUrl) + : GitHubAppTokens.CreateFromBase64EncodedFileString(purpose, slug, friendlyName, appId, key, baseUrl); const hasCustomConfigurationByOrganization = customPurpose?.getForOrganizationName; const standardPurpose = purpose as AppPurpose; if (!hasCustomConfigurationByOrganization) { diff --git a/lib/graphProvider/microsoftGraphProvider.ts b/lib/graphProvider/microsoftGraphProvider.ts index 8cdb4f5e0..0d5922e91 100644 --- a/lib/graphProvider/microsoftGraphProvider.ts +++ b/lib/graphProvider/microsoftGraphProvider.ts @@ -8,6 +8,7 @@ import cache from 'memory-cache'; import axios, { AxiosError } from 'axios'; import querystring from 'querystring'; +import validator from 'validator'; import { IGraphProvider, @@ -17,7 +18,7 @@ import { IGraphGroup, GraphUserType, } from '.'; -import { ErrorHelper, CreateError, splitSemiColonCommas } from '../../transitional'; +import { ErrorHelper, CreateError, splitSemiColonCommas } from '../transitional'; import { ICacheHelper } from '../caching'; const axios12BufferDecompressionBugHeaderAddition = true; @@ -32,20 +33,68 @@ export interface IMicrosoftGraphProviderOptions { skipManagerLookupForIds?: string; } +export type MicrosoftGraphGroupMembersOptions = { + getCount?: boolean; + maximumPages?: number; + throwOnMaximumPages?: boolean; + skipCache?: boolean; + additionalSelectValues?: string[]; + membership?: MicrosoftGraphGroupMembershipType; +}; + +export enum MicrosoftGraphGroupMembershipType { + Transitive = 'transitiveMembers', + Direct = 'members', +} + +export type MicrosoftGraphGroupMember = IGraphGroupMember & { + userType?: GraphUserType; +}; + +export function microsoftGraphUserTypeFromString(type: string): GraphUserType { + if (!type) { + return; + } + switch (type) { + case GraphUserType.Guest: + return GraphUserType.Guest; + case GraphUserType.Member: + return GraphUserType.Member; + default: + return GraphUserType.Unknown; + } +} + +type GraphCheckMembersRequest = { + ids: string[]; +}; + +type GraphCheckMembersResponse = { + value: string[]; +}; + const graphBaseUrl = 'https://graph.microsoft.com/v1.0/'; const odataNextLink = '@odata.nextLink'; -const defaultCachePeriodMinutes = 60; +const defaultCachePeriodMinutes = 60 * 36; // 36 hours const attemptCacheGet = true; -interface IGraphOptions { +type MicrosoftGraphCallOptions = { selectValues?: string; filterValues?: string; orderBy?: string; body?: any; count?: boolean; consistencyLevel?: 'eventual'; -} +}; + +type GraphCacheOptions = { + skipCache?: boolean; + maximumPages?: number; + throwOnMaximumPages?: boolean; +}; + +type GraphOptions = MicrosoftGraphCallOptions & GraphCacheOptions; export class MicrosoftGraphProvider implements IGraphProvider { #_tokenCacheMilliseconds: number; @@ -80,9 +129,26 @@ export class MicrosoftGraphProvider implements IGraphProvider { } async isUserInGroup(corporateId: string, securityGroupId: string): Promise { - // TODO: refactor for efficient use of Microsoft Graph's checkMemberObjects https://docs.microsoft.com/en-us/graph/api/group-checkmemberobjects?view=graph-rest-1.0&tabs=http - const members = await this.getGroupMembers(securityGroupId); - return members.filter((m) => m.id === corporateId).length > 0; + // Formerly used a very inefficient approach: + // const members = await this.getGroupMembers(securityGroupId); + // return members.filter((m) => m.id === corporateId).length > 0; + return await this.checkMemberObjectsForUserId(corporateId, securityGroupId); + } + + private async checkMemberObjectsForUserId(corporateId: string, securityGroupId: string): Promise { + const requestBody: GraphCheckMembersRequest = { + ids: [securityGroupId], + }; + const url = `${graphBaseUrl}users/${corporateId}/checkMemberObjects`; + const response = await this.request( + url, + requestBody, + null, + true + ); /* no cache */ + const foundGroupIds = response.value; + const found = foundGroupIds.includes(securityGroupId); + return found; } private async getTokenThenEntity(aadId: string, resource: string): Promise { @@ -162,12 +228,18 @@ export class MicrosoftGraphProvider implements IGraphProvider { } async getGroup(corporateGroupId: string): Promise { + const selectValues = 'description,displayName,id,mail,mailNickname'; + // if (additionalSelectValues) { + // selectValues = Array.from( + // new Set([...selectValues.split(','), ...additionalSelectValues]).values() + // ).join(','); + // } // prettier-ignore const response = await this.lookupInGraph([ 'groups', corporateGroupId, ], { - selectValues: 'description,displayName,id,mail,mailNickname', + selectValues, }); return response; } @@ -234,8 +306,8 @@ export class MicrosoftGraphProvider implements IGraphProvider { ], { filterValues: `mail eq '${mail}'`, // encodeURIComponent( selectValues: 'id', - count: true, - consistencyLevel: 'eventual', + // count: true, + // consistencyLevel: 'eventual', })) as any[]; if (!response || response.length === 0) { return null; @@ -357,26 +429,50 @@ export class MicrosoftGraphProvider implements IGraphProvider { }); } - async getGroupMembers(corporateGroupId: string): Promise { + async getGroupMembers( + corporateGroupId: string, + options?: MicrosoftGraphGroupMembersOptions + ): Promise { + const defaultSelectSet = ['id', 'userPrincipalName']; + const selectValuesSet = new Set([ + ...defaultSelectSet, + ...(options?.additionalSelectValues || []), + ]); + const graphOptions: GraphOptions = { + selectValues: Array.from(selectValuesSet.values()).join(','), + }; + if (options?.getCount !== undefined) { + graphOptions.count = true; + graphOptions.consistencyLevel = 'eventual'; + } + if (options?.maximumPages !== undefined) { + graphOptions.maximumPages = options.maximumPages; + } + if (options?.throwOnMaximumPages !== undefined) { + graphOptions.throwOnMaximumPages = options.throwOnMaximumPages; + } + const lookupType = options?.membership || MicrosoftGraphGroupMembershipType.Transitive; + const includesUserType = selectValuesSet.has('userType'); const response = (await this.lookupInGraph( - [ - 'groups', - corporateGroupId, - 'transitiveMembers', // transitiveMembers or members - ], - { - selectValues: 'id,userPrincipalName', - } + ['groups', corporateGroupId, lookupType], + graphOptions )) as any[]; - // may be a caching bug: if (Array.isArray(response)) { return response.map((entry) => { - return { id: entry.id, userPrincipalName: entry.userPrincipalName }; + return { + id: entry.id, + userPrincipalName: entry.userPrincipalName, + userType: includesUserType ? microsoftGraphUserTypeFromString(entry.userType) : undefined, + }; }); } const subResponse = (response as any).value ? (response as any).value : []; return subResponse.map((entry) => { - return { id: entry.id, userPrincipalName: entry.userPrincipalName }; + return { + id: entry.id, + userPrincipalName: entry.userPrincipalName, + userType: includesUserType ? microsoftGraphUserTypeFromString(entry.userType) : undefined, + }; }); } @@ -384,12 +480,18 @@ export class MicrosoftGraphProvider implements IGraphProvider { if (!minimum3Characters || minimum3Characters.length < 3) { throw new Error(`Minimum 3 characters required: ${minimum3Characters}`); } + + let filterValues = `securityEnabled eq true and (startswith(displayName, '${minimum3Characters}') or startswith(mailNickname, '${minimum3Characters}'))`; + if (validator.isUUID(minimum3Characters)) { + filterValues = `securityEnabled eq true and (id eq '${minimum3Characters}' or startswith(displayName, '${minimum3Characters}') or startswith(mailNickname, '${minimum3Characters}'))`; + } + // NOTE: this is currently explicitly looking for Security Groups only // prettier-ignore let response = (await this.lookupInGraph([ 'groups', ], { - filterValues: `securityEnabled eq true and (startswith(displayName, '${minimum3Characters}') or startswith(mailNickname, '${minimum3Characters}'))`, + filterValues, selectValues: 'id,displayName,mailNickname', })) as any[]; if (!response.filter && (response as any).value?.filter) { @@ -488,8 +590,9 @@ export class MicrosoftGraphProvider implements IGraphProvider { } } - private async lookupInGraph(entityPath: string[], options: IGraphOptions): Promise { + private async lookupInGraph(entityPath: string[], options: GraphOptions): Promise { // initial hacking on top of the API + const skipCache = options?.skipCache === true; const subUrl = entityPath.map((item) => encodeURIComponent(item)).join('/'); const queries = {}; if (options.filterValues) { @@ -501,12 +604,15 @@ export class MicrosoftGraphProvider implements IGraphProvider { if (options.orderBy) { queries['$orderby'] = options.orderBy; } + if (options.count === true) { + queries['$count'] = 'true'; + } let hasArray = false; let value = null; let url = `${graphBaseUrl}${subUrl}?${querystring.stringify(queries)}`; const originalUrl = url; try { - if (this.#_cache && attemptCacheGet) { + if (this.#_cache && attemptCacheGet && !skipCache) { value = await this.#_cache.getObject(url); if (value?.cache) { if (Array.isArray(value.cache) && value.cache.length === 0) { @@ -522,9 +628,10 @@ export class MicrosoftGraphProvider implements IGraphProvider { console.warn(error); } let pages = 0; + const maximumPages = options?.maximumPages; do { const consistencyLevel = options.consistencyLevel; - const body = await this.request(url, options.body, consistencyLevel); + const body = await this.request(url, options.body, consistencyLevel, skipCache); if (body.value && pages === 0) { hasArray = body && body.value && Array.isArray(body.value); if (hasArray) { @@ -539,14 +646,25 @@ export class MicrosoftGraphProvider implements IGraphProvider { } else { throw new Error(`Page ${pages} in response is not an array type but had a link: ${url}`); } + if (body && body['@odata.count'] !== undefined) { + const count = body['@odata.count']; + // NOTE: we don't store or cache or return this today + console.log(`Total objects in response: ${count}`); + } ++pages; url = body && body[odataNextLink] ? body[odataNextLink] : null; - } while (url); + } while (url && (maximumPages ? pages < maximumPages : true)); + if (pages >= maximumPages) { + if (options.throwOnMaximumPages) { + throw CreateError.InvalidParameters('Maximum pages exceeded for this resource'); + } + console.warn(`WARN: Maximum pages exceeded for this resource: ${originalUrl}`); + } if (this.#_cache) { try { this.#_cache .setObjectWithExpire(originalUrl, { cache: value }, defaultCachePeriodMinutes) - .then((ok) => {}) + .then(() => {}) .catch((err) => { console.warn(err); }); @@ -557,10 +675,15 @@ export class MicrosoftGraphProvider implements IGraphProvider { return value; } - private async request(url: string, body?: any, eventualConsistency?: string): Promise { + private async request( + url: string, + body?: any, + eventualConsistency?: string, + skipCache?: boolean + ): Promise { const token = await this.getToken(); const method = body ? 'post' : 'get'; - if (this.#_cache && attemptCacheGet && method === 'get') { + if (this.#_cache && attemptCacheGet && method === 'get' && !skipCache) { try { const value = await this.#_cache.getObject(url); if (value?.cache) { @@ -584,7 +707,7 @@ export class MicrosoftGraphProvider implements IGraphProvider { } if (eventualConsistency) { - // headers.ConsistencyLevel = eventualConsistency; + headers['ConsistencyLevel'] = eventualConsistency; } const response = await axios({ url, @@ -596,13 +719,12 @@ export class MicrosoftGraphProvider implements IGraphProvider { throw CreateError.ServerError('Empty response'); } if ((response.data as any).error?.message) { - // axios returns unknown now - throw CreateError.InvalidParameters((response.data as any).error.message); // axios returns unknown now + throw CreateError.InvalidParameters((response.data as any).error.message); } if (this.#_cache && method === 'get') { this.#_cache .setObjectWithExpire(url, { cache: response.data }, defaultCachePeriodMinutes) - .then((ok) => {}) + .then(() => {}) .catch((err) => {}); } return response.data; diff --git a/lib/linkProviders/table/tableLinkProvider.ts b/lib/linkProviders/table/tableLinkProvider.ts index 6e4d1c6dc..282a034c4 100644 --- a/lib/linkProviders/table/tableLinkProvider.ts +++ b/lib/linkProviders/table/tableLinkProvider.ts @@ -28,7 +28,7 @@ import { CorporateTableLink } from './tableLink'; import { ILinkProvider } from '..'; import tableEntity from '../../tableEntity'; -import { ErrorHelper } from '../../../transitional'; +import { ErrorHelper } from '../../transitional'; import { decryptEntityAsync, encryptEntityAsync, IEncryptionOptions } from '../../encryption'; import { IKeyVaultSecretResolver } from '../../keyVaultResolver'; diff --git a/lib/mailProvider/index.ts b/lib/mailProvider/index.ts index a334f0340..6ddac4228 100644 --- a/lib/mailProvider/index.ts +++ b/lib/mailProvider/index.ts @@ -3,6 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { promises as fs } from 'fs'; +import { randomUUID } from 'crypto'; + import MockMailService from './mockMailService'; import SmtpMailService from './smtpMailService'; import AzureServiceBus from './azureServiceBus'; @@ -20,6 +23,46 @@ export interface IMail { correlationId?: string; senderProfile?: string; replyTo?: string; + attachments?: MailAttachment[]; + linkedResources?: MailAttachment[]; +} + +export type MailAttachment = { + name: string; + contentId: string; + contentType: string; + base64Value: string; +}; + +export async function createMailAttachment( + localPath: string, + name: string, + contentType: string, + contentId?: string +): Promise { + const realContentId = contentId || randomUUID(); + const content = await fs.readFile(localPath, 'base64'); + return { + name, + contentId: realContentId, + contentType, + base64Value: content, + }; +} + +export function createMailAttachmentFromBase64( + base64contents: string, + name: string, + contentType: string, + contentId?: string +): MailAttachment { + const realContentId = contentId || randomUUID(); + return { + name, + contentId: realContentId, + contentType, + base64Value: base64contents, + }; } export interface IMailProvider { diff --git a/lib/pugViewServices.ts b/lib/pugViewServices.ts index 2fcd7a98b..cf91bb7c9 100644 --- a/lib/pugViewServices.ts +++ b/lib/pugViewServices.ts @@ -5,7 +5,7 @@ import _ from 'lodash'; import moment from 'moment'; -import octicons from 'octicons'; //const octicons = require('octicons'); +import octicons from '@primer/octicons'; import fileSize from 'file-size'; import languageMap from 'language-map'; import validator from 'validator'; diff --git a/transitional.ts b/lib/transitional.ts similarity index 75% rename from transitional.ts rename to lib/transitional.ts index b2bc2813b..e0806ba54 100644 --- a/transitional.ts +++ b/lib/transitional.ts @@ -7,19 +7,22 @@ import crypto from 'crypto'; import githubUsernameRegex from 'github-username-regex'; import { AxiosError } from 'axios'; -import appPackage from './package.json'; -import type { ICreateRepositoryApiResult } from './api/createRepo'; -import { Repository } from './business/repository'; +import appPackage from '../package.json'; +import type { ICreateRepositoryApiResult } from '../api/createRepo'; +import { Repository } from '../business/repository'; import { GitHubRepositoryPermission, - IDictionary, - IFunctionPromise, - IProviders, - ISettledValue, - ReposAppRequest, + type ICorporateLink, + type IDictionary, + type IFunctionPromise, + type IGitHubCollaboratorPermissions, + type IProviders, + type ISettledValue, + type ReposAppRequest, SettledState, -} from './interfaces'; -import { Organization } from './business'; +} from '../interfaces'; +import { ITeamRepositoryPermission, Organization } from '../business'; +import { ILinkProvider } from './linkProviders'; const packageVariableName = 'static-react-package-name'; export function hasStaticReactClientApp() { @@ -53,19 +56,34 @@ export function SettleToStateValue(promise: Promise): Promise { + return new Promise((resolve, reject) => { + const chunks: Buffer[] = []; + readableStream.on('data', (data: Buffer | string) => { + chunks.push(data instanceof Buffer ? data : Buffer.from(data)); + }); + readableStream.on('end', () => { + resolve(Buffer.concat(chunks)); + }); + readableStream.on('error', reject); + }); } export function isPermissionBetterThan( @@ -75,8 +93,8 @@ export function isPermissionBetterThan( if (!currentBest) { return true; } - const comparison = MassagePermissionsToGitHubRepositoryPermission(currentBest); - switch (MassagePermissionsToGitHubRepositoryPermission(newConsideration)) { + const comparison = projectCollaboratorPermissionToGitHubRepositoryPermission(currentBest); + switch (projectCollaboratorPermissionToGitHubRepositoryPermission(newConsideration)) { case GitHubRepositoryPermission.Admin: return true; case GitHubRepositoryPermission.Maintain: @@ -103,7 +121,9 @@ export function isPermissionBetterThan( return false; } -export function MassagePermissionsToGitHubRepositoryPermission(value: string): GitHubRepositoryPermission { +export function projectCollaboratorPermissionToGitHubRepositoryPermission( + value: string +): GitHubRepositoryPermission { // collaborator level APIs return a more generic read/write value, lead to some bad caches in the past... // TODO: support new collaboration values as they come online for Enterprise Cloud! switch (value) { @@ -120,15 +140,15 @@ export function MassagePermissionsToGitHubRepositoryPermission(value: string): G case 'read': return GitHubRepositoryPermission.Pull; default: - throw new Error( - `Invalid ${value} GitHub repository permission [massagePermissionsToGitHubRepositoryPermission]` + throw CreateError.InvalidParameters( + `Invalid ${value} GitHub repository permission [projectCollaboratorPermissionsToGitHubRepositoryPermission]` ); } } export class CreateError { - static CreateStatusCodeError(code: number, message?: string): Error { - const error = new Error(message); + static CreateStatusCodeError(code: number, message?: string, cause?: Error): Error { + const error = cause ? new Error(message, { cause }) : new Error(message); error['status'] = code; return error; } @@ -150,16 +170,20 @@ export class CreateError { return ErrorHelper.SetInnerError(CreateError.CreateStatusCodeError(400, message), innerError); } - static NotAuthenticated(message: string): Error { - return CreateError.CreateStatusCodeError(401, message); + static NotAuthenticated(message: string, cause?: Error): Error { + return CreateError.CreateStatusCodeError(401, message, cause); } - static NotAuthorized(message: string): Error { - return CreateError.CreateStatusCodeError(403, message); + static NotImplemented(message?: string, cause?: Error): Error { + return CreateError.CreateStatusCodeError(500, message || 'This scenario is not yet implemented', cause); } - static ServerError(message: string, innerError?: Error): Error { - return ErrorHelper.SetInnerError(CreateError.CreateStatusCodeError(500, message), innerError); + static NotAuthorized(message: string, cause?: Error): Error { + return CreateError.CreateStatusCodeError(403, message, cause); + } + + static ServerError(message: string, cause?: Error): Error { + return CreateError.CreateStatusCodeError(500, message, cause); } } @@ -193,6 +217,11 @@ export class ErrorHelper { return statusNumber && statusNumber === 404; } + public static IsServerError(error: Error): boolean { + const statusNumber = ErrorHelper.GetStatus(error); + return statusNumber && statusNumber >= 500; + } + public static IsNotAuthorized(error: Error): boolean { const statusNumber = ErrorHelper.GetStatus(error); return statusNumber && statusNumber === 403; @@ -230,9 +259,6 @@ export class ErrorHelper { if (asAny?.statusCode && typeof asAny.statusCode === 'number') { return asAny.statusCode as number; } - if (asAny?.code && typeof asAny.code === 'number') { - return asAny.code as number; - } if (asAny?.status) { const status = asAny.status; const type = typeof status; @@ -245,6 +271,9 @@ export class ErrorHelper { return null; } } + if (asAny?.code && typeof asAny.code === 'number') { + return asAny.code as number; + } return null; } } @@ -272,11 +301,29 @@ export function stripDistFolderName(dirname: string) { return dirname; } +export function getSafeCosmosResourceKey(key: string) { + return key.replace(/[%:\\/?#]/g, ''); +} + export function sha256(str: string) { const hash = crypto.createHash('sha256').update(str).digest('base64'); return hash; } +export async function getThirdPartyLinkById( + linkProvider: ILinkProvider, + thirdPartyId: string | number +): Promise { + try { + return await linkProvider.getByThirdPartyId(String(thirdPartyId)); + } catch (error) { + if (ErrorHelper.IsNotFound(error)) { + return null; + } + throw error; + } +} + export interface ICustomizedNewRepositoryLogic { createContext(req: any): INewRepositoryContext; getAdditionalTelemetryProperties(context: INewRepositoryContext): IDictionary; diff --git a/utils.ts b/lib/utils.ts similarity index 90% rename from utils.ts rename to lib/utils.ts index 514b95476..d1935884c 100644 --- a/utils.ts +++ b/lib/utils.ts @@ -8,15 +8,19 @@ import fs from 'fs'; import path from 'path'; import { URL } from 'url'; import zlib from 'zlib'; -import { type Repository } from './business/repository'; -import { ReposAppRequest, IAppSession, IReposError, SiteConfiguration } from './interfaces'; +import { type Repository } from '../business/repository'; +import type { ReposAppRequest, IAppSession, IReposError, SiteConfiguration } from '../interfaces'; import { getProviders } from './transitional'; export function daysInMilliseconds(days: number): number { return 1000 * 60 * 60 * 24 * days; } +export function dateToDateString(date: Date) { + return date.toISOString().substr(0, 10); +} + export function stringOrNumberAsString(value: any) { if (typeof value === 'number') { return (value as number).toString(); @@ -262,7 +266,12 @@ export function writeTextToFile(filename: string, stringContent: string): Promis }); } -export function quitInTenSeconds(successful: boolean) { +export function quitInTenSeconds(successful: boolean, config?: SiteConfiguration) { + // To allow telemetry to flush, we'll wait typically + if (config?.debug?.exitImmediately || process.env.EXIT_IMMEDIATELY === '1') { + console.log(`EXIT_IMMEDIATELY set, exiting... exit code=${successful ? 0 : 1}`); + return process.exit(successful ? 0 : 1); + } console.log(`Quitting process in 10s... exit code=${successful ? 0 : 1}`); return setTimeout(() => { process.exit(successful ? 0 : 1); @@ -354,3 +363,24 @@ export function getDateTimeBasedBlobFolder() { } export const botBracket = '[bot]'; + +const githubAvatarHostnames = [ + 'githubusercontent.com', + 'objects.githubusercontent.com', + 'object.githubusercontent.com', + 'raw.githubusercontent.com', + 'avatars.githubusercontent.com', +]; + +export function getUserIdFromWellFormedAvatar(avatar: string): string { + // https://*.githubusercontent.com/u/userid?v=* + const url = new URL(avatar); + if (githubAvatarHostnames.includes(url.hostname)) { + const { pathname } = url; + const i = pathname.indexOf('/u/'); + if (i >= 0) { + return pathname.substr(i + 3); + } + } + return null; +} diff --git a/middleware/alternateApps.ts b/middleware/alternateApps.ts index 9f6ec74ae..76e783e49 100644 --- a/middleware/alternateApps.ts +++ b/middleware/alternateApps.ts @@ -8,13 +8,13 @@ const debug = Debug.debug('startup'); import path from 'path'; -import { IApplicationProfile, IReposApplication } from '../interfaces'; +import type { ApplicationProfile, IReposApplication, SiteConfiguration } from '../interfaces'; export default async function initializeAlternateApps( - config, + config: SiteConfiguration, app: IReposApplication, appName: string -): Promise { +): Promise { const appPath = path.resolve(path.join(__dirname, '..', appName, '/')); debug(`Alternate app requested: name=${appName}, path=${appPath}`); try { diff --git a/middleware/apiAad.ts b/middleware/apiAad.ts index a44c24dc1..6968e4e49 100644 --- a/middleware/apiAad.ts +++ b/middleware/apiAad.ts @@ -3,28 +3,30 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; import jwt from 'jsonwebtoken'; import jwksClient from 'jwks-rsa'; import { isJsonError, jsonError } from './jsonError'; import { IApiRequest, wrapErrorForImmediateUserError } from './apiReposAuth'; -import { PersonalAccessToken } from '../entities/token/token'; -import { CreateError, getProviders } from '../transitional'; +import { PersonalAccessToken } from '../business/entities/token/token'; +import { CreateError, getProviders } from '../lib/transitional'; import getCompanySpecificDeployment from './companySpecificDeployment'; // CONSIDER: Caching of signing keys -export function requireAadApiAuthorizedScope(scope: string) { - return (req: IApiRequest, res, next) => { +export function requireAadApiAuthorizedScope(scope: string | string[]) { + return (req: IApiRequest, res: Response, next: NextFunction) => { const { apiKeyToken } = req; - if (!apiKeyToken.hasScope(scope)) { + const scopes = typeof scope === 'string' ? [scope] : scope; + if (!apiKeyToken.hasAnyScope(scopes)) { return next(jsonError(`Not authorized for ${scope}`, 403)); } return next(); }; } -export default function aadApiMiddleware(req: IApiRequest, res, next) { +export default function aadApiMiddleware(req: IApiRequest, res: Response, next: NextFunction) { return validateAadAuthorization(req) .then((ok) => { return next(); @@ -33,7 +35,7 @@ export default function aadApiMiddleware(req: IApiRequest, res, next) { if ((err as any).immediate === true) { console.warn(`AAD API authorization failed: ${err}`); } - return isJsonError(err) ? next(err) : jsonError(err, 500); + return isJsonError(err, req.url) ? next(err) : (jsonError(err, 500) as unknown); }); } @@ -121,20 +123,37 @@ async function validateAadAuthorization(req: IApiRequest): Promise { } const { appid, oid } = payload as any; - let approvedAppMonikerId = await aadApiValidator.getAuthorizedClientIdToken(appid); - if (!approvedAppMonikerId) { - approvedAppMonikerId = await aadApiValidator.getAuthorizedObjectIdToken(oid); + const monikerSources = []; + const approvedAppMonikerClientId = await aadApiValidator.getAuthorizedClientIdToken(appid); + if (approvedAppMonikerClientId) { + monikerSources.push('client'); + } + const approvedAppMonikerObjectId = await aadApiValidator.getAuthorizedObjectIdToken(oid); + if (approvedAppMonikerObjectId) { + monikerSources.push('object'); } - const notAuthorized = !approvedAppMonikerId; + const notAuthorized = !approvedAppMonikerClientId && !approvedAppMonikerObjectId; if (notAuthorized) { throw wrapErrorForImmediateUserError( jsonError(`App ${appid} and object ID ${oid} is not authorized for this API endpoint`, 403) ); } - const scopes = await aadApiValidator.getScopes(approvedAppMonikerId); - const displayValues = await aadApiValidator.getDisplayValues(approvedAppMonikerId); + const scopesSet = new Set(); + if (approvedAppMonikerClientId) { + const clientIdScopes = await aadApiValidator.getScopes(approvedAppMonikerClientId); + clientIdScopes.forEach((s) => scopesSet.add(s)); + } + if (approvedAppMonikerObjectId) { + const objectIdScopes = await aadApiValidator.getScopes(approvedAppMonikerObjectId); + objectIdScopes.forEach((s) => scopesSet.add(s)); + } + const scopes = Array.from(scopesSet); + + const displayValues = await aadApiValidator.getDisplayValues( + approvedAppMonikerClientId || approvedAppMonikerObjectId + ); const apiToken = PersonalAccessToken.CreateFromAadAuthorization( { @@ -151,6 +170,7 @@ async function validateAadAuthorization(req: IApiRequest): Promise { name: 'ApiAadAppAuthorized', properties: Object.assign({}, decodedToken as any, { authorizedScopes: scopes.join(','), + monikerSources: monikerSources.join(','), }), }); } catch (error) { diff --git a/middleware/apiReposAuth.ts b/middleware/apiReposAuth.ts index f6c17f786..ff26109de 100644 --- a/middleware/apiReposAuth.ts +++ b/middleware/apiReposAuth.ts @@ -11,10 +11,11 @@ import basicAuth from 'basic-auth'; import crypto from 'crypto'; +import { NextFunction, Response } from 'express'; import { jsonError } from './jsonError'; -import { getProviders } from '../transitional'; -import { PersonalAccessToken } from '../entities/token/token'; +import { getProviders } from '../lib/transitional'; +import { PersonalAccessToken } from '../business/entities/token/token'; import { ReposAppRequest } from '../interfaces'; export const wrapErrorForImmediateUserError = (err: Error) => { @@ -30,7 +31,7 @@ export interface IApiRequest extends ReposAppRequest { userContextOverwriteRequest?: any; // refactor? } -export default function ReposApiAuthentication(req: IApiRequest, res, next) { +export default function ReposApiAuthentication(req: IApiRequest, res: Response, next: NextFunction) { const user = basicAuth(req); const key = user ? user.pass || user.name : null; if (!key) { diff --git a/middleware/apiVstsAuth.ts b/middleware/apiVstsAuth.ts index 694e2af72..d34b6f67d 100644 --- a/middleware/apiVstsAuth.ts +++ b/middleware/apiVstsAuth.ts @@ -5,16 +5,17 @@ import axios from 'axios'; import asyncHandler from 'express-async-handler'; +import { NextFunction, Response } from 'express'; import { jsonError } from './jsonError'; import { IApiRequest } from './apiReposAuth'; -import { PersonalAccessToken } from '../entities/token/token'; -import { getProviders } from '../transitional'; +import { PersonalAccessToken } from '../business/entities/token/token'; +import { getProviders } from '../lib/transitional'; // TODO: consider better caching const localMemoryCacheVstsToAadId = new Map(); -const vstsAuth = asyncHandler(async (req: IApiRequest, res, next) => { +const vstsAuth = asyncHandler(async (req: IApiRequest, res: Response, next: NextFunction) => { const config = getProviders(req).config; if (!config) { return next(new Error('Missing configuration for the application')); diff --git a/middleware/appInsights.ts b/middleware/appInsights.ts index 11c01d0e8..f3c4051c0 100644 --- a/middleware/appInsights.ts +++ b/middleware/appInsights.ts @@ -3,13 +3,21 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import wrapOrCreateInsightsConsoleClient from '../lib/insights'; import Debug from 'debug'; const debug = Debug.debug('startup'); import { setup as appInsightsSetup, defaultClient } from 'applicationinsights'; -import { IReposApplication, IProviders, ReposAppRequest } from '../interfaces'; +import type { + IReposApplication, + IProviders, + ReposAppRequest, + SiteConfiguration, + ExecutionEnvironment, +} from '../interfaces'; function ignoreKubernetesProbes(envelope /* , context */) { if ('RequestData' === envelope.data.baseType) { @@ -42,20 +50,22 @@ function filterTelemetry(envelope, context): boolean { return true; } -export default function initializeAppInsights(app: IReposApplication, config) { +export default function initializeAppInsights( + providers: IProviders, + executionEnvironment: ExecutionEnvironment, + app: IReposApplication, + config: SiteConfiguration +) { let client = undefined; if (!config) { // Configuration failure happened ahead of this module return; } - const providers = app.settings.providers as IProviders; let cs: string = config?.telemetry?.applicationInsightsConnectionString || config?.telemetry?.applicationInsightsKey; // Override the key with a job-specific one if this is a job execution instead - const jobCs: string = - config?.telemetry?.jobsApplicationInsightsConnectionString || - config?.telemetry?.jobsApplicationInsightsKey; - if (jobCs && config.isJobInternal === true) { + const jobCs: string = config?.telemetry?.jobsApplicationInsightsConnectionString; + if (jobCs && executionEnvironment.isJob === true) { cs = jobCs; } if (cs) { @@ -78,7 +88,7 @@ export default function initializeAppInsights(app: IReposApplication, config) { debug('insights telemetry is not configured with a key or connection string'); } - app.use((req: ReposAppRequest, res, next) => { + app?.use((req: ReposAppRequest, res: Response, next: NextFunction) => { // Acknowledge synthetic tests immediately without spending time in more middleware if ( req.headers && diff --git a/middleware/business/administration.ts b/middleware/business/administration.ts index 38e11a052..7b192cd09 100644 --- a/middleware/business/administration.ts +++ b/middleware/business/administration.ts @@ -3,14 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; -const router: Router = Router(); +import { NextFunction, Response, Router } from 'express'; import { ReposAppRequest } from '../../interfaces'; -import { wrapError } from '../../utils'; +import { wrapError } from '../../lib/utils'; -function denyRoute(next) { +function denyRoute(next: NextFunction) { next( wrapError( null, @@ -20,7 +19,11 @@ function denyRoute(next) { ); } -export function requirePortalAdministrationPermission(req: ReposAppRequest, res, next) { +export function requirePortalAdministrationPermission( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { req.individualContext .isPortalAdministrator() .then((isAdmin) => { diff --git a/middleware/business/allLinks.ts b/middleware/business/allLinks.ts index c25f57df3..ece49af9a 100644 --- a/middleware/business/allLinks.ts +++ b/middleware/business/allLinks.ts @@ -3,13 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; -import { wrapError } from '../../utils'; +import { getProviders } from '../../lib/transitional'; +import { wrapError } from '../../lib/utils'; const cachedLinksRequestKeyName = 'cachedLinks'; -export async function ensureAllLinksInMemory(req: ReposAppRequest, res, next) { +export async function ensureAllLinksInMemory(req: ReposAppRequest, res: Response, next: NextFunction) { if (req[cachedLinksRequestKeyName]) { return next(); } diff --git a/middleware/business/authentication.ts b/middleware/business/authentication.ts index 2c371c112..b0efa15a7 100644 --- a/middleware/business/authentication.ts +++ b/middleware/business/authentication.ts @@ -3,30 +3,32 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { Response, NextFunction } from 'express'; + import { ReposAppRequest, IAppSession } from '../../interfaces'; import Debug from 'debug'; const debug = Debug.debug('user'); -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { ICorporateIdentity, IGitHubIdentity, IndividualContext, GitHubIdentitySource, } from '../../business/user'; -import { storeOriginalUrlAsReferrer } from '../../utils'; +import { storeOriginalUrlAsReferrer } from '../../lib/utils'; import getCompanySpecificDeployment from '../companySpecificDeployment'; export async function requireAuthenticatedUserOrSignInExcluding( exclusionPaths: string[], req: ReposAppRequest, - res, - next + res: Response, + next: NextFunction ) { - const baseUrl = req.baseUrl; + const url = req.url; for (let i = 0; i < exclusionPaths.length; i++) { - if (baseUrl.startsWith(exclusionPaths[i])) { + if (url.startsWith(exclusionPaths[i])) { console.log(`${req.method} ${req.baseUrl} excluded from auth by prefix: ${exclusionPaths[i]}`); return next(); } @@ -34,7 +36,7 @@ export async function requireAuthenticatedUserOrSignInExcluding( return await requireAuthenticatedUserOrSignIn(req, res, next); } -export async function requireAccessTokenClient(req: ReposAppRequest, res, next) { +export async function requireAccessTokenClient(req: ReposAppRequest, res: Response, next: NextFunction) { if (req.oauthAccessToken) { return next(); } @@ -63,7 +65,7 @@ export async function requireAccessTokenClient(req: ReposAppRequest, res, next) return next(); } -function signoutThenSignIn(req: ReposAppRequest, res) { +function signoutThenSignIn(req: ReposAppRequest, res: Response) { const { insights } = getProviders(req); req.logout({ keepSessionInfo: false }, (err) => { if (err) { @@ -73,7 +75,7 @@ function signoutThenSignIn(req: ReposAppRequest, res) { }); } -function redirectToSignIn(req, res) { +function redirectToSignIn(req: ReposAppRequest, res: Response) { const config = getProviders(req).config; storeOriginalUrlAsReferrer( req, @@ -83,7 +85,11 @@ function redirectToSignIn(req, res) { ); } -export async function requireAuthenticatedUserOrSignIn(req: ReposAppRequest, res, next) { +export async function requireAuthenticatedUserOrSignIn( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { const companySpecific = getCompanySpecificDeployment(); const providers = getProviders(req); const { config } = providers; @@ -111,7 +117,7 @@ export async function requireAuthenticatedUserOrSignIn(req: ReposAppRequest, res return shouldRedirectToSignIn ? redirectToSignIn(req, res) : next(); } -export function setIdentity(req: ReposAppRequest, res, next) { +export function setIdentity(req: ReposAppRequest, res: Response, next: NextFunction) { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; if (!activeContext) { return next(new Error('No context available')); diff --git a/middleware/business/corporateAdministrators.ts b/middleware/business/corporateAdministrators.ts index b36e9b391..07e2f5795 100644 --- a/middleware/business/corporateAdministrators.ts +++ b/middleware/business/corporateAdministrators.ts @@ -6,17 +6,19 @@ // This route does not use GitHub as a source of truth but instead falls back to // corporate assigned usernames or security group membership. +import { NextFunction, Response } from 'express'; + import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { IndividualContext } from '../../business/user'; -import { wrapError } from '../../utils'; +import { wrapError } from '../../lib/utils'; import { jsonError } from '../jsonError'; export interface IReposAppRequestWithSystemAdministration extends ReposAppRequest { isSystemAdministrator: boolean; } -function denyRoute(next, isApi: boolean) { +function denyRoute(next: NextFunction, isApi: boolean) { if (isApi) { return next(jsonError('This API is unavailable for you', 403)); } @@ -29,7 +31,11 @@ function denyRoute(next, isApi: boolean) { ); } -export async function AuthorizeOnlyCorporateAdministrators(req: ReposAppRequest, res, next) { +export async function AuthorizeOnlyCorporateAdministrators( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { const { operations } = getProviders(req); const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const corporateId = activeContext.corporateIdentity?.id; @@ -42,8 +48,8 @@ export async function AuthorizeOnlyCorporateAdministrators(req: ReposAppRequest, export async function checkIsCorporateAdministrator( req: IReposAppRequestWithSystemAdministration, - res, - next + res: Response, + next: NextFunction ) { await getIsCorporateAdministrator(req); return next(); diff --git a/middleware/business/corporateAlias.ts b/middleware/business/corporateAlias.ts index 7221975ff..78b451f82 100644 --- a/middleware/business/corporateAlias.ts +++ b/middleware/business/corporateAlias.ts @@ -5,7 +5,7 @@ import { jsonError } from '..'; import { IProviders, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { IndividualContext } from '../../business/user'; const cachedCorporateAliasRequestKey = '__corporateAlias'; diff --git a/middleware/business/corporateHierarchy.ts b/middleware/business/corporateHierarchy.ts index 77b0e40fc..ed38c588d 100644 --- a/middleware/business/corporateHierarchy.ts +++ b/middleware/business/corporateHierarchy.ts @@ -6,7 +6,7 @@ import { jsonError } from '..'; import { IProviders, ReposAppRequest } from '../../interfaces'; import { IGraphEntry } from '../../lib/graphProvider'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { IndividualContext } from '../../business/user'; const cachedCorporateHierarchyRequestKey = '__corporateTree'; diff --git a/middleware/business/corporateMail.ts b/middleware/business/corporateMail.ts index fd6a2a5ab..72b294801 100644 --- a/middleware/business/corporateMail.ts +++ b/middleware/business/corporateMail.ts @@ -5,7 +5,7 @@ import { jsonError } from '..'; import { IProviders, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { ErrorHelper, getProviders } from '../../lib/transitional'; import { IndividualContext } from '../../business/user'; const cachedCorporateMailRequestKey = '__corporateMail'; @@ -25,18 +25,31 @@ export async function getCorporateMailFromActiveContext( providers: IProviders, activeContext: IndividualContext ): Promise { - const { graphProvider } = providers; if (!activeContext.corporateIdentity || !activeContext.corporateIdentity.id) { throw jsonError('No corporate identity', 401); } let corporateMail = activeContext?.link?.corporateMailAddress; if (!corporateMail) { - const id = activeContext.corporateIdentity.id; - const entry = await graphProvider.getUserById(id); - if (!entry || !entry.mailNickname) { + const mail = await tryGetCorporateMailFromId(providers, activeContext.corporateIdentity.id); + if (!mail) { throw jsonError('Invalid corporate identity', 401); } - corporateMail = entry.mail; + corporateMail = mail; } return corporateMail; } + +export async function tryGetCorporateMailFromId(providers: IProviders, corporateId: string): Promise { + const { graphProvider } = providers; + try { + const info = await graphProvider.getUserById(corporateId); + if (info?.mail) { + return info.mail; + } + } catch (error) { + if (!ErrorHelper.IsNotFound(error)) { + throw error; + } + } + return null; +} diff --git a/middleware/business/employeesOnly.ts b/middleware/business/employeesOnly.ts index ed6bb588f..3689147a4 100644 --- a/middleware/business/employeesOnly.ts +++ b/middleware/business/employeesOnly.ts @@ -5,9 +5,15 @@ // This is a Microsoft-specific piece of middleware. +import { NextFunction, Response } from 'express'; + import { ReposAppRequest } from '../../interfaces'; -export function AuthorizeOnlyFullTimeEmployeesAndInterns(req: ReposAppRequest, res, next) { +export function AuthorizeOnlyFullTimeEmployeesAndInterns( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { const individualContext = req.individualContext; if (!individualContext.corporateIdentity || !individualContext.corporateIdentity.username) { return next(new Error('This resource is only available to authenticated users.')); diff --git a/middleware/links/index.ts b/middleware/business/links.ts similarity index 90% rename from middleware/links/index.ts rename to middleware/business/links.ts index b0f24d8e1..2ff7e2a68 100644 --- a/middleware/links/index.ts +++ b/middleware/business/links.ts @@ -6,19 +6,25 @@ // Within the context, tries to resolve a link if it _can_. It does not force that a user is linked! import { IndividualContext } from '../../business/user'; -import { getProviders } from '../../transitional'; -import { wrapError } from '../../utils'; +import { getProviders } from '../../lib/transitional'; +import { wrapError } from '../../lib/utils'; import { ReposAppRequest, IReposError } from '../../interfaces'; +import { NextFunction, Response } from 'express'; export function RequireLinkMatchesGitHubSessionExceptPrefixedRoute(prefix: string) { return requireLinkMatchesGitHubSession.bind(null, prefix); } -export function RequireLinkMatchesGitHubSession(req: ReposAppRequest, res, next) { +export function RequireLinkMatchesGitHubSession(req: ReposAppRequest, res: Response, next: NextFunction) { return requireLinkMatchesGitHubSession(null, req, res, next); } -function requireLinkMatchesGitHubSession(allowedPrefix: string, req: ReposAppRequest, res, next) { +function requireLinkMatchesGitHubSession( + allowedPrefix: string, + req: ReposAppRequest, + res: Response, + next: NextFunction +) { // trying to be equivalent to legacy code in ./usernameConsistency (lightweight) const context = req.individualContext; if (!context) { @@ -67,7 +73,7 @@ function requireLinkMatchesGitHubSession(allowedPrefix: string, req: ReposAppReq return next(securityError); } -export async function AddLinkToRequest(req, res, next) { +export async function AddLinkToRequest(req, res: Response, next: NextFunction) { const activeContext = (req.individualContext || req.apiContext) as IndividualContext; const contextName = req.individualContext ? 'Individual User Context' : 'API Context'; if (!activeContext) { diff --git a/middleware/business/organization.ts b/middleware/business/organization.ts index 04ff3a199..b5872dc00 100644 --- a/middleware/business/organization.ts +++ b/middleware/business/organization.ts @@ -3,8 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { ReposAppRequest } from '../../interfaces/web'; import { jsonError } from '../jsonError'; +import { CreateError, ErrorHelper, getProviders } from '../../lib/transitional'; +import { setOrganizationProfileForRequest } from '../github/ensureOrganizationProfile'; export enum OrganizationManagementType { Managed = 'managed', @@ -21,7 +25,11 @@ export function getOrganizationManagementType(req: IReposAppRequestWithOrganizat return req.organizationManagementType; } -export function blockIfUnmanagedOrganization(req: IReposAppRequestWithOrganizationManagementType, res, next) { +export function blockIfUnmanagedOrganization( + req: IReposAppRequestWithOrganizationManagementType, + res: Response, + next: NextFunction +) { const managementType = getOrganizationManagementType(req); switch (managementType) { case OrganizationManagementType.Unmanaged: @@ -32,3 +40,38 @@ export function blockIfUnmanagedOrganization(req: IReposAppRequestWithOrganizati return next(jsonError('unknown organization management type', 500)); } } + +export async function apiMiddlewareOrganizationsToOrganization( + req: IReposAppRequestWithOrganizationManagementType, + res: Response, + next: NextFunction +) { + const { operations } = getProviders(req); + const { orgName } = req.params; + req.organizationName = orgName; + try { + const org = operations.getOrganization(orgName); + if (org) { + req.organizationManagementType = OrganizationManagementType.Managed; + req.organization = org; + return next(); + } + } catch (orgNotFoundError) { + if (!ErrorHelper.IsNotFound(orgNotFoundError)) { + return next(orgNotFoundError); + } + } + try { + const org = operations.getUncontrolledOrganization(orgName); + req.organizationManagementType = OrganizationManagementType.Unmanaged; + req.organization = org; + await setOrganizationProfileForRequest(req); + } catch (orgProfileError) { + if (ErrorHelper.IsNotFound(orgProfileError)) { + return next(CreateError.NotFound(`The organization ${orgName} does not exist`)); + } else { + return next(orgProfileError); + } + } + return next(); +} diff --git a/middleware/business/repository.ts b/middleware/business/repository.ts new file mode 100644 index 000000000..d93618313 --- /dev/null +++ b/middleware/business/repository.ts @@ -0,0 +1,34 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import { NextFunction, Response } from 'express'; + +import { Repository } from '../../business/repository'; +import type { ReposAppRequest } from '../../interfaces/web'; +import { CreateError } from '../../lib/transitional'; + +export type RequestWithRepo = ReposAppRequest & { + repository: Repository; +}; + +export async function apiMiddlewareRepositoriesToRepository( + req: RequestWithRepo, + res: Response, + next: NextFunction +) { + const { organization } = req; + if (!organization) { + return next(CreateError.InvalidParameters('No organization instance available')); + } + + const { repoName } = req.params; + if (!repoName) { + return next(CreateError.InvalidParameters('No repository name provided')); + } + + // does not confirm the name + req.repository = organization.repository(repoName); + return next(); +} diff --git a/middleware/business/setContext.ts b/middleware/business/setContext.ts index 9b2d90794..37d8a34e2 100644 --- a/middleware/business/setContext.ts +++ b/middleware/business/setContext.ts @@ -3,6 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; import { IndividualContext, IIndividualContextOptions, @@ -11,9 +12,10 @@ import { SessionUserProperties, WebApiContext, } from '../../business/user'; -import { getProviders } from '../../transitional'; +import { ReposAppRequest } from '../../interfaces'; +import { getProviders } from '../../lib/transitional'; -export function webContextMiddleware(req, res, next) { +export function webContextMiddleware(req: ReposAppRequest, res: Response, next: NextFunction) { const { operations, insights } = getProviders(req); if (req.apiContext) { const msg = 'INVALID: API and web contexts should not be mixed'; @@ -46,7 +48,7 @@ export function webContextMiddleware(req, res, next) { return next(); } -export function apiContextMiddleware(req, res, next) { +export function apiContextMiddleware(req, res: Response, next: NextFunction) { const { operations, insights } = getProviders(req); if (req.individualContext) { const msg = 'INVALID: API and web contexts should not be mixed'; diff --git a/middleware/business/userSettings.ts b/middleware/business/userSettings.ts new file mode 100644 index 000000000..8ab028405 --- /dev/null +++ b/middleware/business/userSettings.ts @@ -0,0 +1,41 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import type { NextFunction, Response } from 'express'; + +import type { ReposAppRequestWithUserSettings } from '../../interfaces/middleware'; + +import { UserSettings } from '../../business/entities/userSettings'; +import { ErrorHelper, getProviders } from '../../lib/transitional'; +import { IndividualContext } from '../../business/user'; + +export async function getUserSettings( + req: ReposAppRequestWithUserSettings, + res: Response, + next: NextFunction +) { + const activeContext = (req.individualContext || req.apiContext) as IndividualContext; + const corporateId = activeContext?.corporateIdentity?.id; + const { userSettingsProvider } = getProviders(req); + if (corporateId && !req.userSettings) { + let settings: UserSettings = null; + try { + settings = await userSettingsProvider.getUserSettings(corporateId); + } catch (notFoundError) { + if (ErrorHelper.IsNotFound(notFoundError)) { + // ignore + } else { + throw notFoundError; + } + } + if (!settings) { + settings = new UserSettings(); + settings.corporateId = corporateId; + await userSettingsProvider.insertUserSettings(settings); + } + req.userSettings = settings; + } + return next(); +} diff --git a/middleware/campaign.ts b/middleware/campaign.ts index f1278f930..2d8fd77da 100644 --- a/middleware/campaign.ts +++ b/middleware/campaign.ts @@ -3,7 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { getProviders } from '../transitional'; +import { NextFunction, Response } from 'express'; + +import { getProviders } from '../lib/transitional'; interface ICampaignData { uri?: any; @@ -23,7 +25,7 @@ export default function initializeCampaigns(app) { // come through the app. app.use('*', campaignMiddleware); - function campaignMiddleware(req, res, next) { + function campaignMiddleware(req, res: Response, next: NextFunction) { process.nextTick(processCampaignTelemetry.bind(null, req)); // Immediate return to keep middleware going diff --git a/middleware/codespaces.ts b/middleware/codespaces.ts index 46e4e9c00..4a38fc2c1 100644 --- a/middleware/codespaces.ts +++ b/middleware/codespaces.ts @@ -3,13 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { ReposAppRequest } from '../interfaces'; // Assistant for when using Visual Studio Code to connect to a Codespace // locally instead of the web. The default port forwarding experience is // to toast the user to browse to 127.0.0.1:3000, but since AAD does not // allow for IP-based callback URLs, the user must use localhost. -export function codespacesDevAssistant(req: ReposAppRequest, res, next) { +export function codespacesDevAssistant(req: ReposAppRequest, res: Response, next: NextFunction) { if (req.hostname === '127.0.0.1') { console.warn( `${req.method} ${req.url}: WARNING: You're trying to connect to ${req.hostname} from your codespace.` diff --git a/middleware/companySpecificDeployment.ts b/middleware/companySpecificDeployment.ts index d42009bff..14d38df2a 100644 --- a/middleware/companySpecificDeployment.ts +++ b/middleware/companySpecificDeployment.ts @@ -18,13 +18,13 @@ function getCompanySpecificDeploymentName() { } function getCompanySpecificDeployment(): ICompanySpecificStartup { + if (instance) { + return instance; + } const name = getCompanySpecificDeploymentName(); if (!name) { return null; } - if (instance) { - return instance; - } try { const pn = path.join(__dirname, '..', name); const dynamicInclude = require(pn); diff --git a/middleware/corporateViews.ts b/middleware/corporateViews.ts index 4f16ef7f0..24b53f8bb 100644 --- a/middleware/corporateViews.ts +++ b/middleware/corporateViews.ts @@ -7,7 +7,7 @@ import { constants as fsConstants, promises as fs } from 'fs'; import path from 'path'; import { IProviders } from '../interfaces'; -import { stripDistFolderName } from '../transitional'; +import { stripDistFolderName } from '../lib/transitional'; // providers.corporateViews: // --- diff --git a/middleware/correlationId.ts b/middleware/correlationId.ts index df5b433a7..9f491d1a5 100644 --- a/middleware/correlationId.ts +++ b/middleware/correlationId.ts @@ -3,10 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Request, Response } from 'express'; import { randomUUID } from 'crypto'; +export type WithCorrelationId = T & { + correlationId?: string; +}; + // Generate a correlation ID -export default function (req, res, next) { +export default function (req: WithCorrelationId, res: Response, next: NextFunction) { req.correlationId = randomUUID(); return next(); } diff --git a/middleware/errorHandler.ts b/middleware/errorHandler.ts index 7277cc666..dcfd64194 100644 --- a/middleware/errorHandler.ts +++ b/middleware/errorHandler.ts @@ -6,9 +6,11 @@ import querystring from 'querystring'; import { AxiosError } from 'axios'; -import { wrapError } from '../utils'; -import { getProviders } from '../transitional'; +import { wrapError } from '../lib/utils'; +import { getProviders } from '../lib/transitional'; import { isJsonError } from '.'; +import { NextFunction, Response } from 'express'; +import { ReposAppRequest } from '../interfaces'; function redactRootPathsFromString(string, path) { if (typeof string === 'string' && string.includes && string.split) { @@ -49,9 +51,16 @@ const exceptionFieldsOfInterest = [ 'innerMessage', ]; -export default function SiteErrorHandler(err, req, res, next) { +export default function SiteErrorHandler( + error: unknown, + req: ReposAppRequest, + res: Response, + next: NextFunction +) { + let err = error as any; + const isJson = isJsonError(err, req.url); // CONSIDER: Let's eventually decouple all of our error message improvements to another area to keep the error handler intact. - const { applicationProfile, config } = getProviders(req); + const { applicationProfile, config, insights } = getProviders(req); const correlationId = req.correlationId; const errorStatus = err ? err.status || err.statusCode : undefined; // Per GitHub: https://developer.github.com/v3/oauth/#bad-verification-code @@ -63,8 +72,8 @@ export default function SiteErrorHandler(err, req, res, next) { err.oauthError.message === 'The code passed is incorrect or expired.')) && req.scrubbedUrl.startsWith('/auth/github/') ) { - req.insights.trackMetric({ name: 'GitHubInvalidExpiredCodeRedirect', value: 1 }); - req.insights.trackEvent({ name: 'GitHubInvalidExpiredCodeRetry' }); + insights?.trackMetric({ name: 'GitHubInvalidExpiredCodeRedirect', value: 1 }); + insights?.trackEvent({ name: 'GitHubInvalidExpiredCodeRetry' }); return res.redirect( req.scrubbedUrl === '/auth/github/callback/increased-scope?code=*****' ? '/auth/github/increased-scope' @@ -74,7 +83,7 @@ export default function SiteErrorHandler(err, req, res, next) { const isGitHubAbuseRateLimit = err && err.message && err.message.includes && err.message.includes('#abuse-rate-limits'); if (isGitHubAbuseRateLimit) { - req.insights.trackMetric({ name: 'GitHubAbuseRateLimit', value: 1 }); + insights?.trackMetric({ name: 'GitHubAbuseRateLimit', value: 1 }); } if ( err.message && @@ -82,8 +91,8 @@ export default function SiteErrorHandler(err, req, res, next) { err.message.includes('ETIMEDOUT') && (err.message.includes('192.30.253.116') || err.message.includes('192.30.253.117')) ) { - req.insights.trackMetric({ name: 'GitHubApiTimeout', value: 1 }); - req.insights.trackEvent({ name: 'GitHubApiTimeout' }); + insights?.trackMetric({ name: 'GitHubApiTimeout', value: 1 }); + insights?.trackEvent({ name: 'GitHubApiTimeout' }); err = wrapError(err, 'The GitHub API is temporarily down. Please try again soon.', false); } let primaryUserInstance = req.user ? req.user.github : null; @@ -103,7 +112,7 @@ export default function SiteErrorHandler(err, req, res, next) { stk: undefined, message: undefined, }; - if (req.insights && req.insights.trackException) { + if (insights?.trackException) { for (let i = 0; err && i < exceptionFieldsOfInterest.length; i++) { const key = exceptionFieldsOfInterest[i]; const value = err[key]; @@ -125,7 +134,7 @@ export default function SiteErrorHandler(err, req, res, next) { } if (isGitHubAbuseRateLimit) { insightsProperties.message = err.message; - req.insights.trackEvent({ + insights?.trackEvent({ name: 'GitHubAbuseRateLimitError', properties: insightsProperties, }); @@ -133,7 +142,7 @@ export default function SiteErrorHandler(err, req, res, next) { if (err && err['json']) { // not tracking jsonErrors for now, they pollute app insights } else { - req.insights.trackException({ exception: err, properties: insightsProperties }); + insights?.trackException({ exception: err, properties: insightsProperties }); } } } @@ -141,7 +150,6 @@ export default function SiteErrorHandler(err, req, res, next) { } if (err !== undefined && err.skipLog !== true) { console.log('Error: ' + (err && err.message ? err.message : 'Error is undefined.')); - const isJson = isJsonError(err); if (err.stack && !isJson) { console.error(err.stack); } @@ -234,7 +242,7 @@ export default function SiteErrorHandler(err, req, res, next) { // Support JSON-based error display for the API route, showing just a small // subset of typical view properties to share from the error instance. - if (err && err.json === true) { + if (isJson) { const safeError = { message: safeMessage, correlationId: correlationId, diff --git a/middleware/error-routes.ts b/middleware/errorRoutes.ts similarity index 74% rename from middleware/error-routes.ts rename to middleware/errorRoutes.ts index f5f621d02..f0b92c709 100644 --- a/middleware/error-routes.ts +++ b/middleware/errorRoutes.ts @@ -3,10 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Request, Response } from 'express'; + import { IReposApplication, IReposError } from '../interfaces'; -import RouteErrorHandler from './errorHandler'; +import routeErrorHandler from './errorHandler'; export default async function configureErrorRoutes(app: IReposApplication, initializationError: Error) { + if (!app) { + return; + } if (initializationError) { console.warn('Initialization Error Present: All app requests will fail!'); @@ -14,7 +19,7 @@ export default async function configureErrorRoutes(app: IReposApplication, initi // for any request. Should evaluate whether to hide for // production scenarios or if there is a risk of the // error message leaking sensitive data. - app.use((req, res, next) => { + app.use((req: Request, res: Response, next: NextFunction) => { const error: IReposError = new Error('Application initialization error', { cause: initializationError, }); @@ -23,12 +28,12 @@ export default async function configureErrorRoutes(app: IReposApplication, initi }); } - app.use(function (req, res, next) { + app.use(function (req: Request, res: Response, next: NextFunction) { const err: IReposError = new Error('Not Found'); err.status = 404; err.skipLog = true; - next(err); + return next(err); }); - app.use(RouteErrorHandler); + app.use(routeErrorHandler); } diff --git a/middleware/github/blockEnterpriseManagedUsers.ts b/middleware/github/blockEnterpriseManagedUsers.ts index 740d11dad..b9d13c50f 100644 --- a/middleware/github/blockEnterpriseManagedUsers.ts +++ b/middleware/github/blockEnterpriseManagedUsers.ts @@ -3,10 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { ReposAppRequest, IReposError } from '../../interfaces'; -import { isEnterpriseManagedUserLogin } from '../../utils'; +import { isEnterpriseManagedUserLogin } from '../../lib/utils'; -export function blockEnterpriseManagedUsersAuthentication(req: ReposAppRequest, res, next) { +export function blockEnterpriseManagedUsersAuthentication( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { const context = req.individualContext; if (!context) { return next(new Error('Missing context')); diff --git a/middleware/github/ensureOrganizationProfile.ts b/middleware/github/ensureOrganizationProfile.ts new file mode 100644 index 000000000..7dbec0828 --- /dev/null +++ b/middleware/github/ensureOrganizationProfile.ts @@ -0,0 +1,57 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import asyncHandler from 'express-async-handler'; +import memoryCache from 'memory-cache'; +import { NextFunction, Response } from 'express'; + +import type { IReposAppRequestWithOrganizationManagementType } from '../business/organization'; +import { CreateError, getProviders } from '../../lib/transitional'; +import { + getOrganizationDetailsSanitized, + type GitHubOrganizationResponseSanitized, +} from '../../business/organization'; +import type { IProviders } from '../../interfaces'; + +export async function setOrganizationProfileForRequest(req: IReposAppRequestWithOrganizationManagementType) { + const providers = getProviders(req); + const org = req.organization; + if (!org) { + throw CreateError.InvalidParameters('No organization instance available in the request'); + } + if (!req.organizationProfile && org?.id) { + req.organizationProfile = await getOrganizationProfileViaMemoryCache(providers, String(org.id)); + } + if (!req.organizationProfile && org) { + req.organizationProfile = getOrganizationDetailsSanitized(await org.getDetails()); + } +} + +export async function getOrganizationProfileViaMemoryCache(providers: IProviders, organizationId: string) { + const { operations } = providers; + const cacheTimeMs = 1000 * 60 * 60 * 24; + + const key = `org:profile:${organizationId}`; + let profile = memoryCache.get(key) as GitHubOrganizationResponseSanitized; + if (!profile) { + const details = getOrganizationDetailsSanitized( + await operations.getOrganizationProfileById(Number(organizationId)) + ); + profile = details; + memoryCache.put(key, details, cacheTimeMs); + } + return profile; +} + +async function ensureOrganizationProfile( + req: IReposAppRequestWithOrganizationManagementType, + res: Response, + next: NextFunction +) { + await setOrganizationProfileForRequest(req); + return next(); +} + +export const ensureOrganizationProfileMiddleware = asyncHandler(ensureOrganizationProfile); diff --git a/middleware/github/orgPermissions.ts b/middleware/github/orgPermissions.ts index 9a0626211..d3a4a63a0 100644 --- a/middleware/github/orgPermissions.ts +++ b/middleware/github/orgPermissions.ts @@ -3,8 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { OrganizationMembershipState, ReposAppRequest } from '../../interfaces'; -import { wrapError } from '../../utils'; +import { wrapError } from '../../lib/utils'; const orgPermissionsCacheKeyName = 'orgPermissions'; const orgOwnersCacheKeyName = 'orgOwners'; @@ -21,7 +23,11 @@ export function GetOrganizationPermissionsFromRequest(req: ReposAppRequest) { return req[orgPermissionsCacheKeyName]; } -export async function AddOrganizationPermissionsToRequest(req: ReposAppRequest, res, next) { +export async function AddOrganizationPermissionsToRequest( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { // Only compute once per request if (req[orgPermissionsCacheKeyName]) { return next(); diff --git a/middleware/github/repoPermissions.ts b/middleware/github/repoPermissions.ts index 735f76bc1..d6c06a63a 100644 --- a/middleware/github/repoPermissions.ts +++ b/middleware/github/repoPermissions.ts @@ -3,7 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { ErrorHelper, getProviders } from '../../transitional'; +import { NextFunction, Response } from 'express'; + +import { ErrorHelper, getProviders } from '../../lib/transitional'; import { Repository } from '../../business/repository'; import { GitHubIdentitySource, IIndividualContextOptions, IndividualContext } from '../../business/user'; import getCompanySpecificDeployment from '../companySpecificDeployment'; @@ -107,30 +109,33 @@ export async function getComputedRepositoryPermissions( repoPermissions, activeContext ); - if (!activeContext.link) { - return repoPermissions; - } - repoPermissions.isLinked = true; - const login = activeContext.getGitHubIdentity().username; - const organization = repository.organization; - const isSudoer = await organization.isSudoer(login, activeContext.link); const isPortalSudoer = await activeContext.isPortalAdministrator(); - if (isSudoer === true || isPortalSudoer === true) { + if (isPortalSudoer) { repoPermissions.sudo = true; } - try { - const collaborator = await repository.getCollaborator(login); - if (collaborator) { - if (collaborator.permission === GitHubCollaboratorPermissionLevel.Admin) { - repoPermissions.admin = repoPermissions.read = repoPermissions.write = true; - } else if (collaborator.permission === GitHubCollaboratorPermissionLevel.Write) { - repoPermissions.read = repoPermissions.write = true; - } else if (collaborator.permission === GitHubCollaboratorPermissionLevel.Read) { - repoPermissions.read = true; + repoPermissions.isLinked = !!activeContext.link; + const hasGitHubIdentity = !!activeContext?.getGitHubIdentity()?.username; + if (hasGitHubIdentity) { + const login = activeContext.getGitHubIdentity().username; + const organization = repository.organization; + const isSudoer = await organization.isSudoer(login, activeContext.link); + if (isSudoer) { + repoPermissions.sudo = true; + } + try { + const collaborator = await repository.getCollaborator(login); + if (collaborator) { + if (collaborator.permission === GitHubCollaboratorPermissionLevel.Admin) { + repoPermissions.admin = repoPermissions.read = repoPermissions.write = true; + } else if (collaborator.permission === GitHubCollaboratorPermissionLevel.Write) { + repoPermissions.read = repoPermissions.write = true; + } else if (collaborator.permission === GitHubCollaboratorPermissionLevel.Read) { + repoPermissions.read = true; + } } + } catch (getCollaboratorPermissionError) { + console.dir(getCollaboratorPermissionError); } - } catch (getCollaboratorPermissionError) { - console.dir(getCollaboratorPermissionError); } if (repoPermissions.admin || repoPermissions.sudo) { repoPermissions.allowAdministration = true; @@ -145,7 +150,11 @@ export async function getComputedRepositoryPermissions( return repoPermissions; } -export async function AddRepositoryPermissionsToRequest(req: ReposAppRequest, res, next) { +export async function AddRepositoryPermissionsToRequest( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { if (req[repoPermissionsCacheKeyName]) { return next(); } diff --git a/middleware/github/requireActiveSession.ts b/middleware/github/requireActiveSession.ts index f58ac23b6..a0b46b553 100644 --- a/middleware/github/requireActiveSession.ts +++ b/middleware/github/requireActiveSession.ts @@ -3,11 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; -import { isCodespacesAuthenticating, storeOriginalUrlAsReferrer } from '../../utils'; +import { getProviders } from '../../lib/transitional'; +import { isCodespacesAuthenticating, storeOriginalUrlAsReferrer } from '../../lib/utils'; -export default function RequireActiveGitHubSession(req: ReposAppRequest, res, next) { +export default function RequireActiveGitHubSession(req: ReposAppRequest, res: Response, next: NextFunction) { const { config } = getProviders(req); const identity = req.individualContext.getSessionBasedGitHubIdentity(); if (!identity) { diff --git a/middleware/github/systemWidePermissions.ts b/middleware/github/systemWidePermissions.ts index 16d6d95cf..8787fbdc1 100644 --- a/middleware/github/systemWidePermissions.ts +++ b/middleware/github/systemWidePermissions.ts @@ -3,11 +3,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { ReposAppRequest } from '../../interfaces'; const requestCachedKeyName = 'systemWidePermissions'; -export default function addSystemWidePermissionsToRequest(req: ReposAppRequest, res, next) { +export default function addSystemWidePermissionsToRequest( + req: ReposAppRequest, + res: Response, + next: NextFunction +) { // Only compute once per request if (req[requestCachedKeyName]) { return next(); diff --git a/middleware/github/teamPermissions.ts b/middleware/github/teamPermissions.ts index 16c7317f0..0061260e5 100644 --- a/middleware/github/teamPermissions.ts +++ b/middleware/github/teamPermissions.ts @@ -3,14 +3,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { Team } from '../../business'; import { GitHubTeamRole, ITeamMembershipRoleState, + NoCacheNoBackground, OrganizationMembershipState, ReposAppRequest, } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { IndividualContext } from '../../business/user'; import getCompanySpecificDeployment from '../companySpecificDeployment'; @@ -40,10 +43,11 @@ export function getTeamMembershipFromRequest(req: ReposAppRequest) { return req[teamStatusCacheKeyName] as IRequestTeamMembershipStatus; } -export async function AddTeamMembershipToRequest(req: ReposAppRequest, res, next) { +export async function AddTeamMembershipToRequest(req: ReposAppRequest, res: Response, next: NextFunction) { if (req[teamStatusCacheKeyName]) { return next(); } + const skipCache = req.query.cache === '0'; const team2 = req['team2'] as Team; if (!team2) { return next(new Error('team2 required')); @@ -59,7 +63,9 @@ export async function AddTeamMembershipToRequest(req: ReposAppRequest, res, next } else { const login = activeContext.getGitHubIdentity().username; try { - const statusResult = await team2.getMembershipEfficiently(login); + const statusResult = skipCache + ? await team2.getMembership(login, NoCacheNoBackground) + : await team2.getMembershipEfficiently(login); const value: IRequestTeamMembershipStatus = { membershipStatus: statusResult && (statusResult as ITeamMembershipRoleState).role @@ -94,7 +100,7 @@ export function getTeamPermissionsFromRequest(req: ReposAppRequest) { return req[teamPermissionsCacheKeyName] as IRequestTeamPermissions; } -export async function AddTeamPermissionsToRequest(req: ReposAppRequest, res, next) { +export async function AddTeamPermissionsToRequest(req: ReposAppRequest, res: Response, next: NextFunction) { if (req[teamPermissionsCacheKeyName]) { return next(); } diff --git a/middleware/healthCheck.ts b/middleware/healthCheck.ts index d8997c229..858057919 100644 --- a/middleware/healthCheck.ts +++ b/middleware/healthCheck.ts @@ -5,13 +5,15 @@ import Debug from 'debug'; import { IncomingHttpHeaders } from 'http'; +import { NextFunction, Response } from 'express'; + import type { ConfiguredHeaderProbe, ConfiguredGeneralProbe, ConfiguredProbeBase, } from '../config/webHealthProbes.types'; -import { ReposAppRequest, SiteConfiguration } from '../interfaces'; -import { CreateError } from '../transitional'; +import { IReposApplication, ReposAppRequest, SiteConfiguration } from '../interfaces'; +import { CreateError } from '../lib/transitional'; const dbg = Debug.debug('health'); @@ -29,7 +31,7 @@ enum ProbeType { } export default function initializeHealthCheck( - app, + app: IReposApplication, config: SiteConfiguration /* WebHealthProbeSubsetConfiguration */ ) { const { webHealthProbes: healthConfig } = config; @@ -84,8 +86,8 @@ export default function initializeHealthCheck( probeType: ProbeType, probeConfigs: ConfiguredHeaderProbe[], req: ReposAppRequest, - res, - next + res: Response, + next: NextFunction ) { for (const probeConfig of probeConfigs) { if (requestEligibleForCheck(checkType, probeType, probeConfig, req.headers)) { @@ -133,7 +135,12 @@ export default function initializeHealthCheck( return true; } - function returnExpressHealthCheck(checkType: HealthProbeType, req: ReposAppRequest, res, next) { + function returnExpressHealthCheck( + checkType: HealthProbeType, + req: ReposAppRequest, + res: Response, + next: NextFunction + ) { let result = null; try { result = checkHealth(checkType); @@ -149,7 +156,7 @@ export default function initializeHealthCheck( healthy: true, }; - if (enabledHeaderProbes.length > 0) { + if (enabledHeaderProbes.length > 0 && app) { dbg(`Configured header health probes: ${enabledHeaderProbes.length}`); app.get( '/health/readiness', @@ -160,7 +167,7 @@ export default function initializeHealthCheck( multipleHeaderHealthCheck.bind(null, HealthProbeType.Liveness, ProbeType.Header, enabledHeaderProbes) ); } - if (enabledGenericProbes.length > 0) { + if (enabledGenericProbes.length > 0 && app) { // General probes listen on their own type endpoint for (const genericProbeConfig of enabledGenericProbes) { const url = genericProbeConfig.endpoint || `/health/${genericProbeConfig.endpointSuffix}`; @@ -173,7 +180,7 @@ export default function initializeHealthCheck( ); } } - if (enabledGenericProbes.length + enabledGenericProbes.length > 0) { + if (app && enabledGenericProbes.length + enabledGenericProbes.length > 0) { dbg('Health probes listening'); // 404 on anything that was not handled by any active, allowed probe listeners app.use('/health/*', (req, res) => { diff --git a/middleware/index.ts b/middleware/index.ts index c45fdf0c3..32e2605c8 100644 --- a/middleware/index.ts +++ b/middleware/index.ts @@ -6,21 +6,23 @@ import bodyParser from 'body-parser'; import compression from 'compression'; import path from 'path'; +import { Express } from 'express'; +import passport from 'passport'; import Debug from 'debug'; const debug = Debug.debug('startup'); export * from './react'; -export * from './links'; +export * from './business/links'; export * from './business'; export * from './jsonError'; -import { hasStaticReactClientApp, stripDistFolderName } from '../transitional'; +import { hasStaticReactClientApp, stripDistFolderName } from '../lib/transitional'; import { StaticClientApp } from './staticClientApp'; import { StaticReactClientApp } from './staticClientApp2'; import { StaticSiteFavIcon, StaticSiteAssets } from './staticSiteAssets'; import connectSession from './session'; -import passportConfig from './passport-config'; +import passportConfig from './passportConfig'; import onboard from './onboarding'; import viewServices from '../lib/pugViewServices'; @@ -35,12 +37,14 @@ import routePassport from './passport-routes'; import routeApi from '../api'; -import { IProviders, IReposApplication, SiteConfiguration } from '../interfaces'; +import type { IProviders, IReposApplication, SiteConfiguration } from '../interfaces'; import { codespacesDevAssistant } from './codespaces'; +import { ExpressWithStatic } from './types'; export default async function initMiddleware( app: IReposApplication, - express, + express: Express, + providers: IProviders, config: SiteConfiguration, dirname: string, hasCustomRoutes: boolean, @@ -51,7 +55,6 @@ export default async function initMiddleware( config && config.typescript && config.typescript.appDirectory ? config.typescript.appDirectory : stripDistFolderName(dirname); - const providers = app.get('providers') as IProviders; const applicationProfile = providers.applicationProfile; if (initializationError) { providers.healthCheck.healthy = false; @@ -78,14 +81,15 @@ export default async function initMiddleware( if (applicationProfile.serveStaticAssets) { StaticSiteAssets(app, express); } + const expressWithStatic = express as ExpressWithStatic; if (hasStaticReactClientApp()) { - StaticReactClientApp(app, express, config); + StaticReactClientApp(app, expressWithStatic, config); } if (applicationProfile.serveClientAssets) { - StaticClientApp(app, express); + StaticClientApp(app, expressWithStatic); } providers.campaign = campaign(app); - let passport; + let passport: passport.PassportStatic; if (!initializationError) { if (config.containers && config.containers.deployment) { app.enable('trust proxy'); diff --git a/middleware/initialize.ts b/middleware/initialize.ts index b249d29bd..4422f6271 100644 --- a/middleware/initialize.ts +++ b/middleware/initialize.ts @@ -3,6 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { Express, NextFunction, Response } from 'express'; import path from 'path'; import CosmosSessionStore from '../lib/cosmosSession'; @@ -14,11 +15,11 @@ import { createAndInitializeEntityMetadataProviderInstance, IEntityMetadataProvidersOptions, } from '../lib/entityMetadataProvider'; -import { createAndInitializeRepositoryMetadataProviderInstance } from '../entities/repositoryMetadata'; -import createAndInitializeOrganizationAnnotationProviderInstance from '../entities/organizationAnnotation'; +import { createAndInitializeRepositoryMetadataProviderInstance } from '../business/entities/repositoryMetadata'; +import createAndInitializeOrganizationAnnotationProviderInstance from '../business/entities/organizationAnnotation'; import { createMailAddressProviderInstance, IMailAddressProvider } from '../lib/mailAddressProvider'; -import ErrorRoutes from './error-routes'; +import ErrorRoutes from './errorRoutes'; import { createClient, RedisClientType } from 'redis'; import { Pool as PostgresPool } from 'pg'; @@ -26,6 +27,7 @@ import { Pool as PostgresPool } from 'pg'; import Debug from 'debug'; const debug = Debug.debug('startup'); const pgDebug = Debug.debug('pgpool'); +const nowDebug = Debug.debug('now'); import appInsights from './appInsights'; import keyVault from './keyVault'; @@ -36,9 +38,9 @@ import expressRoutes from '../routes/'; import alternateRoutes from './alternateApps'; import RedisHelper from '../lib/caching/redis'; -import { createTokenProvider } from '../entities/token'; -import { createAndInitializeApprovalProviderInstance } from '../entities/teamJoinApproval'; -import { CreateLocalExtensionKeyProvider } from '../entities/localExtensionKey'; +import { createTokenProvider } from '../business/entities/token'; +import { createAndInitializeApprovalProviderInstance } from '../business/entities/teamJoinApproval'; +import { CreateLocalExtensionKeyProvider } from '../business/entities/localExtensionKey'; import { CreateGraphProviderInstance, IGraphProvider } from '../lib/graphProvider/'; import initializeCorporateViews from './corporateViews'; @@ -46,16 +48,16 @@ import keyVaultResolver, { IKeyVaultSecretResolver } from '../lib/keyVaultResolv import { createMailProviderInstance } from '../lib/mailProvider/'; import { RestLibrary } from '../lib/github'; -import { CreateRepositoryCacheProviderInstance } from '../entities/repositoryCache'; -import { CreateRepositoryCollaboratorCacheProviderInstance } from '../entities/repositoryCollaboratorCache'; -import { CreateTeamCacheProviderInstance } from '../entities/teamCache'; -import { CreateTeamMemberCacheProviderInstance } from '../entities/teamMemberCache'; -import { CreateRepositoryTeamCacheProviderInstance } from '../entities/repositoryTeamCache'; -import { CreateOrganizationMemberCacheProviderInstance } from '../entities/organizationMemberCache'; +import { CreateRepositoryCacheProviderInstance } from '../business/entities/repositoryCache'; +import { CreateRepositoryCollaboratorCacheProviderInstance } from '../business/entities/repositoryCollaboratorCache'; +import { CreateTeamCacheProviderInstance } from '../business/entities/teamCache'; +import { CreateTeamMemberCacheProviderInstance } from '../business/entities/teamMemberCache'; +import { CreateRepositoryTeamCacheProviderInstance } from '../business/entities/repositoryTeamCache'; +import { CreateOrganizationMemberCacheProviderInstance } from '../business/entities/organizationMemberCache'; import QueryCache from '../business/queryCache'; -import { createAndInitializeOrganizationSettingProviderInstance } from '../entities/organizationSettings'; +import { createAndInitializeOrganizationSettingProviderInstance } from '../business/entities/organizationSettings'; import { IEntityMetadataProvider } from '../lib/entityMetadataProvider/entityMetadataProvider'; -import { createAndInitializeAuditLogRecordProviderInstance } from '../entities/auditLogRecord'; +import { createAndInitializeAuditLogRecordProviderInstance } from '../business/entities/auditLogRecord'; import CosmosCache from '../lib/caching/cosmosdb'; import BlobCache from '../lib/caching/blob'; import { StatefulCampaignProvider } from '../lib/campaigns'; @@ -63,7 +65,7 @@ import CosmosHelper from '../lib/cosmosHelper'; import { IQueueProcessor } from '../lib/queues'; import ServiceBusQueueProcessor from '../lib/queues/servicebus'; import AzureQueuesProcessor from '../lib/queues/azurequeue'; -import { UserSettingsProvider } from '../entities/userSettings'; +import { UserSettingsProvider } from '../business/entities/userSettings'; import getCompanySpecificDeployment from './companySpecificDeployment'; import routeCorrelationId from './correlationId'; @@ -71,13 +73,20 @@ import routeHsts from './hsts'; import routeSslify from './sslify'; import middlewareIndex from '.'; -import { ICacheHelper } from '../lib/caching'; -import { IApplicationProfile, IProviders, IReposApplication, SiteConfiguration } from '../interfaces'; -import initializeRepositoryProvider from '../entities/repository'; +import type { ICacheHelper } from '../lib/caching'; +import type { + ExecutionEnvironment, + ApplicationProfile, + IProviders, + IReposApplication, + SiteConfiguration, +} from '../interfaces'; +import initializeRepositoryProvider from '../business/entities/repository'; import { tryGetImmutableStorageProvider } from '../lib/immutable'; +import { GitHubAppPurposes } from '../lib/github/appPurposes'; -const DefaultApplicationProfile: IApplicationProfile = { - applicationName: 'GitHub Management Portal', +const DefaultApplicationProfile: ApplicationProfile = { + applicationName: 'Open Source Management Portal', serveStaticAssets: true, serveClientAssets: true, logDependencies: true, @@ -92,12 +101,13 @@ type CompanyStartupEntrypoint = ( ) => Promise; async function initializeAsync( - app: IReposApplication, - express, + executionEnvironment: ExecutionEnvironment, + providers: IProviders, + // app: IReposApplication, + // express, rootdir: string, config: SiteConfiguration ): Promise { - const providers = app.get('providers') as IProviders; providers.postgresPool = await ConnectPostgresPool(config.data.postgres); providers.linkProvider = await createAndInitializeLinkProviderInstance(providers, config); if (config.github.cache.provider === 'cosmosdb') { @@ -111,7 +121,6 @@ async function initializeAsync( } else if (config.github.cache.provider === 'redis') { const redisClient = await connectRedis(config, config.redis, 'cache'); const redisHelper = new RedisHelper({ redisClient, prefix: config.redis.prefix }); - // providers.redisClient = redisClient; providers.cacheProvider = redisHelper; } else { throw new Error('No cache provider available'); @@ -124,10 +133,7 @@ async function initializeAsync( } providers.graphProvider = await createGraphProvider(providers, config); - app.set('graphProvider', providers.graphProvider); - providers.mailAddressProvider = await createMailAddressProvider(config, providers); - app.set('mailAddressProvider', providers.mailAddressProvider); const mailProvider = createMailProviderInstance(config); if (mailProvider) { @@ -139,7 +145,6 @@ async function initializeAsync( } providers.github = configureGitHubLibrary(providers.cacheProvider, config); - app.set('github', providers.github); // always check if config exists to prevent crashing because of trying to access an undefined object const emOptions: IEntityMetadataProvidersOptions = { @@ -268,7 +273,7 @@ async function initializeAsync( providers.corporateAdministrationProfile = getCompanySpecificDeployment()?.administrationSection; providers.corporateViews = await initializeCorporateViews(providers, rootdir); - await dynamicStartup(config, providers, rootdir); + await dynamicStartup(executionEnvironment, config, providers, rootdir); const webhooksConfig = config.github.webhooks; if (webhooksConfig && webhooksConfig.provider) { @@ -290,16 +295,21 @@ async function initializeAsync( const repositoryMetadataProvider = await createAndInitializeRepositoryMetadataProviderInstance({ entityMetadataProvider: providerNameToInstance(config.entityProviders.repositorymetadata), }); - const operations = new Operations({ providers, repositoryMetadataProvider, github: providers.github }); + const operations = new Operations({ + executionEnvironment, + providers, + repositoryMetadataProvider, + github: providers.github, + }); await operations.initialize(); - app.set('operations', operations); providers.operations = operations; + GitHubAppPurposes.RegisterOperationsInstanceForBuiltInPurposes(operations); } catch (ignoredError2) { console.dir(ignoredError2); throw ignoredError2; } - await dynamicStartup(config, providers, rootdir, 'secondary'); + await dynamicStartup(executionEnvironment, config, providers, rootdir, 'secondary'); if (providers.applicationProfile.startup) { debug('Application provider-specific startup...'); @@ -307,17 +317,7 @@ async function initializeAsync( } } -function configureGitHubLibrary(cacheProvider: ICacheHelper, config): RestLibrary { - if ( - config && - config.github && - config.github.operations && - !config.github.operations.centralOperationsToken - ) { - debug( - 'WARNING: no central GitHub operations token is defined, some library operations may not succeed. ref: config.github.operations.centralOperationsToken var: GITHUB_CENTRAL_OPERATIONS_TOKEN' - ); - } +function configureGitHubLibrary(cacheProvider: ICacheHelper, config: SiteConfiguration): RestLibrary { const libraryContext = new RestLibrary({ config, cacheProvider, @@ -327,33 +327,44 @@ function configureGitHubLibrary(cacheProvider: ICacheHelper, config): RestLibrar // Asynchronous initialization for the Express app, configuration and data stores. export default async function initialize( + executionEnvironment: ExecutionEnvironment, app: IReposApplication, - express, + express: Express, rootdir: string, - config: any, + config: SiteConfiguration, exception: Error -): Promise { +): Promise { if (exception) { console.warn(`Startup exception: ${exception}`, exception?.stack); } if (!config || Object.getOwnPropertyNames(config).length === 0) { throw new Error('Empty configuration object'); } - if (!app.runtimeConfiguration) { + if (app && !app.runtimeConfiguration) { app.runtimeConfiguration = {}; } const applicationProfile = config?.web?.app && config.web.app !== 'repos' ? await alternateRoutes(config, app, config.web.app) : DefaultApplicationProfile; - const web = !(config?.skipModules && config.skipModules.has('web')); + const web = false === executionEnvironment.skipModules.has('web'); if (applicationProfile.webServer && !web) { applicationProfile.webServer = false; } - const containerPurpose = - config && config.isJobInternal ? 'job' : applicationProfile.webServer ? 'web application' : 'application'; - debug(`${containerPurpose} name: ${applicationProfile.applicationName}`); + const containerPurpose = executionEnvironment.isJob + ? 'job' + : applicationProfile.webServer + ? 'web application' + : 'application'; + if (executionEnvironment.entrypointName) { + debug(`${containerPurpose} name: ${executionEnvironment.entrypointName}`); + } + debug(`${containerPurpose} profile: ${applicationProfile.applicationName}`); debug(`environment: ${config?.debug?.environmentName || 'Unknown'}`); + if (config?.continuousDeployment) { + const values = Object.values(config.continuousDeployment).filter((x) => x); + values.length > 0 && debug(`build: ${values.join(', ')}`); + } const codespacesConfig = (config as SiteConfiguration)?.github?.codespaces; if (codespacesConfig?.connected === true && codespacesConfig.block === true) { @@ -377,54 +388,69 @@ export default async function initialize( exception = error; } } - app.set('started', new Date()); - app.config = config; + if (app) { + app.set('started', executionEnvironment.started); + app.config = config; + } if (exception) { // Once app insights is available, will try to log this exception; display for now. console.dir(exception); } - app.set('basedir', rootdir); + if (app) { + app.set('basedir', rootdir); + } const providers: IProviders = { app, basedir: rootdir, applicationProfile, }; - app.set('providers', providers); - app.providers = providers; - app.set('runtimeConfig', config); + executionEnvironment.providers = providers; + if (app) { + app.set('providers', providers); + app.providers = providers; + app.set('runtimeConfig', config); + } providers.healthCheck = healthCheck(app, config); if (applicationProfile.webServer) { - if (!app.startServer) { + if (!app) { + throw new Error('app (Express) is required for web applications'); + } else if (!app.startServer) { throw new Error(`app.startServer is required for web applications`); } await app.startServer(); } - app.use(routeCorrelationId); - providers.insights = appInsights(app, config); - app.set('appInsightsClient', providers.insights); + if (app) { + app.use(routeCorrelationId); + } + const insights = appInsights(providers, executionEnvironment, app, config); + providers.insights = insights; if (!exception && (!config || !config.activeDirectory)) { exception = new Error( `config.activeDirectory.clientId and config.activeDirectory.clientSecret are required to initialize KeyVault` ); } - app.use('*', (req, res, next) => { - if (providers.healthCheck.ready) { - return next(); - } - return res.send('Service not ready.'); - }); + if (app) { + app.use('*', (req, res: Response, next: NextFunction) => { + if (providers.healthCheck.ready) { + return next(); + } + return res.send('Service not ready.'); + }); + } // See docs/configuration.md for all this - if (config?.containers?.deployment) { - debug('Container deployment: HTTP: listening, HSTS: on'); - app.use(routeHsts); - } else if (config?.containers?.docker) { - debug('Docker image: HTTP: listening, HSTS: off'); - } else if (config.webServer.allowHttp) { - debug('development mode: HTTP: listening, HSTS: off'); - } else { - debug('non-container production mode: HTTP: redirect to HTTPS, HSTS: on'); - const sslifyRouter = routeSslify(config.webServer); - sslifyRouter && app.use(sslifyRouter); + if (app) { + if (config?.containers?.deployment) { + debug('Container deployment: HTTP: listening, HSTS: on'); + app.use(routeHsts); + } else if (config?.containers?.docker) { + debug('Docker image: HTTP: listening, HSTS: off'); + } else if (config.webServer.allowHttp) { + debug('development mode: HTTP: listening, HSTS: off'); + } else { + debug('non-container production mode: HTTP: redirect to HTTPS, HSTS: on'); + const sslifyRouter = routeSslify(config.webServer); + sslifyRouter && app.use(sslifyRouter); + } } if (!exception) { const kvConfig = { @@ -437,7 +463,7 @@ export default async function initialize( try { const keyVaultClient = keyVault(kvConfig); keyEncryptionKeyResolver = keyVaultResolver(keyVaultClient); - app.set('keyEncryptionKeyResolver', keyEncryptionKeyResolver); + app && app.set('keyEncryptionKeyResolver', keyEncryptionKeyResolver); providers.keyEncryptionKeyResolver = keyEncryptionKeyResolver; debug('configuration secrets resolved'); } catch (noKeyVault) { @@ -449,7 +475,7 @@ export default async function initialize( } } try { - await initializeAsync(app, express, rootdir, config); + await initializeAsync(executionEnvironment, providers, rootdir, config); } catch (initializeError) { console.dir(initializeError); debug(`Initialization failure: ${initializeError}`); @@ -458,7 +484,9 @@ export default async function initialize( } const hasCustomRoutes = !!applicationProfile.customRoutes; try { - await middlewareIndex(app, express, config, rootdir, hasCustomRoutes, exception); + if (app) { + await middlewareIndex(app, express, providers, config, rootdir, hasCustomRoutes, exception); + } } catch (middlewareError) { exception = middlewareError; } @@ -466,13 +494,12 @@ export default async function initialize( if (!exception) { if (hasCustomRoutes) { await applicationProfile.customRoutes(); - } else { + } else if (app) { app.use('/', expressRoutes); } } else { console.error(exception); - const appInsightsClient = providers.insights; - const crash = (error) => { + const crash = (error: Error) => { return () => { debug('App crashed because of an initialization error.'); console.log(error.message); @@ -482,15 +509,15 @@ export default async function initialize( process.exit(1); }; }; - if (appInsightsClient) { - appInsightsClient.trackException({ + if (insights) { + insights.trackException({ exception, properties: { info: 'App crashed while initializing', }, }); try { - appInsightsClient.flush({ isAppCrashing: true, callback: crash(exception) }); + insights.flush({ isAppCrashing: true, callback: crash(exception) }); } catch (sendError) { console.dir(sendError); crash(exception)(); @@ -500,10 +527,24 @@ export default async function initialize( } } await ErrorRoutes(app, exception); - return app; + if (config?.debug?.breakConsoleEveryMinute === true) { + const isNowDebugging = Debug.enabled('now'); + const everyMinute = () => { + const display = new Date().toISOString().substring(0, 19).replace('T', ' '); + if (isNowDebugging) { + nowDebug(display); + } else { + console.log(); + console.log(display); + } + }; + everyMinute(); + setInterval(everyMinute, 60000); + } + return executionEnvironment; } -function createGraphProvider(providers: IProviders, config: any): Promise { +function createGraphProvider(providers: IProviders, config: SiteConfiguration): Promise { return new Promise((resolve, reject) => { // The graph provider is optional. A graph provider can connect to a // corporate directory to validate or lookup employees and other @@ -601,7 +642,10 @@ async function connectRedis( return redisClient; } -async function createMailAddressProvider(config: any, providers: IProviders): Promise { +async function createMailAddressProvider( + config: SiteConfiguration, + providers: IProviders +): Promise { const options = { config: config, providers: providers, @@ -609,7 +653,13 @@ async function createMailAddressProvider(config: any, providers: IProviders): Pr return createMailAddressProviderInstance(options); } -async function dynamicStartup(config: any, providers: IProviders, rootdir: string, stage?: string) { +async function dynamicStartup( + executionEnvironment: ExecutionEnvironment, + config: SiteConfiguration, + providers: IProviders, + rootdir: string, + stage?: string +) { const p = config?.startup?.path; if (p) { try { @@ -625,6 +675,7 @@ async function dynamicStartup(config: any, providers: IProviders, rootdir: strin } const promise = (entrypoint as CompanyStartupEntrypoint).call( null, + executionEnvironment, config, providers, rootdir @@ -632,6 +683,9 @@ async function dynamicStartup(config: any, providers: IProviders, rootdir: strin await promise; debug(`company-specific ${stage || 'startup'} complete (${p})`); } catch (dynamicLoadError) { + if (dynamicLoadError.stack) { + console.error(dynamicLoadError.stack); + } throw new Error(`config.startup.path=${p} could not successfully load: ${dynamicLoadError}`); } } diff --git a/middleware/jsonError.ts b/middleware/jsonError.ts index 48cdd1bc9..a8f40058d 100644 --- a/middleware/jsonError.ts +++ b/middleware/jsonError.ts @@ -3,17 +3,22 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + +import { ReposAppRequest } from '../interfaces'; + interface IErrorJson extends Error { json?: boolean; statusCode?: string | number; } -export function json404(req, res, next) { +export function json404(req: ReposAppRequest, res: Response, next: NextFunction) { return next(jsonError('Endpoint not found', 404)); } -export function isJsonError(error: IErrorJson | string | Error) { - return error && error['json'] === true; +export function isJsonError(error: IErrorJson | string | Error, url: string) { + const errorAsAny = error as any; + return errorAsAny?.json === true || url?.startsWith('/api/'); } export function jsonError(error: IErrorJson | string | Error, statusCode?: number): IErrorJson { diff --git a/middleware/keyVault.ts b/middleware/keyVault.ts index f03629d5d..77c90a60b 100644 --- a/middleware/keyVault.ts +++ b/middleware/keyVault.ts @@ -4,7 +4,7 @@ // import { ClientSecretCredential } from '@azure/identity'; -import { KeyVaultSecret, SecretClient } from '@azure/keyvault-secrets'; +import { SecretClient } from '@azure/keyvault-secrets'; export interface IKeyVaultConfigurationOptions { tenantId: string; diff --git a/middleware/locals.ts b/middleware/locals.ts index 2fbe3c770..59ed4772f 100644 --- a/middleware/locals.ts +++ b/middleware/locals.ts @@ -4,11 +4,12 @@ // import os from 'os'; -import { ReposAppRequest } from '../interfaces'; +import { NextFunction, Response } from 'express'; -import { getProviders } from '../transitional'; +import { ReposAppRequest } from '../interfaces'; +import { getProviders } from '../lib/transitional'; -export default function (req: ReposAppRequest, res, next) { +export default function (req: ReposAppRequest, res: Response, next: NextFunction) { const { config, viewServices } = getProviders(req); req.app.locals.correlationId = req.correlationId; req.app.locals.scrubbedUrl = req.scrubbedUrl; diff --git a/middleware/logger.ts b/middleware/logger.ts index ef63838d3..7a3689a08 100644 --- a/middleware/logger.ts +++ b/middleware/logger.ts @@ -6,7 +6,7 @@ import logger from 'morgan'; import { ReposAppRequest } from '../interfaces'; -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; const encryptionMetadataKey = '_ClientEncryptionMetadata2'; const piiFormat = diff --git a/middleware/lowercaser.ts b/middleware/lowercaser.ts index 7248e5427..d4eecec20 100644 --- a/middleware/lowercaser.ts +++ b/middleware/lowercaser.ts @@ -3,8 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + +import { ReposAppRequest } from '../interfaces'; + export default function (params) { - return function (req, res, next) { + return function (req: ReposAppRequest, res: Response, next: NextFunction) { // lowercase parameters Object.getOwnPropertyNames(req.params).forEach((param) => { if (params.indexOf(param) > -1) { diff --git a/middleware/officeHyperlinks.ts b/middleware/officeHyperlinks.ts index e3e83bd96..5a0d6daf3 100644 --- a/middleware/officeHyperlinks.ts +++ b/middleware/officeHyperlinks.ts @@ -5,7 +5,8 @@ // I no longer believe this file FYI... I don't think we need this any longer. -import { getProviders } from '../transitional'; +import { NextFunction, Response } from 'express'; +import { getProviders } from '../lib/transitional'; // Office uses a specialized pre-fetch to learn more about hyperlinks before // opening. As a result, if the Office user agent is in use, and the @@ -17,7 +18,7 @@ import { getProviders } from '../transitional'; const GenericOfficeUserAgent = 'ms-office'; const WordUserAgent = 'Microsoft Office Word'; -export default function supportOfficeHyperlinks(req, res, next) { +export default function supportOfficeHyperlinks(req, res: Response, next: NextFunction) { const { insights } = getProviders(req); const userAgent = req.headers['user-agent']; const isAuthenticated = req.isAuthenticated ? req.isAuthenticated() : false; diff --git a/middleware/onboarding.ts b/middleware/onboarding.ts index 225bbbe2b..6a6b34535 100644 --- a/middleware/onboarding.ts +++ b/middleware/onboarding.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { IProviders } from '../interfaces'; +import { IProviders, IReposApplication, SiteConfiguration } from '../interfaces'; // ---------------------------------------------------------------------------- // Onboarding helper @@ -14,7 +14,7 @@ import { IProviders } from '../interfaces'; // rather a configuration/app initialization method just stored here to keep it // out of the way. // ---------------------------------------------------------------------------- -export default async function Onboard(app, config) { +export default async function Onboard(app: IReposApplication, config: SiteConfiguration) { const { operations } = app.settings.providers as IProviders; const onboardingOrganizations = config.github.organizations?.onboarding || []; for (const orgEntry of onboardingOrganizations) { diff --git a/middleware/passport-routes.ts b/middleware/passport-routes.ts index 642e332cc..a0bb18142 100644 --- a/middleware/passport-routes.ts +++ b/middleware/passport-routes.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Response, NextFunction } from 'express'; +import type { Response, NextFunction } from 'express'; -import { redirectToReferrer, storeReferrer } from '../utils'; -import { getProviders } from '../transitional'; -import { ReposAppRequest, IAppSession } from '../interfaces'; +import { redirectToReferrer, storeReferrer } from '../lib/utils'; +import { getProviders } from '../lib/transitional'; +import type { ReposAppRequest, IAppSession } from '../interfaces'; import getCompanySpecificDeployment from './companySpecificDeployment'; import { attachAadPassportRoutes } from './passport/aadRoutes'; import { attachGitHubPassportRoutes } from './passport/githubRoutes'; @@ -228,6 +228,7 @@ export default function configurePassport(app, passport, config) { ? `Your ${config.brand.companyName} and GitHub accounts have been unlinked. You no longer have access to any ${config.brand.companyName} organizations, and you have been signed out of this portal.` : 'Goodbye', title: 'Goodbye', + clearLocalStorage: true, buttonText: unlinked ? 'Sign in to connect a new account' : 'Sign in', config: config.obfuscatedConfig, }); diff --git a/middleware/passport/aadRoutes.ts b/middleware/passport/aadRoutes.ts index 59780a355..10fa64010 100644 --- a/middleware/passport/aadRoutes.ts +++ b/middleware/passport/aadRoutes.ts @@ -5,22 +5,22 @@ import { NextFunction, Response } from 'express'; import { PassportStatic } from 'passport'; -import { IReposError, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; -import { isCodespacesAuthenticating } from '../../utils'; +import { type IReposApplication, type IReposError, ReposAppRequest } from '../../interfaces'; +import { getProviders } from '../../lib/transitional'; +import { isCodespacesAuthenticating } from '../../lib/utils'; import { IPrimaryAuthenticationHelperMethods } from '../passport-routes'; import { aadStrategyUserPropertyName } from './aadStrategy'; const aadPassportStrategyName = 'azure-active-directory'; export function attachAadPassportRoutes( - app, + app: IReposApplication, config: any, passport: PassportStatic, helpers: IPrimaryAuthenticationHelperMethods ) { const signinPath = isCodespacesAuthenticating(config, 'aad') ? 'sign-in' : 'signin'; - app.get(`/${signinPath}`, function (req: ReposAppRequest, res, next) { + app.get(`/${signinPath}`, function (req: ReposAppRequest, res: Response, next: NextFunction) { if (req.isAuthenticated()) { const username = req.user?.azure?.username; if (username) { @@ -81,7 +81,7 @@ export function attachAadPassportRoutes( // links from apps that temporarily prevent sessions. Technically this seems to // impact Windows users who use Word to open links to the site. Collecting // telemetry for now. - app.get('/auth/azure/callback', (req: ReposAppRequest, res, next) => { + app.get('/auth/azure/callback', (req: ReposAppRequest, res: Response, next: NextFunction) => { const { insights } = getProviders(req); const isAuthenticated = req.isAuthenticated(); insights?.trackEvent({ diff --git a/middleware/passport/aadStrategy.ts b/middleware/passport/aadStrategy.ts index 25e894238..9d1db1af8 100644 --- a/middleware/passport/aadStrategy.ts +++ b/middleware/passport/aadStrategy.ts @@ -9,10 +9,10 @@ const debug = Debug.debug('startup'); import { AuthorizationCode } from 'simple-oauth2'; import { OIDCStrategy } from 'passport-azure-ad'; -import { IProviders } from '../../interfaces'; +import type { IProviders, IReposApplication, SiteConfiguration } from '../../interfaces'; import { GraphUserType } from '../../lib/graphProvider'; -import { getCodespacesHostname, isCodespacesAuthenticating } from '../../utils'; +import { getCodespacesHostname, isCodespacesAuthenticating } from '../../lib/utils'; export const aadStrategyName = 'azure-active-directory'; export const aadStrategyUserPropertyName = 'azure'; @@ -25,19 +25,64 @@ interface IAADUser { displayName: string; oid: string; username: string; - oauthToken?: string; + // oauthToken?: string; // we aren't using this, no need to store these } +/* cSpell:disable */ +type AadJwtJson = { + aio: string; + amr: string; + family_name: string; + given_name: string; + ipaddr: string; + name: string; + oid: string; + onprem_sid: string; + rh: string; + sub: string; + tid: string; + unique_name: string; + upn: string; + uti: string; + ver: string; +}; +/* cSpell:enable */ + +type AadResponseProfile = { + _json: AadJwtJson; + _raw: string; + displayName: string; + emails: undefined; + name: { + familyName: string; + givenName: string; + middleName: string; + }; + oid: string; + sub: string; + upn: string; +}; + +type AadBearerToken = { + access_token: string; + expireS_in: string; + expires_on: string; + ext_expires_in: string; + id_token: string; + refresh_token: string; + token_type: 'Bearer'; +}; + async function login( - app, - config, + app: IReposApplication, + config: SiteConfiguration, client: AuthorizationCode, - iss, - sub, - profile, + iss: string, + sub: string, + profile: AadResponseProfile, accessToken: string, refreshToken: string, - params + params: AadBearerToken ): Promise { const { graphProvider, insights } = app.settings.providers as IProviders; const oauthToken = JSON.stringify(params); @@ -55,7 +100,7 @@ async function login( displayName: impersonationResult.displayName, oid: impersonationResult.id, username: impersonationResult.userPrincipalName, - oauthToken, + // oauthToken, }, }; } @@ -75,21 +120,21 @@ async function login( displayName: profile.displayName, oid: profile.oid, username: profile.upn, - oauthToken, + // oauthToken, }, }; } function activeDirectorySubset( - app, - config, + app: IReposApplication, + config: SiteConfiguration, client: AuthorizationCode, - iss, - sub, - profile, + iss: string, + sub: string, + profile: AadResponseProfile, accessToken: string, refreshToken: string, - params, + params: AadBearerToken, done ) { login(app, config, client, iss, sub, profile, accessToken, refreshToken, params) @@ -101,9 +146,9 @@ function activeDirectorySubset( }); } -export default function createAADStrategy(app, config) { +export default function createAADStrategy(app: IReposApplication, config: SiteConfiguration) { const { redirectUrl, tenantId, clientId, clientSecret } = config.activeDirectory; - const codespaces = config?.github?.codespaces || {}; + const codespaces = config?.github?.codespaces; if (!clientId) { debug('No Azure Active Directory clientID configured, corporate authentication will be unavailable.'); return {}; diff --git a/middleware/passport/encryptionSerializer.ts b/middleware/passport/encryptionSerializer.ts index b87cff659..c35cfb106 100644 --- a/middleware/passport/encryptionSerializer.ts +++ b/middleware/passport/encryptionSerializer.ts @@ -4,7 +4,7 @@ // import { decryptEntityAsync, encryptEntityAsync, IEncryptionOptions } from '../../lib/encryption'; -import { wrapError } from '../../utils'; +import { wrapError } from '../../lib/utils'; import { LegacySerializer } from './serializer'; // NOTE TO DEVELOPERS: we are no longer using encrypted sessions at our company diff --git a/middleware/passport/githubRoutes.ts b/middleware/passport/githubRoutes.ts index 07e0a287c..03f441ca7 100644 --- a/middleware/passport/githubRoutes.ts +++ b/middleware/passport/githubRoutes.ts @@ -5,10 +5,11 @@ import { NextFunction, Response } from 'express'; import querystring from 'querystring'; +import { PassportStatic } from 'passport'; -import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; -import { isCodespacesAuthenticating } from '../../utils'; +import { IReposApplication, ReposAppRequest, SiteConfiguration } from '../../interfaces'; +import { getProviders } from '../../lib/transitional'; +import { isCodespacesAuthenticating } from '../../lib/utils'; import { IAuthenticationHelperMethods } from '../passport-routes'; import { getGithubAppConfigurationOptions, @@ -19,9 +20,9 @@ import { } from '../passport/githubStrategy'; export function attachGitHubPassportRoutes( - app, - config: any, - passport, + app: IReposApplication, + config: SiteConfiguration, + passport: PassportStatic, helpers: IAuthenticationHelperMethods ) { const signinPath = isCodespacesAuthenticating(config, 'github') ? 'sign-in' : 'signin'; diff --git a/middleware/passport/githubStrategy.ts b/middleware/passport/githubStrategy.ts index ff98687dd..fd056d788 100644 --- a/middleware/passport/githubStrategy.ts +++ b/middleware/passport/githubStrategy.ts @@ -5,10 +5,21 @@ import { Strategy as GithubStrategy } from 'passport-github'; -import { IGitHubAccountDetails, IProviders } from '../../interfaces'; -import { getCodespacesHostname, isCodespacesAuthenticating, isEnterpriseManagedUserLogin } from '../../utils'; +import { + getCodespacesHostname, + isCodespacesAuthenticating, + isEnterpriseManagedUserLogin, +} from '../../lib/utils'; +import type { + IGitHubAccountDetails, + IProviders, + IReposApplication, + SiteConfiguration, +} from '../../interfaces'; +import type { ConfigGitHubCodespaces } from '../../config/github.codespaces.types'; import Debug from 'debug'; +import { ConfigGitHubOAuth2 } from '../../config/github.oauth2.types'; const debug = Debug.debug('startup'); export const githubStrategyName = 'github'; @@ -55,7 +66,7 @@ function impersonatedIdentityFromDetails( } function githubResponseToSubset( - app, + app: IReposApplication, modernAppInUse: boolean, accessToken: string, refreshToken: string, @@ -73,7 +84,7 @@ function githubResponseToSubset( } async function githubResponseToSubsetEx( - app, + app: IReposApplication, modernAppInUse: boolean, accessToken: string, refreshToken: string, @@ -142,7 +153,7 @@ function githubResponseToIncreasedScopeSubset( return done(null, subset); } -export function getGithubAppConfigurationOptions(config) { +export function getGithubAppConfigurationOptions(config: SiteConfiguration) { let legacyOAuthApp = config?.github?.oauth2?.clientId && config?.github?.oauth2?.clientSecret ? config.github.oauth2 : null; const customerFacingApp = @@ -168,9 +179,9 @@ export function getGithubAppConfigurationOptions(config) { }; } -export default function createGithubStrategy(app, config) { +export default function createGithubStrategy(app: IReposApplication, config: SiteConfiguration) { const strategies = {}; - const codespaces = config?.github?.codespaces || {}; + const codespaces = config?.github?.codespaces || ({} as ConfigGitHubCodespaces); const { modernAppInUse, githubAppConfiguration, useIncreasedScopeLegacyAppIfNeeded } = getGithubAppConfigurationOptions(config); if (!githubAppConfiguration?.clientId) { @@ -183,7 +194,7 @@ export default function createGithubStrategy(app, config) { const finalCallbackUrl = isCodespacesAuthenticating(config, 'github') && !codespaces?.block ? getCodespacesHostname(config) + redirectSuffix - : githubAppConfiguration.callbackUrl; + : (githubAppConfiguration as ConfigGitHubOAuth2)?.callbackUrl; let clientId = githubAppConfiguration.clientId; let clientSecret = githubAppConfiguration.clientSecret; let codespacesOverrideText = ''; diff --git a/middleware/passport-config.ts b/middleware/passportConfig.ts similarity index 96% rename from middleware/passport-config.ts rename to middleware/passportConfig.ts index 064eb605e..3f52f94a8 100644 --- a/middleware/passport-config.ts +++ b/middleware/passportConfig.ts @@ -3,7 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; import passport from 'passport'; + import { IKeyVaultSecretResolver } from '../lib/keyVaultResolver'; import getCompanySpecificDeployment from './companySpecificDeployment'; @@ -73,7 +75,7 @@ export default function (app: IReposApplication, config: SiteConfiguration) { passport.deserializeUser(serializer.deserialize(serializerOptions)); serializer.initialize(serializerOptions, app); - app.use((req: ReposAppRequest, res, next) => { + app.use((req: ReposAppRequest, res: Response, next: NextFunction) => { if (req?.insights?.commonProperties && config.authentication.scheme === 'aad' && req?.user?.azure?.oid) { req.insights.commonProperties.aadId = req.user.azure.oid; } diff --git a/middleware/rawBodyParser.ts b/middleware/rawBodyParser.ts index 984f9852e..1ef2e395a 100644 --- a/middleware/rawBodyParser.ts +++ b/middleware/rawBodyParser.ts @@ -3,10 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; import { ReposAppRequest } from '../interfaces'; -import { isWebhookIngestionEndpointEnabled } from '../transitional'; +import { isWebhookIngestionEndpointEnabled } from '../lib/transitional'; -export default function rawBodyParser(req: ReposAppRequest, res, next) { +export default function rawBodyParser(req: ReposAppRequest, res: Response, next: NextFunction) { if (!isWebhookIngestionEndpointEnabled(req)) { return next(); } diff --git a/middleware/react.ts b/middleware/react.ts index b797e1d76..8738e76fd 100644 --- a/middleware/react.ts +++ b/middleware/react.ts @@ -3,15 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Response } from 'express'; +import { NextFunction, Response } from 'express'; import fs from 'fs'; import path from 'path'; import appPackage from '../package.json'; import { getStaticBlobCacheFallback } from '../lib/staticBlobCacheFallback'; -import { getProviders, splitSemiColonCommas } from '../transitional'; -import { ReposAppRequest } from '../interfaces'; +import { getProviders, splitSemiColonCommas } from '../lib/transitional'; +import type { ReposAppRequest, SiteConfiguration } from '../interfaces'; import { IndividualContext } from '../business/user'; const staticReactPackageNameKey = 'static-react-package-name'; @@ -31,37 +31,44 @@ type PackageJsonSubset = { flights?: Record; }; +type BasicFlightingOptions = { + enabled: boolean; +}; + type ContentOptions = { html: string; package: PackageJsonSubset; }; -type FlightingOptions = ContentOptions & { - enabled: boolean; - divertEveryone: boolean; - staticFlightIds?: Set; - flightName: string; -}; +type FlightingOptions = BasicFlightingOptions & + ContentOptions & { + divertEveryone?: boolean; + staticFlightIds?: Set; + flightName?: string; + }; export function injectReactClient() { const standardContent = getReactScriptsIndex(staticClientPackageName); + let flightingBasics: BasicFlightingOptions = null; let flightingOptions: FlightingOptions = null; - return function injectedRoute(req: ReposAppRequest, res, next) { + return function injectedRoute(req: ReposAppRequest, res: Response, next: NextFunction) { const { config } = getProviders(req); // special passthrough if (req.path.includes('/byClient')) { return next(); } if (!flightingOptions) { - flightingOptions = evaluateFlightConditions(req); + flightingBasics = evaluateFlightConditions(req); + flightingOptions = flightingBasics as FlightingOptions; } const activeContext = (req.individualContext || req.apiContext) as IndividualContext; - const flightAvailable = flightingOptions.enabled && flightingOptions.html; - const flightName = flightAvailable ? flightingOptions.flightName : null; + const flightEnabled = flightingBasics?.enabled === true; + const flightAvailable = flightEnabled && flightingOptions?.html; + const flightName = flightingOptions?.flightName; const userFlighted = - flightingOptions.divertEveryone === true || + flightingOptions?.divertEveryone === true || (activeContext?.corporateIdentity?.id && - flightingOptions.staticFlightIds?.has(activeContext.corporateIdentity.id)); + flightingOptions?.staticFlightIds?.has(activeContext.corporateIdentity.id)); const userFlightOverride = req.query.flight === '0' || req.query.flight === '1' ? req.query.flight : undefined; let inFlight = flightAvailable && (userFlighted || req.query.flight === '1'); @@ -141,7 +148,7 @@ export function injectReactClient() { }; } -function evaluateFlightConditions(req: ReposAppRequest): FlightingOptions { +function evaluateFlightConditions(req: ReposAppRequest): FlightingOptions | BasicFlightingOptions { const { config } = getProviders(req); if (config?.client?.flighting?.enabled === true && staticClientFlightingPackageName) { const options = getReactScriptsIndex(staticClientFlightingPackageName) as FlightingOptions; @@ -157,9 +164,12 @@ function evaluateFlightConditions(req: ReposAppRequest): FlightingOptions { ); return options; } + return { + enabled: false, + }; } -function getUserClientFeatureFlags(config: any, corporateId: string) { +function getUserClientFeatureFlags(config: SiteConfiguration, corporateId: string) { const featureFlagList = config?.client?.flighting?.featureFlagUsers; if (featureFlagList && typeof featureFlagList === 'object') { const flights = []; diff --git a/middleware/scrubbedUrl.ts b/middleware/scrubbedUrl.ts index 0ed6f9496..1600724a8 100644 --- a/middleware/scrubbedUrl.ts +++ b/middleware/scrubbedUrl.ts @@ -3,9 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; +import { ReposAppRequest } from '../interfaces'; + // Scrub the incoming URL value(s) in the request, replacing tokens and other // secrets. -export default function (req, res, next) { +export default function (req: ReposAppRequest, res: Response, next: NextFunction) { let url = req.originalUrl || req.url; const secretKeys = ['code', 'token']; for (let i = 0; i < secretKeys.length; i++) { @@ -16,5 +19,5 @@ export default function (req, res, next) { } } req.scrubbedUrl = url; - next(); + return next(); } diff --git a/middleware/sslify.ts b/middleware/sslify.ts index 4fd121d2d..2b7a83dc5 100644 --- a/middleware/sslify.ts +++ b/middleware/sslify.ts @@ -4,6 +4,7 @@ // import sslify from 'express-sslify'; + import type { ConfigWebServer } from '../config/webServer.types'; export default function (webServerConfig: ConfigWebServer) { diff --git a/middleware/staticClientApp.ts b/middleware/staticClientApp.ts index 14af5da60..2cebc2dbe 100644 --- a/middleware/staticClientApp.ts +++ b/middleware/staticClientApp.ts @@ -8,10 +8,13 @@ import appPackage from '../package.json'; const packageVariableName = 'static-client-package-name'; const otherPackageVariableName = 'static-react-package-name'; +import type { IReposApplication } from '../interfaces'; +import type { ExpressWithStatic } from './types'; + import Debug from 'debug'; const debug = Debug.debug('startup'); -export function StaticClientApp(app, express) { +export function StaticClientApp(app: IReposApplication, express: ExpressWithStatic) { // Serve/host the static client app from the location reported by the private // NPM module for the Ember app. Assumes that the inclusion of the package // returns the path to host. diff --git a/middleware/staticClientApp2.ts b/middleware/staticClientApp2.ts index 7fdc795bd..73112124d 100644 --- a/middleware/staticClientApp2.ts +++ b/middleware/staticClientApp2.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { hasStaticReactClientApp } from '../transitional'; +import { hasStaticReactClientApp } from '../lib/transitional'; import appPackage from '../package.json'; @@ -16,6 +16,7 @@ const staticReactFlightingPackageNameKey = 'static-react-flight-package-name'; const staticClientFlightingPackageName = appPackage[staticReactFlightingPackageNameKey]; import Debug from 'debug'; +import { ExpressWithStatic } from './types'; const debug = Debug.debug('startup'); export type RuntimeConfigurationClient = { @@ -31,7 +32,11 @@ export type RootRuntimeConfigurationClient = { client?: RuntimeConfigurationClient; }; -export function StaticReactClientApp(app: IReposApplication, express, config: SiteConfiguration) { +export function StaticReactClientApp( + app: IReposApplication, + express: ExpressWithStatic, + config: SiteConfiguration +) { const clientRuntimeConfiguration: RuntimeConfigurationClient = {}; app.runtimeConfiguration.client = clientRuntimeConfiguration; diff --git a/middleware/staticSiteAssets.ts b/middleware/staticSiteAssets.ts index 155e0c41d..5d56d4e50 100644 --- a/middleware/staticSiteAssets.ts +++ b/middleware/staticSiteAssets.ts @@ -12,7 +12,7 @@ const debug = Debug.debug('startup'); import favicon from 'serve-favicon'; import path from 'path'; -import { CreateError } from '../transitional'; +import { CreateError } from '../lib/transitional'; const appRootPath = appRoot.toString(); diff --git a/middleware/supportMultipleAuthProviders.ts b/middleware/supportMultipleAuthProviders.ts index 4cdb353a8..0905cbab0 100644 --- a/middleware/supportMultipleAuthProviders.ts +++ b/middleware/supportMultipleAuthProviders.ts @@ -3,9 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { jsonError } from './jsonError'; import { IApiRequest } from './apiReposAuth'; -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; // We have made a decision to not use Passport for the API routes, which is why this // performs some passport-like functionality... @@ -24,7 +26,7 @@ export default function returnCombinedMiddleware(supportedProviders) { if (totalProviders <= 0) { throw new Error('supportedProviders must provide at least one provider to use for auth'); } - return function middleware(req: IApiRequest, res, next) { + return function middleware(req: IApiRequest, res: Response, next: NextFunction) { const { insights } = getProviders(req); let i = 0; let currentProvider = supportedProviders[i]; diff --git a/scripts/migrateLinks/index.ts b/middleware/types.ts similarity index 50% rename from scripts/migrateLinks/index.ts rename to middleware/types.ts index 6c6856b80..50b8e1de7 100644 --- a/scripts/migrateLinks/index.ts +++ b/middleware/types.ts @@ -3,9 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import Job from './task'; -import app from '../../app'; +import { Express } from 'express'; -app.runJob(Job, { - defaultDebugOutput: 'cache,restapi', -}); +export type ExpressWithStatic = Express & { + static: (path: string, options?: any) => Express; +}; diff --git a/package-lock.json b/package-lock.json index 911fbbe64..5e48390e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "opensource-management-portal", "version": "7.1.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -9,21 +9,22 @@ "version": "7.1.0", "license": "MIT", "dependencies": { - "@azure/cosmos": "3.17.3", + "@azure/cosmos": "4.0.0", "@azure/data-tables": "13.2.2", - "@azure/identity": "3.2.2", + "@azure/identity": "4.0.0", "@azure/keyvault-secrets": "4.7.0", - "@azure/service-bus": "7.9.0", - "@azure/storage-blob": "12.14.0", - "@azure/storage-queue": "12.14.0", - "@octokit/auth-app": "4.0.13", - "@octokit/plugin-paginate-graphql": "2.0.1", - "@octokit/request": "6.2.5", - "@octokit/rest": "19.0.11", + "@azure/service-bus": "7.9.3", + "@azure/storage-blob": "12.17.0", + "@azure/storage-queue": "12.16.0", + "@octokit/auth-app": "6.0.3", + "@octokit/plugin-paginate-graphql": "4.0.0", + "@octokit/request": "8.1.6", + "@octokit/rest": "20.0.2", + "@primer/octicons": "19.8.0", "app-root-path": "3.1.0", - "applicationinsights": "2.7.0", + "applicationinsights": "2.9.2", "async-prompt": "1.0.1", - "axios": "1.4.0", + "axios": "1.6.5", "basic-auth": "2.0.1", "body-parser": "1.20.2", "color-contrast-checker": "2.1.0", @@ -34,7 +35,7 @@ "deepmerge": "4.3.1", "dotenv": "16.3.1", "express": "4.18.2", - "express-async-handler": "1.1.4", + "express-async-handler": "1.2.0", "express-session": "1.17.3", "express-sslify": "1.2.0", "file-size": "1.0.0", @@ -43,83 +44,93 @@ "js-yaml": "4.1.0", "json-2-csv": "^3.18.0", "jsonc": "2.0.0", - "jsonwebtoken": "9.0.1", - "jwks-rsa": "3.0.1", + "jsonwebtoken": "9.0.2", + "jwks-rsa": "3.1.0", "language-map": "1.5.0", "lodash": "4.17.21", - "luxon": "3.3.0", + "luxon": "3.4.4", "memory-cache": "0.2.0", - "moment": "2.29.4", + "moment": "2.30.1", "morgan": "1.10.0", "node-jose": "2.2.0", - "nodemailer": "6.9.4", + "nodemailer": "6.9.8", "object-path": "0.11.8", - "octicons": "5.0.1", - "passport": "0.6.0", + "passport": "0.7.0", "passport-azure-ad": "4.3.5", "passport-github": "1.1.0", - "pg": "8.11.0", + "pg": "8.11.3", "pg-escape": "0.2.0", "pug": "3.0.2", "pug-load": "3.0.0", "recursive-readdir": "2.2.3", - "redis": "4.6.8", + "redis": "4.6.12", "secure-compare": "3.0.1", - "semver": "7.5.1", + "semver": "7.5.4", "serve-favicon": "2.5.0", "simple-oauth2": "5.0.0", "throat": "6.0.2", "tmp-promise": "3.0.3", - "validator": "13.9.0", + "validator": "13.11.0", "walk-back": "5.1.0" }, "devDependencies": { - "@types/debug": "4.1.7", - "@types/express": "4.17.17", - "@types/express-session": "1.17.7", - "@types/jest": "29.5.1", - "@types/lodash": "4.14.194", - "@types/luxon": "3.3.0", - "@types/memory-cache": "0.2.2", - "@types/morgan": "1.9.4", - "@types/node": "20.4.2", - "@types/node-jose": "1.1.10", - "@types/object-path": "0.11.1", - "@types/passport": "1.0.12", - "@types/passport-azure-ad": "4.3.1", - "@types/passport-github": "1.1.7", - "@types/pg": "8.10.1", - "@types/pug": "2.0.6", - "@types/recursive-readdir": "2.2.1", - "@types/semver": "7.5.0", - "@types/simple-oauth2": "5.0.4", - "@types/validator": "13.7.17", - "@typescript-eslint/eslint-plugin": "5.59.7", - "@typescript-eslint/parser": "5.59.7", - "cspell": "6.31.1", - "eslint": "8.41.0", - "eslint-config-prettier": "8.8.0", - "eslint-plugin-n": "16.0.0", - "eslint-plugin-prettier": "4.2.1", + "@types/cors": "2.8.17", + "@types/debug": "4.1.12", + "@types/express": "4.17.21", + "@types/express-session": "1.17.10", + "@types/jest": "29.5.11", + "@types/lodash": "4.14.202", + "@types/luxon": "3.4.0", + "@types/memory-cache": "0.2.5", + "@types/morgan": "1.9.9", + "@types/node": "20.11.0", + "@types/node-jose": "1.1.13", + "@types/object-path": "0.11.4", + "@types/passport": "1.0.16", + "@types/passport-azure-ad": "4.3.5", + "@types/passport-github": "1.1.12", + "@types/pg": "8.10.9", + "@types/pug": "2.0.10", + "@types/recursive-readdir": "2.2.4", + "@types/semver": "7.5.6", + "@types/simple-oauth2": "5.0.7", + "@types/validator": "13.11.8", + "@typescript-eslint/eslint-plugin": "6.18.1", + "@typescript-eslint/parser": "6.18.1", + "cspell": "8.3.2", + "eslint": "8.56.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-n": "16.6.2", + "eslint-plugin-prettier": "5.1.3", "husky": "8.0.3", - "jest": "29.5.0", + "jest": "29.7.0", "jest-junit": "16.0.0", - "lint-staged": "13.2.2", - "markdownlint-cli2": "0.7.1", - "prettier": "2.8.8", - "ts-jest": "29.1.0", - "ts-node": "10.9.1", + "lint-staged": "15.2.0", + "markdownlint-cli2": "0.12.0", + "prettier": "3.1.1", + "ts-jest": "29.1.1", + "ts-node": "10.9.2", "ts-prune": "0.10.3", - "typescript": "5.0.4" + "typescript": "5.3.3" }, "engines": { - "node": ">=16" + "node": ">=18" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/@ampproject/remapping": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -129,18 +140,20 @@ } }, "node_modules/@azure/abort-controller": { - "version": "1.0.4", - "license": "MIT", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", "dependencies": { - "tslib": "^2.0.0" + "tslib": "^2.2.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/core-amqp": { - "version": "3.3.0", - "license": "MIT", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@azure/core-amqp/-/core-amqp-4.1.0.tgz", + "integrity": "sha512-tjnviDypSAgjGBZCPw+sH7vDWz27N+z0xtQewp7+xH17/eb67VH4sApl3XHuxVBro6Y6pOfxCDpqFenOoGWz6Q==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -148,7 +161,6 @@ "@azure/logger": "^1.0.0", "buffer": "^6.0.0", "events": "^3.0.0", - "jssha": "^3.1.0", "process": "^0.11.10", "rhea": "^3.0.0", "rhea-promise": "^3.0.0", @@ -156,57 +168,67 @@ "util": "^0.12.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, - "node_modules/@azure/core-amqp/node_modules/@azure/core-util": { - "version": "1.3.2", - "license": "MIT", + "node_modules/@azure/core-auth": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.5.0.tgz", + "integrity": "sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw==", "dependencies": { "@azure/abort-controller": "^1.0.0", + "@azure/core-util": "^1.1.0", "tslib": "^2.2.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@azure/core-asynciterator-polyfill": { - "version": "1.0.2", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/core-auth": { - "version": "1.4.0", - "license": "MIT", + "node_modules/@azure/core-client": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.7.3.tgz", + "integrity": "sha512-kleJ1iUTxcO32Y06dH9Pfi9K4U+Tlb111WXEnbt7R/ne+NLRwppZiTGJuTD5VVoxTMK5NTbEtm5t2vcdNCFe2g==", "dependencies": { "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", "tslib": "^2.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, - "node_modules/@azure/core-client": { - "version": "1.5.0", - "license": "MIT", + "node_modules/@azure/core-http": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.4.tgz", + "integrity": "sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-asynciterator-polyfill": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.5.0", "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.5.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/@azure/core-http-compat": { "version": "1.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-1.3.0.tgz", + "integrity": "sha512-ZN9avruqbQ5TxopzG3ih3KRy52n8OAbitX3fnZT5go4hzu0J+KVPSzkL+Wt3hpJpdG8WIfg1sBD1tWkgUdEpBA==", "dependencies": { "@azure/abort-controller": "^1.0.4", "@azure/core-client": "^1.3.0", @@ -216,22 +238,36 @@ "node": ">=12.0.0" } }, + "node_modules/@azure/core-http/node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "dependencies": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/core-lro": { - "version": "2.2.4", - "license": "MIT", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.5.4.tgz", + "integrity": "sha512-3GJiMVH7/10bulzOKGrrLeG/uCBH/9VtxqaMcB9lIqAeamI/xYQSHJL/KcsLDuH+yTjYpro/u6D/MuRe4dN70Q==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.2.0", "@azure/logger": "^1.0.0", "tslib": "^2.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/@azure/core-paging": { "version": "1.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.5.0.tgz", + "integrity": "sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==", "dependencies": { "tslib": "^2.2.0" }, @@ -240,39 +276,28 @@ } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.10.1", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.13.0.tgz", + "integrity": "sha512-a62aP/wppgmnfIkJLfcB4ssPBcH94WzrzPVJ3tlJt050zX4lfmtnvy95D3igDo3f31StO+9BgPrzvkj4aOxnoA==", "dependencies": { - "@azure/abort-controller": "^1.0.0", + "@azure/abort-controller": "^1.1.0", "@azure/core-auth": "^1.4.0", "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.0.0", + "@azure/core-util": "^1.3.0", "@azure/logger": "^1.0.0", - "form-data": "^4.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@azure/core-rest-pipeline/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { "tslib": "^2.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" } }, "node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "license": "MIT", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", "dependencies": { - "@opentelemetry/api": "^1.0.1", "tslib": "^2.2.0" }, "engines": { @@ -280,21 +305,23 @@ } }, "node_modules/@azure/core-util": { - "version": "1.2.0", - "license": "MIT", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.6.1.tgz", + "integrity": "sha512-h5taHeySlsV9qxuK64KZxy4iln1BtMYlNt5jbuEFN3UFSAd1EwKg/Gjl5a6tZ/W8t6li3xPnutOx7zbDyXnPmQ==", "dependencies": { "@azure/abort-controller": "^1.0.0", "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@azure/core-xml": { - "version": "1.3.3", - "license": "MIT", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.3.4.tgz", + "integrity": "sha512-B1xI79Ur/u+KR69fGTcsMNj8KDjBSqAy0Ys6Byy4Qm1CqoUy7gCT5A7Pej0EBWRskuH6bpCwrAnosfmQEalkcg==", "dependencies": { - "fast-xml-parser": "^4.0.8", + "fast-xml-parser": "^4.2.4", "tslib": "^2.2.0" }, "engines": { @@ -302,8 +329,9 @@ } }, "node_modules/@azure/cosmos": { - "version": "3.17.3", - "license": "MIT", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.0.0.tgz", + "integrity": "sha512-/Z27p1+FTkmjmm8jk90zi/HrczPHw2t8WecFnsnTe4xGocWl0Z4clP0YlLUTJPhRLWYa5upwD9rMvKJkS1f1kg==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -323,19 +351,10 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/cosmos/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/data-tables": { "version": "13.2.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@azure/data-tables/-/data-tables-13.2.2.tgz", + "integrity": "sha512-Dq2Aq0mMMF0BPzYQKdBY/OtO7VemP/foh6z+mJpUO1hRL+65C1rGQUJf20LJHotSyU8wHb4HJzOs+Z50GXSy1w==", "dependencies": { "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", @@ -351,54 +370,34 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/data-tables/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/identity": { - "version": "3.2.2", - "license": "MIT", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.0.0.tgz", + "integrity": "sha512-gtPYxIL0kI39Dw4t3HvlbfhOdXqKD2MqDgynlklF0j728j51dcKgRo6FLX0QzpBw/1gGfLxjMXqq3nKOSQ2lmA==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", + "@azure/core-auth": "^1.5.0", "@azure/core-client": "^1.4.0", "@azure/core-rest-pipeline": "^1.1.0", "@azure/core-tracing": "^1.0.0", "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^2.32.2", - "@azure/msal-common": "^9.0.2", - "@azure/msal-node": "^1.14.6", + "@azure/msal-browser": "^3.5.0", + "@azure/msal-node": "^2.5.1", "events": "^3.0.0", "jws": "^4.0.0", "open": "^8.0.0", "stoppable": "^1.1.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@azure/identity/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { "tslib": "^2.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" } }, "node_modules/@azure/keyvault-secrets": { "version": "4.7.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@azure/keyvault-secrets/-/keyvault-secrets-4.7.0.tgz", + "integrity": "sha512-YvlFXRQ+SI5NT4GtSFbb6HGo6prW3yzDab8tr6vga2/SjDQew3wJsCAAr/xwZz6XshFXCYEX26CDKmPf+SJKJg==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -416,100 +415,72 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/keyvault-secrets/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/logger": { - "version": "1.0.3", - "license": "MIT", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz", + "integrity": "sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==", "dependencies": { "tslib": "^2.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/@azure/msal-browser": { - "version": "2.37.0", - "license": "MIT", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.7.0.tgz", + "integrity": "sha512-ktDB/Gf7UDgYBJOnoIlh70lxIo4e1/D2UgHuayB4RntN1IlusfTtIVH3k8NpJMdl+38tfTXIaUoR+qlr5voZEg==", "dependencies": { - "@azure/msal-common": "13.0.0" + "@azure/msal-common": "14.6.0" }, "engines": { "node": ">=0.8.0" } }, - "node_modules/@azure/msal-browser/node_modules/@azure/msal-common": { - "version": "13.0.0", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@azure/msal-common": { - "version": "9.1.1", - "license": "MIT", + "version": "14.6.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.6.0.tgz", + "integrity": "sha512-AGusT/JvxdzJIYi5u0n97cmhd3pUT6UuI6rEkT5iDeT2FGcV0/EB8pk+dy6GLPpYg9vhDCuyoYrEZGd+2UeCCQ==", "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-node": { - "version": "1.17.2", - "license": "MIT", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.6.1.tgz", + "integrity": "sha512-wYwz83pWatTNWUCkTi3cAOXbchad5FnZz/pbZz7b8Z6FuEqohXcTtg6BLip9SmcjN6FlbwUdJIZYOof2v1Gnrg==", "dependencies": { - "@azure/msal-common": "13.0.0", + "@azure/msal-common": "14.6.0", "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, "engines": { - "node": "10 || 12 || 14 || 16 || 18" - } - }, - "node_modules/@azure/msal-node/node_modules/@azure/msal-common": { - "version": "13.0.0", - "license": "MIT", - "engines": { - "node": ">=0.8.0" + "node": ">=16" } }, "node_modules/@azure/opentelemetry-instrumentation-azure-sdk": { - "version": "1.0.0-beta.3", - "license": "MIT", + "version": "1.0.0-beta.5", + "resolved": "https://registry.npmjs.org/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz", + "integrity": "sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==", "dependencies": { "@azure/core-tracing": "^1.0.0", "@azure/logger": "^1.0.0", - "@opentelemetry/api": "^1.4.0", - "@opentelemetry/core": "^1.9.0", - "@opentelemetry/instrumentation": "^0.35.0", + "@opentelemetry/api": "^1.4.1", + "@opentelemetry/core": "^1.15.2", + "@opentelemetry/instrumentation": "^0.41.2", "tslib": "^2.2.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@azure/opentelemetry-instrumentation-azure-sdk/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/service-bus": { - "version": "7.9.0", - "license": "MIT", + "version": "7.9.3", + "resolved": "https://registry.npmjs.org/@azure/service-bus/-/service-bus-7.9.3.tgz", + "integrity": "sha512-6g37YpVTzRHI75BkYPiB4zqbYhQHM1Jvd+sNfRCbXeRW5FLsWoXgFVTw3Jv5kkMMX1pUNtrkaQhEoeTwtm5v3w==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-amqp": "^3.3.0", + "@azure/core-amqp": "^4.1.0", "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.0.0", "@azure/core-paging": "^1.4.0", @@ -528,33 +499,13 @@ "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@azure/service-bus/node_modules/@azure/core-tracing": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/service-bus/node_modules/@azure/core-util": { - "version": "1.3.2", - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/@azure/storage-blob": { - "version": "12.14.0", - "license": "MIT", + "version": "12.17.0", + "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.17.0.tgz", + "integrity": "sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^3.0.0", @@ -569,44 +520,22 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/storage-blob/node_modules/@azure/core-http": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@azure/storage-blob/node_modules/xml2js": { - "version": "0.5.0", - "license": "MIT", + "node_modules/@azure/storage-blob/node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/storage-queue": { - "version": "12.14.0", - "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.14.0.tgz", - "integrity": "sha512-1j6uxhzCcbEDVPOTNWIJ5CsLzOAU5U/bXgGZeT25fy6IghFTC1JlPGALez2CWJ9fBVj6AmSnsiBXL/77iXhSpg==", + "version": "12.16.0", + "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.16.0.tgz", + "integrity": "sha512-HzwzMsNAh2PwLtx9WfXndj9elUr6duDFak5CjM6BxdWhLqf37VywPCWmEzjxuFfrq30c1T34+MjMXnN6YgqRUw==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^3.0.0", @@ -619,79 +548,117 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/storage-queue/node_modules/@azure/core-http": { - "version": "3.0.1", - "license": "MIT", + "node_modules/@azure/storage-queue/node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=12.0.0" } }, - "node_modules/@azure/storage-queue/node_modules/xml2js": { - "version": "0.5.0", - "license": "MIT", + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.21.4", + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/highlight": "^7.18.6" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, "node_modules/@babel/compat-data": { - "version": "7.21.7", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.8", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -701,25 +668,22 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.21.5", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.21.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -729,176 +693,190 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.5", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.21.5", + "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, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", + "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, - "license": "MIT", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.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", + "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, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.5", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-simple-access": "^7.21.5", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.21.5", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.21.5", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.21.5" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", + "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, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "license": "MIT", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "license": "MIT", + "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==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.5", + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", + "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -907,8 +885,9 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -918,8 +897,9 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -929,39 +909,29 @@ "node": ">=4" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -970,8 +940,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.8", - "license": "MIT", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -981,8 +952,9 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -992,8 +964,9 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1003,8 +976,9 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -1014,8 +988,9 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1025,8 +1000,9 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1035,11 +1011,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.21.4", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1050,8 +1027,9 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1061,8 +1039,9 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1072,8 +1051,9 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1083,8 +1063,9 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1094,8 +1075,9 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1105,8 +1087,9 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1116,8 +1099,9 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1129,11 +1113,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.21.4", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1143,32 +1128,34 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", - "debug": "^4.1.0", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@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.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -1177,18 +1164,20 @@ }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.21.5", - "license": "MIT", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1197,342 +1186,443 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true }, "node_modules/@cspell/cspell-bundled-dicts": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.3.2.tgz", + "integrity": "sha512-3ubOgz1/MDixJbq//0rQ2omB3cSdhVJDviERZeiREGz4HOq84aaK1Fqbw5SjNZHvhpoq+AYXm6kJbIAH8YhKgg==", "dev": true, - "license": "MIT", "dependencies": { - "@cspell/dict-ada": "^4.0.1", - "@cspell/dict-aws": "^3.0.0", - "@cspell/dict-bash": "^4.1.1", - "@cspell/dict-companies": "^3.0.9", - "@cspell/dict-cpp": "^5.0.2", - "@cspell/dict-cryptocurrencies": "^3.0.1", + "@cspell/dict-ada": "^4.0.2", + "@cspell/dict-aws": "^4.0.1", + "@cspell/dict-bash": "^4.1.3", + "@cspell/dict-companies": "^3.0.29", + "@cspell/dict-cpp": "^5.0.10", + "@cspell/dict-cryptocurrencies": "^5.0.0", "@cspell/dict-csharp": "^4.0.2", - "@cspell/dict-css": "^4.0.5", - "@cspell/dict-dart": "^2.0.2", - "@cspell/dict-django": "^4.0.2", - "@cspell/dict-docker": "^1.1.6", + "@cspell/dict-css": "^4.0.12", + "@cspell/dict-dart": "^2.0.3", + "@cspell/dict-django": "^4.1.0", + "@cspell/dict-docker": "^1.1.7", "@cspell/dict-dotnet": "^5.0.0", - "@cspell/dict-elixir": "^4.0.2", - "@cspell/dict-en_us": "^4.3.2", - "@cspell/dict-en-common-misspellings": "^1.0.2", + "@cspell/dict-elixir": "^4.0.3", + "@cspell/dict-en_us": "^4.3.13", + "@cspell/dict-en-common-misspellings": "^2.0.0", "@cspell/dict-en-gb": "1.1.33", - "@cspell/dict-filetypes": "^3.0.0", - "@cspell/dict-fonts": "^3.0.1", + "@cspell/dict-filetypes": "^3.0.3", + "@cspell/dict-fonts": "^4.0.0", + "@cspell/dict-fsharp": "^1.0.1", "@cspell/dict-fullstack": "^3.1.5", "@cspell/dict-gaming-terms": "^1.0.4", - "@cspell/dict-git": "^2.0.0", - "@cspell/dict-golang": "^6.0.1", + "@cspell/dict-git": "^3.0.0", + "@cspell/dict-golang": "^6.0.5", "@cspell/dict-haskell": "^4.0.1", - "@cspell/dict-html": "^4.0.3", + "@cspell/dict-html": "^4.0.5", "@cspell/dict-html-symbol-entities": "^4.0.0", - "@cspell/dict-java": "^5.0.5", - "@cspell/dict-k8s": "^1.0.1", + "@cspell/dict-java": "^5.0.6", + "@cspell/dict-k8s": "^1.0.2", "@cspell/dict-latex": "^4.0.0", - "@cspell/dict-lorem-ipsum": "^3.0.0", - "@cspell/dict-lua": "^4.0.1", - "@cspell/dict-node": "^4.0.2", - "@cspell/dict-npm": "^5.0.5", - "@cspell/dict-php": "^4.0.1", - "@cspell/dict-powershell": "^5.0.1", - "@cspell/dict-public-licenses": "^2.0.2", - "@cspell/dict-python": "^4.0.2", + "@cspell/dict-lorem-ipsum": "^4.0.0", + "@cspell/dict-lua": "^4.0.3", + "@cspell/dict-makefile": "^1.0.0", + "@cspell/dict-node": "^4.0.3", + "@cspell/dict-npm": "^5.0.14", + "@cspell/dict-php": "^4.0.5", + "@cspell/dict-powershell": "^5.0.3", + "@cspell/dict-public-licenses": "^2.0.5", + "@cspell/dict-python": "^4.1.11", "@cspell/dict-r": "^2.0.1", - "@cspell/dict-ruby": "^5.0.0", + "@cspell/dict-ruby": "^5.0.2", "@cspell/dict-rust": "^4.0.1", "@cspell/dict-scala": "^5.0.0", - "@cspell/dict-software-terms": "^3.1.6", - "@cspell/dict-sql": "^2.1.0", + "@cspell/dict-software-terms": "^3.3.15", + "@cspell/dict-sql": "^2.1.3", "@cspell/dict-svelte": "^1.0.2", "@cspell/dict-swift": "^2.0.1", - "@cspell/dict-typescript": "^3.1.1", + "@cspell/dict-typescript": "^3.1.2", "@cspell/dict-vue": "^3.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" + } + }, + "node_modules/@cspell/cspell-json-reporter": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.3.2.tgz", + "integrity": "sha512-gHSz4jXMJPcxx+lOGfXhHuoyenAWQ8PVA/atHFrWYKo1LzKTbpkEkrsDnlX8QNJubc3EMH63Uy+lOIaFDVyHiQ==", + "dev": true, + "dependencies": { + "@cspell/cspell-types": "8.3.2" + }, + "engines": { + "node": ">=18" } }, "node_modules/@cspell/cspell-pipe": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.3.2.tgz", + "integrity": "sha512-GZmDwvQGOjQi3IjD4k9xXeVTDANczksOsgVKb3v2QZk9mR4Qj8c6Uarjd4AgSiIhu/wBliJfzr5rWFJu4X2VfQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=14" + "node": ">=18" + } + }, + "node_modules/@cspell/cspell-resolver": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.3.2.tgz", + "integrity": "sha512-w2Tmb95bzdEz9L4W5qvsP5raZbyEzKL7N2ksU/+yh8NEJcTuExmAl/nMnb3aIk7m2b+kPHnMOcJuwfUMLmyv4A==", + "dev": true, + "dependencies": { + "global-directory": "^4.0.1" + }, + "engines": { + "node": ">=18" } }, "node_modules/@cspell/cspell-service-bus": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.3.2.tgz", + "integrity": "sha512-skTHNyVi74//W/O+f4IauDhm6twA9S2whkylonsIzPxEl4Pn3y2ZEMXNki/MWUwZfDIzKKSxlcREH61g7zCvhg==", "dev": true, - "license": "MIT", "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/@cspell/cspell-types": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.3.2.tgz", + "integrity": "sha512-qS/gWd9ItOrN6ZX5pwC9lJjnBoyiAyhxYq0GUXuV892LQvwrBmECGk6KhsA1lPW7JJS7o57YTAS1jmXnmXMEpg==", "dev": true, - "license": "MIT", "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/@cspell/dict-ada": { - "version": "4.0.1", - "dev": true, - "license": "MIT" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.0.2.tgz", + "integrity": "sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==", + "dev": true }, "node_modules/@cspell/dict-aws": { - "version": "3.0.0", - "dev": true, - "license": "MIT" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.1.tgz", + "integrity": "sha512-NXO+kTPQGqaaJKa4kO92NAXoqS+i99dQzf3/L1BxxWVSBS3/k1f3uhmqIh7Crb/n22W793lOm0D9x952BFga3Q==", + "dev": true }, "node_modules/@cspell/dict-bash": { - "version": "4.1.1", - "dev": true, - "license": "MIT" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.1.3.tgz", + "integrity": "sha512-tOdI3QVJDbQSwPjUkOiQFhYcu2eedmX/PtEpVWg0aFps/r6AyjUQINtTgpqMYnYuq8O1QUIQqnpx21aovcgZCw==", + "dev": true }, "node_modules/@cspell/dict-companies": { - "version": "3.0.10", - "dev": true, - "license": "MIT" + "version": "3.0.31", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.0.31.tgz", + "integrity": "sha512-hKVpV/lcGKP4/DpEPS8P4osPvFH/YVLJaDn9cBIOH6/HSmL5LbFgJNKpMGaYRbhm2FEX56MKE3yn/MNeNYuesQ==", + "dev": true }, "node_modules/@cspell/dict-cpp": { - "version": "5.0.3", - "dev": true, - "license": "MIT" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.1.1.tgz", + "integrity": "sha512-Qy9fNsR/5RcQ6G85gDKFjvzh0AdgAilLQeSXPtqY21Fx1kCjUqdVVJYMmHUREgcxH6ptAxtn5knTWU4PIhQtOw==", + "dev": true }, "node_modules/@cspell/dict-cryptocurrencies": { - "version": "3.0.1", - "dev": true, - "license": "MIT" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.0.tgz", + "integrity": "sha512-Z4ARIw5+bvmShL+4ZrhDzGhnc9znaAGHOEMaB/GURdS/jdoreEDY34wdN0NtdLHDO5KO7GduZnZyqGdRoiSmYA==", + "dev": true }, "node_modules/@cspell/dict-csharp": { "version": "4.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.2.tgz", + "integrity": "sha512-1JMofhLK+4p4KairF75D3A924m5ERMgd1GvzhwK2geuYgd2ZKuGW72gvXpIV7aGf52E3Uu1kDXxxGAiZ5uVG7g==", + "dev": true }, "node_modules/@cspell/dict-css": { - "version": "4.0.6", - "dev": true, - "license": "MIT" + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.12.tgz", + "integrity": "sha512-vGBgPM92MkHQF5/2jsWcnaahOZ+C6OE/fPvd5ScBP72oFY9tn5GLuomcyO0z8vWCr2e0nUSX1OGimPtcQAlvSw==", + "dev": true }, "node_modules/@cspell/dict-dart": { - "version": "2.0.2", - "dev": true, - "license": "MIT" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.0.3.tgz", + "integrity": "sha512-cLkwo1KT5CJY5N5RJVHks2genFkNCl/WLfj+0fFjqNR+tk3tBI1LY7ldr9piCtSFSm4x9pO1x6IV3kRUY1lLiw==", + "dev": true + }, + "node_modules/@cspell/dict-data-science": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-1.0.11.tgz", + "integrity": "sha512-TaHAZRVe0Zlcc3C23StZqqbzC0NrodRwoSAc8dis+5qLeLLnOCtagYQeROQvDlcDg3X/VVEO9Whh4W/z4PAmYQ==", + "dev": true }, "node_modules/@cspell/dict-django": { - "version": "4.0.2", - "dev": true, - "license": "MIT" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.0.tgz", + "integrity": "sha512-bKJ4gPyrf+1c78Z0Oc4trEB9MuhcB+Yg+uTTWsvhY6O2ncFYbB/LbEZfqhfmmuK/XJJixXfI1laF2zicyf+l0w==", + "dev": true }, "node_modules/@cspell/dict-docker": { - "version": "1.1.6", - "dev": true, - "license": "MIT" + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.7.tgz", + "integrity": "sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==", + "dev": true }, "node_modules/@cspell/dict-dotnet": { "version": "5.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-dotnet/-/dict-dotnet-5.0.0.tgz", + "integrity": "sha512-EOwGd533v47aP5QYV8GlSSKkmM9Eq8P3G/eBzSpH3Nl2+IneDOYOBLEUraHuiCtnOkNsz0xtZHArYhAB2bHWAw==", + "dev": true }, "node_modules/@cspell/dict-elixir": { "version": "4.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-elixir/-/dict-elixir-4.0.3.tgz", + "integrity": "sha512-g+uKLWvOp9IEZvrIvBPTr/oaO6619uH/wyqypqvwpmnmpjcfi8+/hqZH8YNKt15oviK8k4CkINIqNhyndG9d9Q==", + "dev": true }, "node_modules/@cspell/dict-en_us": { - "version": "4.3.2", - "dev": true, - "license": "MIT" + "version": "4.3.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.13.tgz", + "integrity": "sha512-T6lHiGCjloGNE0d8CogF+efJZPCAP8zdzn+KnlI0Bmjaz5nvG2LTX7CXl1zkOl1nYYev0FuIk9WJ9YPVRjcFbQ==", + "dev": true }, "node_modules/@cspell/dict-en-common-misspellings": { - "version": "1.0.2", - "dev": true, - "license": "MIT" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.0.tgz", + "integrity": "sha512-NOg8dlv37/YqLkCfBs5OXeJm/Wcfb/CzeOmOZJ2ZXRuxwsNuolb4TREUce0yAXRqMhawahY5TSDRJJBgKjBOdw==", + "dev": true }, "node_modules/@cspell/dict-en-gb": { "version": "1.1.33", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz", + "integrity": "sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==", + "dev": true }, "node_modules/@cspell/dict-filetypes": { - "version": "3.0.0", - "dev": true, - "license": "MIT" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.3.tgz", + "integrity": "sha512-J9UP+qwwBLfOQ8Qg9tAsKtSY/WWmjj21uj6zXTI9hRLD1eG1uUOLcfVovAmtmVqUWziPSKMr87F6SXI3xmJXgw==", + "dev": true }, "node_modules/@cspell/dict-fonts": { - "version": "3.0.2", - "dev": true, - "license": "MIT" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-fonts/-/dict-fonts-4.0.0.tgz", + "integrity": "sha512-t9V4GeN/m517UZn63kZPUYP3OQg5f0OBLSd3Md5CU3eH1IFogSvTzHHnz4Wqqbv8NNRiBZ3HfdY/pqREZ6br3Q==", + "dev": true + }, + "node_modules/@cspell/dict-fsharp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-fsharp/-/dict-fsharp-1.0.1.tgz", + "integrity": "sha512-23xyPcD+j+NnqOjRHgW3IU7Li912SX9wmeefcY0QxukbAxJ/vAN4rBpjSwwYZeQPAn3fxdfdNZs03fg+UM+4yQ==", + "dev": true }, "node_modules/@cspell/dict-fullstack": { "version": "3.1.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-fullstack/-/dict-fullstack-3.1.5.tgz", + "integrity": "sha512-6ppvo1dkXUZ3fbYn/wwzERxCa76RtDDl5Afzv2lijLoijGGUw5yYdLBKJnx8PJBGNLh829X352ftE7BElG4leA==", + "dev": true }, "node_modules/@cspell/dict-gaming-terms": { - "version": "1.0.4", - "dev": true, - "license": "MIT" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.0.5.tgz", + "integrity": "sha512-C3riccZDD3d9caJQQs1+MPfrUrQ+0KHdlj9iUR1QD92FgTOF6UxoBpvHUUZ9YSezslcmpFQK4xQQ5FUGS7uWfw==", + "dev": true }, "node_modules/@cspell/dict-git": { - "version": "2.0.0", - "dev": true, - "license": "MIT" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.0.tgz", + "integrity": "sha512-simGS/lIiXbEaqJu9E2VPoYW1OTC2xrwPPXNXFMa2uo/50av56qOuaxDrZ5eH1LidFXwoc8HROCHYeKoNrDLSw==", + "dev": true }, "node_modules/@cspell/dict-golang": { - "version": "6.0.1", - "dev": true, - "license": "MIT" + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.5.tgz", + "integrity": "sha512-w4mEqGz4/wV+BBljLxduFNkMrd3rstBNDXmoX5kD4UTzIb4Sy0QybWCtg2iVT+R0KWiRRA56QKOvBsgXiddksA==", + "dev": true }, "node_modules/@cspell/dict-haskell": { "version": "4.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-haskell/-/dict-haskell-4.0.1.tgz", + "integrity": "sha512-uRrl65mGrOmwT7NxspB4xKXFUenNC7IikmpRZW8Uzqbqcu7ZRCUfstuVH7T1rmjRgRkjcIjE4PC11luDou4wEQ==", + "dev": true }, "node_modules/@cspell/dict-html": { - "version": "4.0.3", - "dev": true, - "license": "MIT" + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.5.tgz", + "integrity": "sha512-p0brEnRybzSSWi8sGbuVEf7jSTDmXPx7XhQUb5bgG6b54uj+Z0Qf0V2n8b/LWwIPJNd1GygaO9l8k3HTCy1h4w==", + "dev": true }, "node_modules/@cspell/dict-html-symbol-entities": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.0.tgz", + "integrity": "sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==", + "dev": true }, "node_modules/@cspell/dict-java": { - "version": "5.0.5", - "dev": true, - "license": "MIT" + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-java/-/dict-java-5.0.6.tgz", + "integrity": "sha512-kdE4AHHHrixyZ5p6zyms1SLoYpaJarPxrz8Tveo6gddszBVVwIUZ+JkQE1bWNLK740GWzIXdkznpUfw1hP9nXw==", + "dev": true }, "node_modules/@cspell/dict-k8s": { - "version": "1.0.1", - "dev": true, - "license": "MIT" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.2.tgz", + "integrity": "sha512-tLT7gZpNPnGa+IIFvK9SP1LrSpPpJ94a/DulzAPOb1Q2UBFwdpFd82UWhio0RNShduvKG/WiMZf/wGl98pn+VQ==", + "dev": true }, "node_modules/@cspell/dict-latex": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-latex/-/dict-latex-4.0.0.tgz", + "integrity": "sha512-LPY4y6D5oI7D3d+5JMJHK/wxYTQa2lJMSNxps2JtuF8hbAnBQb3igoWEjEbIbRRH1XBM0X8dQqemnjQNCiAtxQ==", + "dev": true }, "node_modules/@cspell/dict-lorem-ipsum": { - "version": "3.0.0", - "dev": true, - "license": "MIT" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.0.tgz", + "integrity": "sha512-1l3yjfNvMzZPibW8A7mQU4kTozwVZVw0AvFEdy+NcqtbxH+TvbSkNMqROOFWrkD2PjnKG0+Ea0tHI2Pi6Gchnw==", + "dev": true }, "node_modules/@cspell/dict-lua": { - "version": "4.0.1", - "dev": true, - "license": "MIT" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-lua/-/dict-lua-4.0.3.tgz", + "integrity": "sha512-lDHKjsrrbqPaea13+G9s0rtXjMO06gPXPYRjRYawbNmo4E/e3XFfVzeci3OQDQNDmf2cPOwt9Ef5lu2lDmwfJg==", + "dev": true + }, + "node_modules/@cspell/dict-makefile": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-makefile/-/dict-makefile-1.0.0.tgz", + "integrity": "sha512-3W9tHPcSbJa6s0bcqWo6VisEDTSN5zOtDbnPabF7rbyjRpNo0uHXHRJQF8gAbFzoTzBBhgkTmrfSiuyQm7vBUQ==", + "dev": true }, "node_modules/@cspell/dict-node": { - "version": "4.0.2", - "dev": true, - "license": "MIT" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-4.0.3.tgz", + "integrity": "sha512-sFlUNI5kOogy49KtPg8SMQYirDGIAoKBO3+cDLIwD4MLdsWy1q0upc7pzGht3mrjuyMiPRUV14Bb0rkVLrxOhg==", + "dev": true }, "node_modules/@cspell/dict-npm": { - "version": "5.0.5", - "dev": true, - "license": "MIT" + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.0.15.tgz", + "integrity": "sha512-sX0X5YWNW54F4baW7b5JJB6705OCBIZtUqjOghlJNORS5No7QY1IX1zc5FxNNu4gsaCZITAmfMi4ityXEsEThA==", + "dev": true }, "node_modules/@cspell/dict-php": { - "version": "4.0.1", - "dev": true, - "license": "MIT" + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.0.5.tgz", + "integrity": "sha512-9r8ao7Z/mH9Z8pSB7yLtyvcCJWw+/MnQpj7xGVYzIV7V2ZWDRjXZAMgteHMJ37m8oYz64q5d4tiipD300QSetQ==", + "dev": true }, "node_modules/@cspell/dict-powershell": { - "version": "5.0.1", - "dev": true, - "license": "MIT" + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-powershell/-/dict-powershell-5.0.3.tgz", + "integrity": "sha512-lEdzrcyau6mgzu1ie98GjOEegwVHvoaWtzQnm1ie4DyZgMr+N6D0Iyj1lzvtmt0snvsDFa5F2bsYzf3IMKcpcA==", + "dev": true }, "node_modules/@cspell/dict-public-licenses": { - "version": "2.0.2", - "dev": true, - "license": "MIT" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.5.tgz", + "integrity": "sha512-91HK4dSRri/HqzAypHgduRMarJAleOX5NugoI8SjDLPzWYkwZ1ftuCXSk+fy8DLc3wK7iOaFcZAvbjmnLhVs4A==", + "dev": true }, "node_modules/@cspell/dict-python": { - "version": "4.0.4", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.1.11.tgz", + "integrity": "sha512-XG+v3PumfzUW38huSbfT15Vqt3ihNb462ulfXifpQllPok5OWynhszCLCRQjQReV+dgz784ST4ggRxW452/kVg==", "dev": true, - "license": "MIT" + "dependencies": { + "@cspell/dict-data-science": "^1.0.11" + } }, "node_modules/@cspell/dict-r": { "version": "2.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-r/-/dict-r-2.0.1.tgz", + "integrity": "sha512-KCmKaeYMLm2Ip79mlYPc8p+B2uzwBp4KMkzeLd5E6jUlCL93Y5Nvq68wV5fRLDRTf7N1LvofkVFWfDcednFOgA==", + "dev": true }, "node_modules/@cspell/dict-ruby": { - "version": "5.0.0", - "dev": true, - "license": "MIT" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-ruby/-/dict-ruby-5.0.2.tgz", + "integrity": "sha512-cIh8KTjpldzFzKGgrqUX4bFyav5lC52hXDKo4LbRuMVncs3zg4hcSf4HtURY+f2AfEZzN6ZKzXafQpThq3dl2g==", + "dev": true }, "node_modules/@cspell/dict-rust": { - "version": "4.0.1", - "dev": true, - "license": "MIT" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.2.tgz", + "integrity": "sha512-RhziKDrklzOntxAbY3AvNR58wnFGIo3YS8+dNeLY36GFuWOvXDHFStYw5Pod4f/VXbO/+1tXtywCC4zWfB2p1w==", + "dev": true }, "node_modules/@cspell/dict-scala": { "version": "5.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-scala/-/dict-scala-5.0.0.tgz", + "integrity": "sha512-ph0twaRoV+ylui022clEO1dZ35QbeEQaKTaV2sPOsdwIokABPIiK09oWwGK9qg7jRGQwVaRPEq0Vp+IG1GpqSQ==", + "dev": true }, "node_modules/@cspell/dict-software-terms": { - "version": "3.1.8", - "dev": true, - "license": "MIT" + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-3.3.16.tgz", + "integrity": "sha512-ixorEP80LGxAU+ODVSn/CYIDjV0XAlZ2VrBu7CT+PwUFJ7h8o3JX1ywKB4qnt0hHru3JjWFtBoBThmZdrXnREQ==", + "dev": true }, "node_modules/@cspell/dict-sql": { - "version": "2.1.0", - "dev": true, - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.1.3.tgz", + "integrity": "sha512-SEyTNKJrjqD6PAzZ9WpdSu6P7wgdNtGV2RV8Kpuw1x6bV+YsSptuClYG+JSdRExBTE6LwIe1bTklejUp3ZP8TQ==", + "dev": true }, "node_modules/@cspell/dict-svelte": { "version": "1.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-svelte/-/dict-svelte-1.0.2.tgz", + "integrity": "sha512-rPJmnn/GsDs0btNvrRBciOhngKV98yZ9SHmg8qI6HLS8hZKvcXc0LMsf9LLuMK1TmS2+WQFAan6qeqg6bBxL2Q==", + "dev": true }, "node_modules/@cspell/dict-swift": { "version": "2.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-swift/-/dict-swift-2.0.1.tgz", + "integrity": "sha512-gxrCMUOndOk7xZFmXNtkCEeroZRnS2VbeaIPiymGRHj5H+qfTAzAKxtv7jJbVA3YYvEzWcVE2oKDP4wcbhIERw==", + "dev": true }, "node_modules/@cspell/dict-typescript": { - "version": "3.1.1", - "dev": true, - "license": "MIT" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.1.2.tgz", + "integrity": "sha512-lcNOYWjLUvDZdLa0UMNd/LwfVdxhE9rKA+agZBGjL3lTA3uNvH7IUqSJM/IXhJoBpLLMVEOk8v1N9xi+vDuCdA==", + "dev": true }, "node_modules/@cspell/dict-vue": { "version": "3.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@cspell/dict-vue/-/dict-vue-3.0.0.tgz", + "integrity": "sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==", + "dev": true }, "node_modules/@cspell/dynamic-import": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.3.2.tgz", + "integrity": "sha512-4t0xM5luA3yQhar2xWvYK4wQSDB2r0u8XkpzzJqd57MnJXd7uIAxI0awGUrDXukadRaCo0tDIlMUBemH48SNVg==", "dev": true, - "license": "MIT", "dependencies": { - "import-meta-resolve": "^2.2.2" + "import-meta-resolve": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=18.0" } }, "node_modules/@cspell/strong-weak-map": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.3.2.tgz", + "integrity": "sha512-Mte/2000ap278kRYOUhiGWI7MNr1+A7WSWJmlcdP4CAH5SO20sZI3/cyZLjJJEyapdhK5vaP1L5J9sUcVDHd3A==", "dev": true, - "license": "MIT", "engines": { - "node": ">=14.6" + "node": ">=18" } }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -1542,8 +1632,9 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1551,8 +1642,9 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -1564,21 +1656,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, - "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -1593,47 +1687,77 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { - "version": "8.41.0", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@hapi/boom": { "version": "10.0.1", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-10.0.1.tgz", + "integrity": "sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==", "dependencies": { "@hapi/hoek": "^11.0.2" } }, "node_modules/@hapi/boom/node_modules/@hapi/hoek": { - "version": "11.0.2", - "license": "BSD-3-Clause" + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz", + "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==" }, "node_modules/@hapi/bourne": { "version": "3.0.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-3.0.0.tgz", + "integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==" }, "node_modules/@hapi/hoek": { "version": "10.0.1", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-10.0.1.tgz", + "integrity": "sha512-CvlW7jmOhWzuqOqiJQ3rQVLMcREh0eel4IBnxDx2FAcK8g7qoJRQK4L1CPBASoCY6y8e6zuCy3f2g+HWdkzcMw==" }, "node_modules/@hapi/topo": { "version": "5.1.0", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@hapi/topo/node_modules/@hapi/hoek": { "version": "9.3.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "node_modules/@hapi/wreck": { "version": "18.0.1", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-18.0.1.tgz", + "integrity": "sha512-OLHER70+rZxvDl75xq3xXOfd3e8XIvz8fWY0dqg92UvhZ29zo24vQgfqgHSYhB5ZiuFpSLeriOisAlxAo/1jWg==", "dependencies": { "@hapi/boom": "^10.0.1", "@hapi/bourne": "^3.0.0", @@ -1641,26 +1765,51 @@ } }, "node_modules/@hapi/wreck/node_modules/@hapi/hoek": { - "version": "11.0.2", - "license": "BSD-3-Clause" + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz", + "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -1670,14 +1819,85 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, - "license": "BSD-3-Clause" + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -1691,16 +1911,18 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -1711,8 +1933,9 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1723,8 +1946,9 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -1734,8 +1958,9 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -1748,8 +1973,9 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -1759,59 +1985,111 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/@jest/core": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -1827,84 +2105,160 @@ } } }, + "node_modules/@jest/core/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@jest/environment": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0" + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, - "license": "MIT", "dependencies": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, - "license": "MIT", "dependencies": { - "jest-get-type": "^29.4.3" + "jest-get-type": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, - "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -1912,13 +2266,13 @@ "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1936,37 +2290,110 @@ } } }, - "node_modules/@jest/schemas": { - "version": "29.4.3", + "node_modules/@jest/reporters/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.25.16" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@jest/source-map": { - "version": "29.4.3", + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-result": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1975,13 +2402,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/test-result": "^29.5.0", + "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -1989,21 +2417,22 @@ } }, "node_modules/@jest/transform": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -2013,12 +2442,75 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/@jest/types": { - "version": "29.5.0", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -2029,10 +2521,60 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2043,48 +2585,49 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true, - "license": "MIT" - }, "node_modules/@microsoft/applicationinsights-web-snippet": { "version": "1.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-snippet/-/applicationinsights-web-snippet-1.0.1.tgz", + "integrity": "sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2095,16 +2638,18 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2114,268 +2659,279 @@ } }, "node_modules/@octokit/auth-app": { - "version": "4.0.13", - "license": "MIT", - "dependencies": { - "@octokit/auth-oauth-app": "^5.0.0", - "@octokit/auth-oauth-user": "^2.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.0.3.tgz", + "integrity": "sha512-9N7IlBAKEJR3tJgPSubCxIDYGXSdc+2xbkjYpk9nCyqREnH8qEMoMhiEB1WgoA9yTFp91El92XNXAi+AjuKnfw==", + "dependencies": { + "@octokit/auth-oauth-app": "^7.0.0", + "@octokit/auth-oauth-user": "^4.0.0", + "@octokit/request": "^8.0.2", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", "deprecation": "^2.3.1", - "lru-cache": "^9.0.0", - "universal-github-app-jwt": "^1.1.1", + "lru-cache": "^10.0.0", + "universal-github-app-jwt": "^1.1.2", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/auth-app/node_modules/lru-cache": { - "version": "9.1.1", - "license": "ISC", - "engines": { - "node": "14 || >=16.14" + "node": ">= 18" } }, "node_modules/@octokit/auth-oauth-app": { - "version": "5.0.5", - "license": "MIT", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz", + "integrity": "sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg==", "dependencies": { - "@octokit/auth-oauth-device": "^4.0.0", - "@octokit/auth-oauth-user": "^2.0.0", - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", + "@octokit/auth-oauth-device": "^6.0.0", + "@octokit/auth-oauth-user": "^4.0.0", + "@octokit/request": "^8.0.2", + "@octokit/types": "^12.0.0", "@types/btoa-lite": "^1.0.0", "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/auth-oauth-device": { - "version": "4.0.4", - "license": "MIT", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.0.1.tgz", + "integrity": "sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw==", "dependencies": { - "@octokit/oauth-methods": "^2.0.0", - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", + "@octokit/oauth-methods": "^4.0.0", + "@octokit/request": "^8.0.0", + "@octokit/types": "^12.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/auth-oauth-user": { - "version": "2.1.1", - "license": "MIT", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.0.1.tgz", + "integrity": "sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw==", "dependencies": { - "@octokit/auth-oauth-device": "^4.0.0", - "@octokit/oauth-methods": "^2.0.0", - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", + "@octokit/auth-oauth-device": "^6.0.0", + "@octokit/oauth-methods": "^4.0.0", + "@octokit/request": "^8.0.2", + "@octokit/types": "^12.0.0", "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/auth-token": { - "version": "3.0.3", - "license": "MIT", - "dependencies": { - "@octokit/types": "^9.0.0" - }, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/core": { - "version": "4.2.1", - "license": "MIT", - "dependencies": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.2.tgz", + "integrity": "sha512-cZUy1gUvd4vttMic7C0lwPed8IYXWYp8kHIMatyhY8t8n3Cpw2ILczkV5pGMPqef7v0bLo0pOHrEHarsau2Ydg==", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.0.0", + "@octokit/request": "^8.0.2", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/endpoint": { - "version": "7.0.5", - "license": "MIT", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", + "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", "dependencies": { - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", + "@octokit/types": "^12.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/graphql": { - "version": "5.0.5", - "license": "MIT", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", + "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", "dependencies": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", + "@octokit/request": "^8.0.1", + "@octokit/types": "^12.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/oauth-authorization-url": { - "version": "5.0.0", - "license": "MIT", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", + "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==", "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/oauth-methods": { - "version": "2.0.5", - "license": "MIT", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-4.0.1.tgz", + "integrity": "sha512-1NdTGCoBHyD6J0n2WGXg9+yDLZrRNZ0moTEex/LSPr49m530WNKcCfXDghofYptr3st3eTii+EHoG5k/o+vbtw==", "dependencies": { - "@octokit/oauth-authorization-url": "^5.0.0", - "@octokit/request": "^6.2.3", - "@octokit/request-error": "^3.0.3", - "@octokit/types": "^9.0.0", + "@octokit/oauth-authorization-url": "^6.0.2", + "@octokit/request": "^8.0.2", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", "btoa-lite": "^1.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/openapi-types": { - "version": "17.2.0", - "license": "MIT" + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz", + "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw==" }, "node_modules/@octokit/plugin-paginate-graphql": { - "version": "2.0.1", - "license": "MIT", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-4.0.0.tgz", + "integrity": "sha512-7HcYW5tP7/Z6AETAPU14gp5H5KmCPT3hmJrS/5tO7HIgbwenYmgw4OY9Ma54FDySuxMwD+wsJlxtuGWwuZuItA==", + "engines": { + "node": ">= 18" + }, "peerDependencies": { - "@octokit/core": ">=4" + "@octokit/core": ">=5" } }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "6.1.2", - "license": "MIT", + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz", + "integrity": "sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg==", "dependencies": { - "@octokit/tsconfig": "^1.0.2", - "@octokit/types": "^9.2.3" + "@octokit/types": "^12.4.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" }, "peerDependencies": { - "@octokit/core": ">=4" + "@octokit/core": ">=5" } }, "node_modules/@octokit/plugin-request-log": { - "version": "1.0.4", - "license": "MIT", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", + "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", + "engines": { + "node": ">= 18" + }, "peerDependencies": { - "@octokit/core": ">=3" + "@octokit/core": ">=5" } }, "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "7.1.2", - "license": "MIT", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.2.0.tgz", + "integrity": "sha512-ePbgBMYtGoRNXDyKGvr9cyHjQ163PbwD0y1MkDJCpkO2YH4OeXX40c4wYHKikHGZcpGPbcRLuy0unPUuafco8Q==", "dependencies": { - "@octokit/types": "^9.2.3", - "deprecation": "^2.3.1" + "@octokit/types": "^12.3.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" }, "peerDependencies": { - "@octokit/core": ">=3" + "@octokit/core": ">=5" } }, "node_modules/@octokit/request": { - "version": "6.2.5", - "license": "MIT", + "version": "8.1.6", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", + "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", "dependencies": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", + "@octokit/endpoint": "^9.0.0", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/request-error": { - "version": "3.0.3", - "license": "MIT", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", + "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", "dependencies": { - "@octokit/types": "^9.0.0", + "@octokit/types": "^12.0.0", "deprecation": "^2.0.0", "once": "^1.4.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/rest": { - "version": "19.0.11", - "license": "MIT", + "version": "20.0.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", + "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", "dependencies": { - "@octokit/core": "^4.2.1", - "@octokit/plugin-paginate-rest": "^6.1.2", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^7.1.2" + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, - "node_modules/@octokit/tsconfig": { - "version": "1.0.2", - "license": "MIT" - }, "node_modules/@octokit/types": { - "version": "9.2.3", - "license": "MIT", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.4.0.tgz", + "integrity": "sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ==", "dependencies": { - "@octokit/openapi-types": "^17.2.0" + "@octokit/openapi-types": "^19.1.0" } }, "node_modules/@opentelemetry/api": { - "version": "1.4.1", - "license": "Apache-2.0", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", + "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==", "engines": { "node": ">=8.0.0" } }, "node_modules/@opentelemetry/core": { - "version": "1.13.0", - "license": "Apache-2.0", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.20.0.tgz", + "integrity": "sha512-lSRvk5AIdD6CtgYJcJXh0wGibQ3S/8bC2qbqKs9wK8e0K1tsWV6YkGFOqVc+jIRlCbZoIBeZzDe5UI+vb94uvg==", "dependencies": { - "@opentelemetry/semantic-conventions": "1.13.0" + "@opentelemetry/semantic-conventions": "1.20.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.5.0" + "@opentelemetry/api": ">=1.0.0 <1.8.0" } }, "node_modules/@opentelemetry/instrumentation": { - "version": "0.35.1", - "license": "Apache-2.0", - "dependencies": { - "require-in-the-middle": "^5.0.3", - "semver": "^7.3.2", + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz", + "integrity": "sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==", + "dependencies": { + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.4.2", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.1", "shimmer": "^1.2.1" }, "engines": { @@ -2386,52 +2942,86 @@ } }, "node_modules/@opentelemetry/resources": { - "version": "1.13.0", - "license": "Apache-2.0", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.20.0.tgz", + "integrity": "sha512-nOpV0vGegSq+9ze2cEDvO3BMA5pGBhmhKZiAlj+xQZjiEjPmJtdHIuBLRvptu2ahcbFJw85gIB9BYHZOvZK1JQ==", "dependencies": { - "@opentelemetry/core": "1.13.0", - "@opentelemetry/semantic-conventions": "1.13.0" + "@opentelemetry/core": "1.20.0", + "@opentelemetry/semantic-conventions": "1.20.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.5.0" + "@opentelemetry/api": ">=1.0.0 <1.8.0" } }, "node_modules/@opentelemetry/sdk-trace-base": { - "version": "1.13.0", - "license": "Apache-2.0", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.20.0.tgz", + "integrity": "sha512-BAIZ0hUgnhdb3OBQjn1FKGz/Iwie4l+uOMKklP7FGh7PTqEAbbzDNMJKaZQh6KepF7Fq+CZDRKslD3yrYy2Tzw==", "dependencies": { - "@opentelemetry/core": "1.13.0", - "@opentelemetry/resources": "1.13.0", - "@opentelemetry/semantic-conventions": "1.13.0" + "@opentelemetry/core": "1.20.0", + "@opentelemetry/resources": "1.20.0", + "@opentelemetry/semantic-conventions": "1.20.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.5.0" + "@opentelemetry/api": ">=1.0.0 <1.8.0" } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.13.0", - "license": "Apache-2.0", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.20.0.tgz", + "integrity": "sha512-3zLJJCgTKYpbqFX8drl8hOCHtdchELC+kGqlVcV4mHW1DiElTtv1Nt9EKBptTd1IfL56QkuYnWJ3DeHd2Gtu/A==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, "engines": { "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@primer/octicons": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.8.0.tgz", + "integrity": "sha512-Imze/fyW41Io5fN+27T5EAeXJrgBjMbz6nzU+wYbRylXvIAjLPUvaJPVoStiFlgSU+TjTUJqg5A9rgMDzTyMCg==", + "dependencies": { + "object-assign": "^4.1.1" + } + }, "node_modules/@redis/bloom": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/client": { - "version": "1.5.9", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.9.tgz", - "integrity": "sha512-SffgN+P1zdWJWSXBvJeynvEnmnZrYmtKSRW00xl8pOPFOMJjxRR9u0frSxJpPR6Y4V+k54blJjGW7FgxbTI7bQ==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.13.tgz", + "integrity": "sha512-epkUM9D0Sdmt93/8Ozk43PNjLi36RZzG+d/T1Gdu5AI8jvghonTeLYV69WVWdilvFo+PYxbP0TZ0saMvr6nscQ==", "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -2442,23 +3032,25 @@ } }, "node_modules/@redis/graph": { - "version": "1.1.0", - "license": "MIT", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/json": { - "version": "1.0.4", - "license": "MIT", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", + "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/search": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", + "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -2473,55 +3065,76 @@ }, "node_modules/@sideway/address": { "version": "4.1.4", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@sideway/address/node_modules/@hapi/hoek": { "version": "9.3.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "node_modules/@sideway/formula": { "version": "3.0.1", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "dev": true, - "license": "MIT" + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", + "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/@sinonjs/commons": { - "version": "2.0.0", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^2.0.0" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@tootallnate/once": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "engines": { "node": ">= 10" } }, "node_modules/@ts-morph/common": { "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.12.3.tgz", + "integrity": "sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==", "dev": true, - "license": "MIT", "dependencies": { "fast-glob": "^3.2.7", "minimatch": "^3.0.4", @@ -2529,30 +3142,57 @@ "path-browserify": "^1.0.1" } }, + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true }, "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "dev": true, - "license": "MIT" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true }, "node_modules/@types/babel__core": { - "version": "7.20.0", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -2562,60 +3202,77 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.4", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.1", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, - "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.18.5", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { - "version": "1.19.2", - "license": "MIT", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/btoa-lite": { - "version": "1.0.0", - "license": "MIT" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.2.tgz", + "integrity": "sha512-ZYbcE2x7yrvNFJiU7xJGrpF/ihpkM7zKgw8bha3LNJSesvTtUNxbpzaT7WXBIryf6jovisrxTBvymxMeLLj1Mg==" }, "node_modules/@types/connect": { - "version": "3.4.35", - "license": "MIT", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/debug": { - "version": "4.1.7", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/ms": "*" } }, "node_modules/@types/express": { - "version": "4.17.17", - "license": "MIT", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -2624,8 +3281,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.34", - "license": "MIT", + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -2634,174 +3292,193 @@ } }, "node_modules/@types/express-session": { - "version": "1.17.7", + "version": "1.17.10", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.10.tgz", + "integrity": "sha512-U32bC/s0ejXijw5MAzyaV4tuZopCh/K7fPoUDyNbsRXHvPSeymygYD1RFL99YOLhF5PNOkzswvOTRaVHdL1zMw==", "dev": true, - "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/graceful-fs": { - "version": "4.1.6", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, "node_modules/@types/is-buffer": { - "version": "2.0.0", - "license": "MIT", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/is-buffer/-/is-buffer-2.0.2.tgz", + "integrity": "sha512-G6OXy83Va+xEo8XgqAJYOuvOMxeey9xM5XKkvwJNmN8rVdcB+r15HvHsG86hl86JvU0y1aa7Z2ERkNFYWw9ySg==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "dev": true, - "license": "MIT" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, - "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.1", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/jest": { - "version": "29.5.1", + "version": "29.5.11", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", + "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", "dev": true, - "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "dev": true, - "license": "MIT" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "node_modules/@types/jsonwebtoken": { - "version": "9.0.2", - "license": "MIT", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/lodash": { - "version": "4.14.194", - "dev": true, - "license": "MIT" + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true }, "node_modules/@types/luxon": { - "version": "3.3.0", - "dev": true, - "license": "MIT" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.0.tgz", + "integrity": "sha512-PEVoA4MOfSsFNaPrZjIUGUZujBDxnO/tj2A2N9KfzlR+pNgpBdDuk0TmRvSMAVUP5q4q8IkMEZ8UOp3MIr+QgA==", + "dev": true }, "node_modules/@types/memory-cache": { - "version": "0.2.2", - "dev": true, - "license": "MIT" + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@types/memory-cache/-/memory-cache-0.2.5.tgz", + "integrity": "sha512-OIKRDDZUFeKT/rsko7/CGnR5qE8xTU8ogzyaaSDSHGkKwlSB/E6RopSF5fReo89khCAcGIoqSi723tDqUe6gYw==", + "dev": true }, "node_modules/@types/mime": { - "version": "1.3.2", - "license": "MIT" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/morgan": { - "version": "1.9.4", + "version": "1.9.9", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.9.tgz", + "integrity": "sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/ms": { - "version": "0.7.31", - "dev": true, - "license": "MIT" + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true }, "node_modules/@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" - }, - "node_modules/@types/node-fetch": { - "version": "2.6.1", - "license": "MIT", + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", "dependencies": { - "@types/node": "*", - "form-data": "^3.0.0" + "undici-types": "~5.26.4" } }, - "node_modules/@types/node-fetch/node_modules/form-data": { - "version": "3.0.1", - "license": "MIT", + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" + "@types/node": "*", + "form-data": "^4.0.0" } }, "node_modules/@types/node-jose": { - "version": "1.1.10", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@types/node-jose/-/node-jose-1.1.13.tgz", + "integrity": "sha512-QjMd4yhwy1EvSToQn0YI3cD29YhyfxFwj7NecuymjLys2/P0FwxWnkgBlFxCai6Y3aBCe7rbwmqwJJawxlgcXw==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/oauth": { - "version": "0.9.1", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.4.tgz", + "integrity": "sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/object-path": { - "version": "0.11.1", - "dev": true, - "license": "MIT" + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@types/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==", + "dev": true }, "node_modules/@types/parse-json": { - "version": "4.0.0", - "dev": true, - "license": "MIT" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true }, "node_modules/@types/passport": { - "version": "1.0.12", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz", + "integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==", "dev": true, - "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/passport-azure-ad": { - "version": "4.3.1", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@types/passport-azure-ad/-/passport-azure-ad-4.3.5.tgz", + "integrity": "sha512-dzWBDye7VvzWgKQbxImEvT0x1b0Vi37AYZrjN/XitTkstHsegDT97Wha5Aknoh4vPpv68DdaxZ4defK8YIk7kA==", "dev": true, - "license": "MIT", "dependencies": { "@types/express": "*", "@types/passport": "*" } }, "node_modules/@types/passport-github": { - "version": "1.1.7", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@types/passport-github/-/passport-github-1.1.12.tgz", + "integrity": "sha512-VJpMEIH+cOoXB694QgcxuvWy2wPd1Oq3gqrg2Y9DMVBYs9TmH9L14qnqPDZsNMZKBDH+SvqRsGZj9SgHYeDgcA==", "dev": true, - "license": "MIT", "dependencies": { "@types/express": "*", "@types/passport": "*", @@ -2809,9 +3486,10 @@ } }, "node_modules/@types/passport-oauth2": { - "version": "1.4.11", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.15.tgz", + "integrity": "sha512-9cUTP/HStNSZmhxXGuRrBJfEWzIEJRub2eyJu3CvkA+8HAMc9W3aKdFhVq+Qz1hi42qn+GvSAnz3zwacDSYWpw==", "dev": true, - "license": "MIT", "dependencies": { "@types/express": "*", "@types/oauth": "*", @@ -2819,175 +3497,140 @@ } }, "node_modules/@types/pg": { - "version": "8.10.1", + "version": "8.10.9", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.9.tgz", + "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^4.0.1" } }, - "node_modules/@types/pg/node_modules/pg-types": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "pg-numeric": "1.0.2", - "postgres-array": "~3.0.1", - "postgres-bytea": "~3.0.0", - "postgres-date": "~2.0.1", - "postgres-interval": "^3.0.0", - "postgres-range": "^1.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@types/pg/node_modules/postgres-array": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/@types/pg/node_modules/postgres-bytea": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "obuf": "~1.1.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/pg/node_modules/postgres-date": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/@types/pg/node_modules/postgres-interval": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/@types/prettier": { - "version": "2.7.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/pug": { - "version": "2.0.6", - "dev": true, - "license": "MIT" + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", + "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", + "dev": true }, "node_modules/@types/qs": { - "version": "6.9.7", - "license": "MIT" + "version": "6.9.11", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "license": "MIT" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/recursive-readdir": { - "version": "2.2.1", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@types/recursive-readdir/-/recursive-readdir-2.2.4.tgz", + "integrity": "sha512-84REEGT3lcgopvpkmGApzmU5UEG0valme5rQS/KGiguTkJ70/Au8UYZTyrzoZnY9svuX9351+1uvrRPzWDD/uw==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/semver": { - "version": "7.5.0", - "dev": true, - "license": "MIT" + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true }, "node_modules/@types/send": { - "version": "0.17.1", - "license": "MIT", + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.13.10", - "license": "MIT", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dependencies": { - "@types/mime": "^1", + "@types/http-errors": "*", + "@types/mime": "*", "@types/node": "*" } }, + "node_modules/@types/shimmer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.0.5.tgz", + "integrity": "sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==" + }, "node_modules/@types/simple-oauth2": { - "version": "5.0.4", - "dev": true, - "license": "MIT" + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@types/simple-oauth2/-/simple-oauth2-5.0.7.tgz", + "integrity": "sha512-8JbWVJbiTSBQP/7eiyGKyXWAqp3dKQZpaA+pdW16FCi32ujkzRMG8JfjoAzdWt6W8U591ZNdHcPtP2D7ILTKuA==", + "dev": true }, "node_modules/@types/stack-utils": { - "version": "2.0.1", - "dev": true, - "license": "MIT" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true }, "node_modules/@types/tunnel": { "version": "0.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", + "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/validator": { - "version": "13.7.17", - "dev": true, - "license": "MIT" + "version": "13.11.8", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.8.tgz", + "integrity": "sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ==", + "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.24", + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, - "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "dev": true, - "license": "MIT" + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.7", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", + "integrity": "sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==", "dev": true, - "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/type-utils": "5.59.7", - "@typescript-eslint/utils": "5.59.7", + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/type-utils": "6.18.1", + "@typescript-eslint/utils": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -2996,24 +3639,26 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.7", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.1.tgz", + "integrity": "sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/typescript-estree": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -3022,15 +3667,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.7", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", + "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3038,24 +3684,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.7", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.1.tgz", + "integrity": "sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.7", - "@typescript-eslint/utils": "5.59.7", + "@typescript-eslint/typescript-estree": "6.18.1", + "@typescript-eslint/utils": "6.18.1", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -3064,11 +3711,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.7", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", + "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", "dev": true, - "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3076,20 +3724,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.7", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", + "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3102,49 +3752,57 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.7", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", + "integrity": "sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==", "dev": true, - "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/typescript-estree": "6.18.1", + "semver": "^7.5.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.7", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", + "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.18.1", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/accepts": { "version": "1.3.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -3154,9 +3812,9 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "dev": true, - "license": "MIT", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "bin": { "acorn": "bin/acorn" }, @@ -3164,25 +3822,36 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.2.0", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { "version": "6.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dependencies": { "debug": "4" }, @@ -3190,22 +3859,11 @@ "node": ">= 6.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3219,8 +3877,9 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -3233,8 +3892,9 @@ }, "node_modules/ansi-escapes/node_modules/type-fest": { "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -3243,22 +3903,24 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.1", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" + "node": ">=12" }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" @@ -3266,8 +3928,9 @@ }, "node_modules/anymatch": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3278,29 +3941,30 @@ }, "node_modules/app-root-path": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", "engines": { "node": ">= 6.0.0" } }, "node_modules/applicationinsights": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.7.0.tgz", - "integrity": "sha512-/vV5X6M4TlRA5NxNZAdCE0gukzfK24mb3z18D5Kl/CyIfSVIkafsIji3mK+Zi5q+7dn6H1CkFazlcnLf40anHw==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.9.2.tgz", + "integrity": "sha512-wlDiD7v0BQNM8oNzsf9C836R5ze25u+CuCEZsbA5xMIXYYBxkqkWE/mo9GFJM7rsKaiGqpxEwWmePHKD2Lwy2w==", "dependencies": { - "@azure/core-auth": "^1.4.0", + "@azure/core-auth": "^1.5.0", "@azure/core-rest-pipeline": "1.10.1", "@azure/core-util": "1.2.0", - "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.3", + "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.5", "@microsoft/applicationinsights-web-snippet": "^1.0.1", - "@opentelemetry/api": "^1.0.4", - "@opentelemetry/core": "^1.12.0", - "@opentelemetry/sdk-trace-base": "^1.12.0", - "@opentelemetry/semantic-conventions": "^1.12.0", + "@opentelemetry/api": "^1.7.0", + "@opentelemetry/core": "^1.19.0", + "@opentelemetry/sdk-trace-base": "^1.19.0", + "@opentelemetry/semantic-conventions": "^1.19.0", "cls-hooked": "^4.2.2", "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "1.1.0", - "diagnostic-channel-publishers": "1.0.6" + "diagnostic-channel": "1.1.1", + "diagnostic-channel-publishers": "1.0.8" }, "engines": { "node": ">=8.0.0" @@ -3314,51 +3978,88 @@ } } }, + "node_modules/applicationinsights/node_modules/@azure/core-rest-pipeline": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz", + "integrity": "sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "form-data": "^4.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/applicationinsights/node_modules/@azure/core-util": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.2.0.tgz", + "integrity": "sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/arg": { "version": "4.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "node_modules/argparse": { "version": "2.0.1", - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-flatten": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/array-timsort": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "dev": true }, "node_modules/array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/asap": { "version": "2.0.6", - "license": "MIT" + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "node_modules/assert-never": { "version": "1.2.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" }, - "node_modules/astral-regex": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, "node_modules/async-hook-jl": { "version": "1.7.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", + "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", "dependencies": { "stack-chain": "^1.3.7" }, @@ -3368,7 +4069,8 @@ }, "node_modules/async-listener": { "version": "0.6.10", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", "dependencies": { "semver": "^5.3.0", "shimmer": "^1.1.0" @@ -3378,15 +4080,17 @@ } }, "node_modules/async-listener/node_modules/semver": { - "version": "5.7.1", - "license": "ISC", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "bin": { "semver": "bin/semver" } }, "node_modules/async-prompt": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/async-prompt/-/async-prompt-1.0.1.tgz", + "integrity": "sha512-AdeC4NCuD0RxpbWm6pexY/AWMasHzMe+/zvdxdsAvpMmuz4in7N8OrKP7YzbRPYhUS+hibZNdUablgfE6Uj8UA==", "dependencies": { "keypress": "~0.2.1" }, @@ -3396,11 +4100,13 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/available-typed-arrays": { "version": "1.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "engines": { "node": ">= 0.4" }, @@ -3409,23 +4115,25 @@ } }, "node_modules/axios": { - "version": "1.4.0", - "license": "MIT", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", + "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "node_modules/babel-jest": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/transform": "^29.5.0", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -3437,10 +4145,60 @@ "@babel/core": "^7.8.0" } }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -3452,10 +4210,36 @@ "node": ">=8" } }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.5.0", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -3468,8 +4252,9 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -3489,11 +4274,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.5.0", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, - "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.5.0", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -3505,7 +4291,8 @@ }, "node_modules/babel-walk": { "version": "3.0.0-canary-5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", "dependencies": { "@babel/types": "^7.9.6" }, @@ -3515,10 +4302,13 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -3532,19 +4322,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/base64url": { "version": "3.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", "engines": { "node": ">=6.0.0" } }, "node_modules/basic-auth": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "dependencies": { "safe-buffer": "5.1.2" }, @@ -3553,12 +4344,14 @@ } }, "node_modules/before-after-hook": { - "version": "2.2.2", - "license": "Apache-2.0" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" }, "node_modules/body-parser": { "version": "1.20.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -3580,37 +4373,31 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "license": "MIT" - }, - "node_modules/body-parser/node_modules/on-finished": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "license": "MIT", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -3619,7 +4406,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "funding": [ { @@ -3629,14 +4418,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -3647,8 +4439,9 @@ }, "node_modules/bs-logger": { "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, - "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -3658,18 +4451,22 @@ }, "node_modules/bser": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } }, "node_modules/btoa-lite": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", + "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==" }, "node_modules/buffer": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -3684,7 +4481,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -3692,34 +4488,51 @@ }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "node_modules/buffer-from": { "version": "1.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, "node_modules/buffer-writer": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", "engines": { "node": ">=4" } }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/builtins": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, - "license": "MIT", "dependencies": { "semver": "^7.0.0" } }, "node_modules/bunyan": { "version": "1.8.15", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", + "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", "engines": [ "node >=0.10.0" ], - "license": "MIT", "bin": { "bunyan": "bin/bunyan" }, @@ -3732,14 +4545,16 @@ }, "node_modules/bytes": { "version": "3.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } }, "node_modules/cache-manager": { "version": "3.6.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-3.6.3.tgz", + "integrity": "sha512-dS4DnV6c6cQcVH5OxzIU1XZaACXwvVIiUPkFytnRmLOACuBGv3GQgRQ1RJGRRw4/9DF14ZK2RFlZu1TUgDniMg==", "dependencies": { "async": "3.2.3", "lodash.clonedeep": "^4.5.0", @@ -3748,14 +4563,28 @@ }, "node_modules/cache-manager/node_modules/async": { "version": "3.2.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + }, + "node_modules/cache-manager/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, "node_modules/call-bind": { - "version": "1.0.2", - "license": "MIT", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3763,22 +4592,26 @@ }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001486", + "version": "1.0.30001579", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", + "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==", "dev": true, "funding": [ { @@ -3793,41 +4626,56 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/chalk": { - "version": "4.1.2", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk-template": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", + "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", "dev": true, - "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "chalk": "^5.2.0" }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/chalk-template?sponsor=1" } }, "node_modules/char-regex": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/character-parser": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", "dependencies": { "is-regex": "^1.0.3" } }, "node_modules/ci-info": { - "version": "3.8.0", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -3835,28 +4683,20 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "dev": true, - "license": "MIT" - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" }, "node_modules/clear-module": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz", + "integrity": "sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^2.0.0", "resolve-from": "^5.0.0" @@ -3869,93 +4709,154 @@ } }, "node_modules/cli-cursor": { - "version": "3.1.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, - "license": "MIT", "dependencies": { - "restore-cursor": "^3.1.0" + "restore-cursor": "^4.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-truncate": { - "version": "3.1.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", "dev": true, - "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" + "string-width": "^7.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.0.1", + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "MIT", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "9.2.2", + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=8" + } }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "5.1.2", + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=12" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.0.1", + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">=12" + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/cliui": { - "version": "8.0.1", + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=12" + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/cls-hooked": { "version": "4.2.2", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", + "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", "dependencies": { "async-hook-jl": "^1.7.6", "emitter-listener": "^1.0.1", @@ -3966,23 +4867,26 @@ } }, "node_modules/cls-hooked/node_modules/semver": { - "version": "5.7.1", - "license": "ISC", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "bin": { "semver": "bin/semver" } }, "node_modules/cluster-key-slot": { "version": "1.1.2", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", "engines": { "node": ">=0.10.0" } }, "node_modules/co": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, - "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -3990,42 +4894,46 @@ }, "node_modules/code-block-writer": { "version": "11.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", + "integrity": "sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==", + "dev": true }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "dev": true, - "license": "MIT" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true }, "node_modules/color-contrast-checker": { "version": "2.1.0", - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/color-contrast-checker/-/color-contrast-checker-2.1.0.tgz", + "integrity": "sha512-6Y0aIEej3pwZTVlicIqVzhO6T4izDWouaIXnYoDdTuFFAMQ9nnN0dgHNP9J94jRnH6asjPq1/wzUKxwoNbWtRQ==" }, "node_modules/color-convert": { - "version": "2.0.1", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "color-name": "1.1.3" } }, "node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/colorette": { "version": "2.0.20", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4034,17 +4942,19 @@ } }, "node_modules/commander": { - "version": "10.0.1", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/comment-json": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz", + "integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==", "dev": true, - "license": "MIT", "dependencies": { "array-timsort": "^1.0.3", "core-util-is": "^1.0.3", @@ -4058,7 +4968,8 @@ }, "node_modules/compressible": { "version": "2.0.18", - "license": "MIT", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -4068,7 +4979,8 @@ }, "node_modules/compression": { "version": "1.7.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -4084,56 +4996,53 @@ }, "node_modules/compression/node_modules/bytes": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "engines": { "node": ">= 0.8" } }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/concat-map": { "version": "0.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/configstore": { - "version": "5.0.1", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/configstore/node_modules/write-file-atomic": { - "version": "3.0.3", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" } }, "node_modules/connect-redis": { "version": "7.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-7.1.0.tgz", + "integrity": "sha512-UaqO1EirWjON2ENsyau7N5lbkrdYBpS6mYlXSeff/OYXsd6EGZ+SXSmNPoljL2PSua8fgjAEaldSA73PMZQ9Eg==", "engines": { "node": ">=16" }, @@ -4143,7 +5052,8 @@ }, "node_modules/constantinople": { "version": "4.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", "dependencies": { "@babel/parser": "^7.6.0", "@babel/types": "^7.6.1" @@ -4151,7 +5061,8 @@ }, "node_modules/content-disposition": { "version": "0.5.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dependencies": { "safe-buffer": "5.2.1" }, @@ -4161,6 +5072,8 @@ }, "node_modules/content-disposition/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -4174,19 +5087,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/content-type": { "version": "1.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { "node": ">= 0.6" } }, "node_modules/continuation-local-storage": { "version": "3.2.1", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", "dependencies": { "async-listener": "^0.6.0", "emitter-listener": "^1.1.1" @@ -4194,28 +5108,33 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true }, "node_modules/cookie": { "version": "0.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "license": "MIT" + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-util-is": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true }, "node_modules/cors": { "version": "2.8.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -4225,180 +5144,319 @@ } }, "node_modules/cosmiconfig": { - "version": "8.0.0", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, - "license": "MIT", "dependencies": { + "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", "parse-json": "^5.0.0", - "path-type": "^4.0.0" + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "engines": { - "node": ">=14" + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, + "node_modules/create-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/create-require": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "license": "MIT" + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } }, "node_modules/crypto-random-string": { - "version": "2.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "dev": true, - "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cspell": { - "version": "6.31.1", + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/cspell-pipe": "6.31.1", - "@cspell/dynamic-import": "6.31.1", - "chalk": "^4.1.2", - "commander": "^10.0.0", - "cspell-gitignore": "6.31.1", - "cspell-glob": "6.31.1", - "cspell-io": "6.31.1", - "cspell-lib": "6.31.1", - "fast-glob": "^3.2.12", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cspell": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.3.2.tgz", + "integrity": "sha512-V8Ub3RO/a5lwSsltW/ib3Z3G/sczKtSpBBN1JChzbSCfEgaY2mJY8JW0BpkSV+Ug6uJitpXNOOaxa3Xr489i7g==", + "dev": true, + "dependencies": { + "@cspell/cspell-json-reporter": "8.3.2", + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-types": "8.3.2", + "@cspell/dynamic-import": "8.3.2", + "chalk": "^5.3.0", + "chalk-template": "^1.1.0", + "commander": "^11.1.0", + "cspell-gitignore": "8.3.2", + "cspell-glob": "8.3.2", + "cspell-io": "8.3.2", + "cspell-lib": "8.3.2", + "fast-glob": "^3.3.2", "fast-json-stable-stringify": "^2.1.0", - "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", - "imurmurhash": "^0.1.4", - "semver": "^7.3.8", - "strip-ansi": "^6.0.1", - "vscode-uri": "^3.0.7" + "file-entry-cache": "^8.0.0", + "get-stdin": "^9.0.0", + "semver": "^7.5.4", + "strip-ansi": "^7.1.0", + "vscode-uri": "^3.0.8" }, "bin": { - "cspell": "bin.js", + "cspell": "bin.mjs", "cspell-esm": "bin.mjs" }, "engines": { - "node": ">=14" + "node": ">=18" }, "funding": { "url": "https://github.com/streetsidesoftware/cspell?sponsor=1" } }, + "node_modules/cspell-config-lib": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.3.2.tgz", + "integrity": "sha512-Wc98XhBNLwDxnxCzMtgRJALI9a69cu3C5Gf1rGjNTKSFo9JYiQmju0Ur3z25Pkx9Sa86f+2IjvNCf33rUDSoBQ==", + "dev": true, + "dependencies": { + "@cspell/cspell-types": "8.3.2", + "comment-json": "^4.2.3", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/cspell-dictionary": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.3.2.tgz", + "integrity": "sha512-xyK95hO2BMPFxIo8zBwGml8035qOxSBdga1BMhwW/p2wDrQP8S4Cdm/54//tCDmKn6uRkFQvyOfWGaX2l8WMEg==", "dev": true, - "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "6.31.1", - "@cspell/cspell-types": "6.31.1", - "cspell-trie-lib": "6.31.1", - "fast-equals": "^4.0.3", - "gensequence": "^5.0.2" + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-types": "8.3.2", + "cspell-trie-lib": "8.3.2", + "fast-equals": "^5.0.1", + "gensequence": "^6.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/cspell-gitignore": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.3.2.tgz", + "integrity": "sha512-3Qc9P5BVvl/cg//s2s+zIMGKcoH5v7oOtRgwn4UQry8yiyo19h0tiTKkSR574FMhF5NtcShTnwIwPSIXVBPFHA==", "dev": true, - "license": "MIT", "dependencies": { - "cspell-glob": "6.31.1", - "find-up": "^5.0.0" + "cspell-glob": "8.3.2", + "find-up-simple": "^1.0.0" }, "bin": { "cspell-gitignore": "bin.mjs" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/cspell-glob": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.3.2.tgz", + "integrity": "sha512-KtIFxE+3l5dGEofND4/CdZffXP8XN1+XGQKxJ96lIzWsc01mkotfhxTkla6mgvfH039t7BsY/SWv0460KyGslQ==", "dev": true, - "license": "MIT", "dependencies": { "micromatch": "^4.0.5" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/cspell-grammar": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.3.2.tgz", + "integrity": "sha512-tYCkOmRzJe1a6/R+8QGSwG7TwTgznLPqsHtepKzLmnS4YX54VXjKRI9zMARxXDzUVfyCSVdW5MyiY/0WTNoy+A==", "dev": true, - "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "6.31.1", - "@cspell/cspell-types": "6.31.1" + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-types": "8.3.2" }, "bin": { "cspell-grammar": "bin.mjs" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/cspell-io": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.3.2.tgz", + "integrity": "sha512-WYpKsyBCQP0SY4gXnhW5fPuxcYchKYKG1PIXVV3ezFU4muSgW6GuLNbGuSfwv/8YNXRgFSN0e3hYH0rdBK2Aow==", "dev": true, - "license": "MIT", "dependencies": { - "@cspell/cspell-service-bus": "6.31.1", - "node-fetch": "^2.6.9" + "@cspell/cspell-service-bus": "8.3.2" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/cspell-lib": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.3.2.tgz", + "integrity": "sha512-wTvdaev/TyGB/ln6CVD1QbVs2D7/+QiajQ67S7yj1suLHM6YcNQQb/5sPAM8VPtj0E7PgwgPXf3bq18OtPvnFg==", "dev": true, - "license": "MIT", "dependencies": { - "@cspell/cspell-bundled-dicts": "6.31.1", - "@cspell/cspell-pipe": "6.31.1", - "@cspell/cspell-types": "6.31.1", - "@cspell/strong-weak-map": "6.31.1", + "@cspell/cspell-bundled-dicts": "8.3.2", + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-resolver": "8.3.2", + "@cspell/cspell-types": "8.3.2", + "@cspell/dynamic-import": "8.3.2", + "@cspell/strong-weak-map": "8.3.2", "clear-module": "^4.1.2", "comment-json": "^4.2.3", - "configstore": "^5.0.1", - "cosmiconfig": "8.0.0", - "cspell-dictionary": "6.31.1", - "cspell-glob": "6.31.1", - "cspell-grammar": "6.31.1", - "cspell-io": "6.31.1", - "cspell-trie-lib": "6.31.1", - "fast-equals": "^4.0.3", - "find-up": "^5.0.0", - "gensequence": "^5.0.2", + "configstore": "^6.0.0", + "cspell-config-lib": "8.3.2", + "cspell-dictionary": "8.3.2", + "cspell-glob": "8.3.2", + "cspell-grammar": "8.3.2", + "cspell-io": "8.3.2", + "cspell-trie-lib": "8.3.2", + "fast-equals": "^5.0.1", + "gensequence": "^6.0.0", "import-fresh": "^3.3.0", "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0", - "vscode-languageserver-textdocument": "^1.0.8", - "vscode-uri": "^3.0.7" + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" }, "engines": { - "node": ">=14.6" + "node": ">=18" } }, "node_modules/cspell-trie-lib": { - "version": "6.31.1", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.3.2.tgz", + "integrity": "sha512-8qh2FqzkLMwzlTlvO/5Z+89fhi30rrfekocpight/BmqKbE2XFJQD7wS2ml24e7q/rdHJLXVpJbY/V5mByucCA==", "dev": true, - "license": "MIT", "dependencies": { - "@cspell/cspell-pipe": "6.31.1", - "@cspell/cspell-types": "6.31.1", - "gensequence": "^5.0.2" + "@cspell/cspell-pipe": "8.3.2", + "@cspell/cspell-types": "8.3.2", + "gensequence": "^6.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/debug": { "version": "4.3.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, @@ -4412,57 +5470,87 @@ } }, "node_modules/dedent": { - "version": "0.7.0", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", "dev": true, - "license": "MIT" + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deeks": { - "version": "2.6.0", - "license": "MIT", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/deeks/-/deeks-2.6.1.tgz", + "integrity": "sha512-PZrpz5xLo2JPZa3L+kqMMMdZU5pRwMysTM1xd6pLhNtgQw4Iq3wbF2QWaQTVh+HRq9Yg4rcjDIJ+scfGLxmsjQ==", "engines": { "node": ">= 12" } }, "node_modules/deep-is": { "version": "0.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/deepmerge": { "version": "4.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "engines": { "node": ">=0.10.0" } }, - "node_modules/define-lazy-prop": { + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-lazy-prop": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "engines": { "node": ">=8" } }, "node_modules/delayed-stream": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { "node": ">= 0.8" } }, "node_modules/deprecation": { "version": "2.3.1", - "license": "ISC" + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" }, "node_modules/destroy": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -4470,53 +5558,52 @@ }, "node_modules/detect-newline": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/diagnostic-channel": { - "version": "1.1.0", - "license": "MIT", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz", + "integrity": "sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==", "dependencies": { - "semver": "^5.3.0" + "semver": "^7.5.3" } }, "node_modules/diagnostic-channel-publishers": { - "version": "1.0.6", - "license": "MIT", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.8.tgz", + "integrity": "sha512-HmSm9hXxSPxA9BaLGY98QU1zsdjeCk113KjAYGPCen1ZP6mhVaTPzHd6UYv5r21DnWANi+f+NyPOHruGT9jpqQ==", "peerDependencies": { "diagnostic-channel": "*" } }, - "node_modules/diagnostic-channel/node_modules/semver": { - "version": "5.7.1", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/diff-sequences": { - "version": "29.4.3", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, - "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -4525,16 +5612,18 @@ } }, "node_modules/doc-path": { - "version": "3.0.6", - "license": "MIT", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-3.1.0.tgz", + "integrity": "sha512-Pv2hLQbUM8du5681lTWIYk0OtVBmNhMAeZNGeFhMMJBIR89Nw4XesBwee1Xtlfk83n71tn0Y6VsJOn4d3qIiTw==", "engines": { "node": ">=12" } }, "node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -4544,17 +5633,22 @@ }, "node_modules/doctypes": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" }, "node_modules/dot-prop": { - "version": "5.3.0", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", "dev": true, - "license": "MIT", "dependencies": { "is-obj": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/dotenv": { @@ -4570,8 +5664,9 @@ }, "node_modules/dtrace-provider": { "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", "hasInstallScript": true, - "license": "BSD-2-Clause", "optional": true, "dependencies": { "nan": "^2.14.0" @@ -4582,36 +5677,42 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "dependencies": { "safe-buffer": "^5.0.1" } }, "node_modules/ee-first": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.392", - "dev": true, - "license": "ISC" + "version": "1.4.639", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.639.tgz", + "integrity": "sha512-CkKf3ZUVZchr+zDpAlNLEEy2NJJ9T64ULWaDgy3THXXlPVPkLu3VOs9Bac44nebVtdwl2geSj6AxTtGDOxoXhg==", + "dev": true }, "node_modules/emitter-listener": { "version": "1.1.2", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", "dependencies": { "shimmer": "^1.2.0" } }, "node_modules/emittery": { "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -4620,44 +5721,63 @@ } }, "node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es6-promise": { "version": "4.2.8", - "license": "MIT" + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "node_modules/escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -4666,26 +5786,28 @@ } }, "node_modules/eslint": { - "version": "8.41.0", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.41.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4695,7 +5817,6 @@ "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", @@ -4705,9 +5826,8 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -4720,10 +5840,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-compat-utils": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", + "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, "node_modules/eslint-config-prettier": { - "version": "8.8.0", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -4732,12 +5865,14 @@ } }, "node_modules/eslint-plugin-es-x": { - "version": "6.2.1", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz", + "integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.5.0" + "@eslint-community/regexpp": "^4.6.0", + "eslint-compat-utils": "^0.1.2" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -4750,18 +5885,22 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.0.0", + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", - "eslint-plugin-es-x": "^6.1.0", - "ignore": "^5.1.1", - "is-core-module": "^2.12.0", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", + "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", + "is-core-module": "^2.12.1", "minimatch": "^3.1.2", "resolve": "^1.22.2", - "semver": "^7.5.0" + "semver": "^7.5.3" }, "engines": { "node": ">=16.0.0" @@ -4773,42 +5912,79 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", "dev": true, - "license": "MIT", "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" }, "engines": { - "node": ">=12.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, "eslint-config-prettier": { "optional": true } } }, "node_modules/eslint-scope": { - "version": "5.1.1", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.1", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4816,48 +5992,146 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/cross-spawn": { - "version": "7.0.3", + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=10" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "license": "BSD-2-Clause", + "dependencies": { + "flat-cache": "^3.0.4" + }, "engines": { - "node": ">=4.0" + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/eslint/node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/espree": { - "version": "9.5.2", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -4870,8 +6144,9 @@ }, "node_modules/esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -4882,8 +6157,9 @@ }, "node_modules/esquery": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -4891,18 +6167,11 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -4910,48 +6179,51 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, "node_modules/estraverse": { - "version": "4.3.0", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, "node_modules/events": { "version": "3.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "engines": { "node": ">=0.8.x" } }, "node_modules/execa": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -4970,36 +6242,26 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "7.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/exit": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5007,7 +6269,8 @@ }, "node_modules/express": { "version": "4.18.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -5046,12 +6309,14 @@ } }, "node_modules/express-async-handler": { - "version": "1.1.4", - "license": "MIT" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz", + "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" }, "node_modules/express-session": { "version": "1.17.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", "dependencies": { "cookie": "0.4.2", "cookie-signature": "1.0.6", @@ -5068,24 +6333,29 @@ }, "node_modules/express-session/node_modules/cookie": { "version": "0.4.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "engines": { "node": ">= 0.6" } }, "node_modules/express-session/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/express-session/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express-session/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -5099,16 +6369,17 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/express-sslify": { "version": "1.2.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/express-sslify/-/express-sslify-1.2.0.tgz", + "integrity": "sha512-OOf2B3MxAVjEXPPWl4Z19wA2oMH+RCULJVhejPwuhiDDClr9QczZz5ycABLSnnN+oY8JcLs32ghs9cxOj0vi+w==" }, "node_modules/express/node_modules/body-parser": { "version": "1.20.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -5130,28 +6401,21 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "license": "MIT" - }, - "node_modules/express/node_modules/on-finished": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express/node_modules/raw-body": { "version": "2.5.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -5164,6 +6428,8 @@ }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -5177,28 +6443,34 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-diff": { - "version": "1.2.0", - "dev": true, - "license": "Apache-2.0" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true }, "node_modules/fast-equals": { - "version": "4.0.3", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=6.0.0" + } }, "node_modules/fast-glob": { - "version": "3.2.12", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5212,8 +6484,9 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -5223,30 +6496,34 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "node_modules/fast-safe-stringify": { "version": "2.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "node_modules/fast-xml-parser": { - "version": "4.2.2", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.3.tgz", + "integrity": "sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg==", "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" } ], - "license": "MIT", "dependencies": { "strnum": "^1.0.5" }, @@ -5255,40 +6532,45 @@ } }, "node_modules/fastq": { - "version": "1.15.0", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fb-watchman": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } }, "node_modules/file-entry-cache": { - "version": "6.0.1", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, - "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-size": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/file-size/-/file-size-1.0.0.tgz", + "integrity": "sha512-tLIdonWTpABkU6Axg2yGChYdrOsy4V8xcm0IcyAP8fSsu6jiXLm5pgs083e4sq5fzNRZuAYolUbZyYmPvCKfwQ==" }, "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==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5298,7 +6580,8 @@ }, "node_modules/finalhandler": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -5314,29 +6597,22 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "license": "MIT" - }, - "node_modules/finalhandler/node_modules/on-finished": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -5348,32 +6624,48 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat-cache": { - "version": "3.0.4", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.0.tgz", + "integrity": "sha512-EryKbCE/wxpxKniQlyas6PY1I9vwtF3uCBweX+N8KYTCn3Y12RTGtQAJ/bd5pl7kxUAc8v/R3Ake/N17OZiFqA==", "dev": true, - "license": "MIT", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4", + "rimraf": "^5.0.5" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.5", - "dev": true, - "license": "ISC" + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.2", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -5385,14 +6677,44 @@ }, "node_modules/for-each": { "version": "0.3.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dependencies": { "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5404,26 +6726,31 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "version": "0.5.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } }, "node_modules/fs.realpath": { "version": "1.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { - "version": "2.3.2", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -5433,47 +6760,69 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "license": "MIT" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/generic-pool": { "version": "3.9.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", "engines": { "node": ">= 4" } }, "node_modules/gensequence": { - "version": "5.0.2", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-6.0.0.tgz", + "integrity": "sha512-8WwuywE9pokJRAcg2QFR/plk3cVPebSUqRPzpGQh3WQ0wIiHAw+HyOQj5IuHyUTQBHpBKFoB2JUMu9zT3vJ16Q==", "dev": true, - "license": "MIT", "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { + "node_modules/get-east-asian-width": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5481,18 +6830,20 @@ }, "node_modules/get-package-type": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/get-stdin": { - "version": "8.0.0", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5500,8 +6851,9 @@ }, "node_modules/get-stream": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -5509,18 +6861,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/github-username-regex": { "version": "1.0.0", - "license": "CC0-1.0" + "resolved": "https://registry.npmjs.org/github-username-regex/-/github-username-regex-1.0.0.tgz", + "integrity": "sha512-EqDVkN0/5MQyDPOSDLInVRRXdeISRfcN1UW/1FUqD2knV1HHw8DndMB3UPNn5lO51DvRnjzbLXwWqNNV86PLOw==" }, "node_modules/glob": { - "version": "7.2.0", - "license": "ISC", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -5533,8 +6899,9 @@ }, "node_modules/glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -5542,21 +6909,46 @@ "node": ">=10.13.0" } }, - "node_modules/global-dirs": { - "version": "0.1.1", + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", "dev": true, - "license": "MIT", "dependencies": { - "ini": "^1.3.4" + "ini": "4.1.1" }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globals": { - "version": "13.20.0", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -5569,8 +6961,9 @@ }, "node_modules/globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -5588,7 +6981,8 @@ }, "node_modules/gopd": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -5597,48 +6991,60 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "license": "ISC" - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "dev": true, - "license": "MIT" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/graphemer": { "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/has": { - "version": "1.0.3", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-own-prop": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, @@ -5648,7 +7054,8 @@ }, "node_modules/has-tostringtag": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dependencies": { "has-symbols": "^1.0.2" }, @@ -5659,9 +7066,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hsts": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", + "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", "dependencies": { "depd": "2.0.0" }, @@ -5671,12 +7090,14 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, "node_modules/http-errors": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -5690,7 +7111,8 @@ }, "node_modules/http-proxy-agent": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -5701,8 +7123,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "license": "MIT", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dependencies": { "agent-base": "6", "debug": "4" @@ -5713,16 +7136,18 @@ }, "node_modules/human-signals": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/husky": { "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true, - "license": "MIT", "bin": { "husky": "lib/bin.js" }, @@ -5735,7 +7160,8 @@ }, "node_modules/iconv-lite": { "version": "0.4.24", - "license": "MIT", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5745,6 +7171,8 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -5758,21 +7186,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/ignore": { - "version": "5.2.0", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -5786,8 +7215,9 @@ }, "node_modules/import-fresh/node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -5797,16 +7227,29 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/import-in-the-middle": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz", + "integrity": "sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-assertions": "^1.9.0", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/import-local": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, - "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -5822,9 +7265,10 @@ } }, "node_modules/import-meta-resolve": { - "version": "2.2.2", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", + "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5832,23 +7276,17 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/inflight": { "version": "1.0.6", - "license": "ISC", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5856,23 +7294,30 @@ }, "node_modules/inherits": { "version": "2.0.4", - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { - "version": "1.3.8", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", "dev": true, - "license": "ISC" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, "node_modules/ipaddr.js": { "version": "1.9.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "engines": { "node": ">= 0.10" } }, "node_modules/is-arguments": { "version": "1.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -5886,10 +7331,13 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-buffer": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "funding": [ { "type": "github", @@ -5904,14 +7352,29 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "engines": { "node": ">= 0.4" }, @@ -5920,10 +7383,11 @@ } }, "node_modules/is-core-module": { - "version": "2.12.0", - "license": "MIT", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5931,7 +7395,8 @@ }, "node_modules/is-docker": { "version": "2.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "bin": { "is-docker": "cli.js" }, @@ -5944,7 +7409,8 @@ }, "node_modules/is-expression": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", "dependencies": { "acorn": "^7.1.1", "object-assign": "^4.1.1" @@ -5952,7 +7418,8 @@ }, "node_modules/is-expression/node_modules/acorn": { "version": "7.4.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "bin": { "acorn": "bin/acorn" }, @@ -5962,31 +7429,38 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-generator-fn": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/is-generator-function": { "version": "1.0.10", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -5999,8 +7473,9 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -6010,42 +7485,40 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-obj": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-path-inside": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-promise": { "version": "2.2.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "node_modules/is-regex": { "version": "1.1.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6059,8 +7532,9 @@ }, "node_modules/is-stream": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -6069,14 +7543,11 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "license": "MIT", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -6087,12 +7558,14 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true }, "node_modules/is-wsl": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dependencies": { "is-docker": "^2.0.0" }, @@ -6102,57 +7575,54 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -6163,9 +7633,10 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.5", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -6174,15 +7645,34 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.5.0" + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" @@ -6200,11 +7690,13 @@ } }, "node_modules/jest-changed-files": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, - "license": "MIT", "dependencies": { "execa": "^5.0.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0" }, "engines": { @@ -6212,27 +7704,28 @@ } }, "node_modules/jest-circus": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" @@ -6241,22 +7734,71 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-cli": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", + "create-jest": "^29.7.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "yargs": "^17.3.1" }, "bin": { @@ -6274,31 +7816,81 @@ } } }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-config": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -6318,24 +7910,124 @@ } } }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-diff": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-docblock": { - "version": "29.4.3", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, - "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -6344,58 +8036,111 @@ } }, "node_modules/jest-each": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-environment-node": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.4.3", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, - "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -6408,8 +8153,9 @@ }, "node_modules/jest-junit": { "version": "16.0.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", + "integrity": "sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "mkdirp": "^1.0.4", "strip-ansi": "^6.0.1", @@ -6420,44 +8166,117 @@ "node": ">=10.12.0" } }, - "node_modules/jest-leak-detector": { - "version": "29.5.0", + "node_modules/jest-junit/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-matcher-utils": { - "version": "29.5.0", + "node_modules/jest-junit/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-message-util": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -6465,14 +8284,64 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-mock": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.5.0" + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6480,8 +8349,9 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" }, @@ -6495,24 +8365,26 @@ } }, "node_modules/jest-regex-util": { - "version": "29.4.3", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, - "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -6522,915 +8394,955 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, - "license": "MIT", "dependencies": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runner": { - "version": "29.5.0", + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runtime": { - "version": "29.5.0", + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-snapshot": { - "version": "29.5.0", + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" + "color-name": "~1.1.4" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=7.0.0" } }, - "node_modules/jest-util": { - "version": "29.5.0", + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "ci-info": "^3.2.0", + "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate": { - "version": "29.5.0", + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "leven": "^3.1.0", - "pretty-format": "^29.5.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-watcher": { - "version": "29.5.0", + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.5.0", - "string-length": "^4.0.1" + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-worker": { - "version": "29.5.0", + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/joi": { - "version": "17.9.2", - "license": "BSD-3-Clause", + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/joi/node_modules/@hapi/hoek": { - "version": "9.3.0", - "license": "BSD-3-Clause" - }, - "node_modules/jose": { - "version": "4.14.4", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/js-stringify": { - "version": "1.0.2", - "license": "MIT" + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/js-tokens": { - "version": "4.0.0", + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "license": "MIT", "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbi": { - "version": "3.2.5", - "license": "Apache-2.0" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { - "node": ">=4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/json-2-csv": { - "version": "3.18.0", - "license": "MIT", + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "deeks": "2.6.0", - "doc-path": "3.0.6" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 12" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/json5": { - "version": "2.2.3", + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jsonc": { - "version": "2.0.0", - "license": "MIT", + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "fast-safe-stringify": "^2.0.6", - "graceful-fs": "^4.1.15", - "mkdirp": "^0.5.1", - "parse-json": "^4.0.0", - "strip-bom": "^4.0.0", - "strip-json-comments": "^3.0.1" + "color-convert": "^2.0.1" }, "engines": { "node": ">=8" - } - }, - "node_modules/jsonc/node_modules/mkdirp": { - "version": "0.5.6", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" }, - "bin": { - "mkdirp": "bin/cmd.js" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jsonc/node_modules/parse-json": { - "version": "4.0.0", - "license": "MIT", + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jsonwebtoken": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", - "integrity": "sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==", + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "jws": "^3.2.2", - "lodash": "^4.17.21", - "ms": "^2.1.1", - "semver": "^7.3.8" + "color-name": "~1.1.4" }, "engines": { - "node": ">=12", - "npm": ">=6" + "node": ">=7.0.0" } }, - "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.1", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.2", - "license": "MIT", + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jssha": { - "version": "3.3.0", - "license": "BSD-3-Clause", + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, "engines": { - "node": "*" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jstransformer": { - "version": "1.0.0", - "license": "MIT", + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jwa": { - "version": "2.0.0", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jwks-rsa": { - "version": "3.0.1", - "license": "MIT", + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { - "@types/express": "^4.17.14", - "@types/jsonwebtoken": "^9.0.0", - "debug": "^4.3.4", - "jose": "^4.10.4", - "limiter": "^1.1.5", - "lru-memoizer": "^2.1.4" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=14" - } - }, - "node_modules/jws": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/keypress": { - "version": "0.2.1", - "license": "MIT" - }, - "node_modules/kleur": { - "version": "3.0.3", + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">=6" + "node": ">=7.0.0" } }, - "node_modules/language-map": { - "version": "1.5.0", - "license": "MIT" + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/leven": { - "version": "3.1.0", + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, - "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/levn": { - "version": "0.4.1", + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/lilconfig": { - "version": "2.1.0", + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/limiter": { - "version": "1.1.5" - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, - "node_modules/linkify-it": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/lint-staged": { - "version": "13.2.2", + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { - "chalk": "5.2.0", - "cli-truncate": "^3.1.0", - "commander": "^10.0.0", - "debug": "^4.3.4", - "execa": "^7.0.0", - "lilconfig": "2.1.0", - "listr2": "^5.0.7", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-inspect": "^1.12.3", - "pidtree": "^0.6.0", - "string-argv": "^0.3.1", - "yaml": "^2.2.2" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" + "color-name": "~1.1.4" }, "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" + "node": ">=7.0.0" } }, - "node_modules/lint-staged/node_modules/chalk": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/lint-staged/node_modules/cross-spawn": { - "version": "7.0.3", + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, - "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/lint-staged/node_modules/execa": { - "version": "7.1.1", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + "node": ">=10" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/lint-staged/node_modules/human-signals": { - "version": "4.3.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=14.18.0" + "node_modules/joi": { + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.0.tgz", + "integrity": "sha512-HSLsmSmXz+PV9PYoi3p7cgIbj06WnEBNT28n+bbBNcPZXZFqCzzvGqpTBPujx/Z0nh1+KNQPDrNgdmQ8dq0qYw==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.4", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" } }, - "node_modules/lint-staged/node_modules/is-stream": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, + "node_modules/joi/node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/jose": { + "version": "4.15.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", + "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/panva" } }, - "node_modules/lint-staged/node_modules/mimic-fn": { + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" + }, + "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, - "node_modules/lint-staged/node_modules/npm-run-path": { - "version": "5.1.0", - "dev": true, - "license": "MIT", + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "argparse": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/lint-staged/node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", + "node_modules/jsbi": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.2.5.tgz", + "integrity": "sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "bin": { + "jsesc": "bin/jsesc" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=4" } }, - "node_modules/lint-staged/node_modules/onetime": { - "version": "6.0.0", - "dev": true, - "license": "MIT", + "node_modules/json-2-csv": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-3.20.0.tgz", + "integrity": "sha512-IbqUB+yaycVNB/q2fiY5kyRjy5kRiEXqvNvGlxM5L0Bfi0RdvklVHc4t9MfeYF1GsZVpZWDBs9LdWmSjsQ8jvg==", "dependencies": { - "mimic-fn": "^4.0.0" + "deeks": "2.6.1", + "doc-path": "3.1.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 12" } }, - "node_modules/lint-staged/node_modules/strip-final-newline": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, - "node_modules/listr2": { - "version": "5.0.8", + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.8.0", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } + "node": ">=6" } }, - "node_modules/listr2/node_modules/cli-truncate": { - "version": "2.1.0", - "dev": true, - "license": "MIT", + "node_modules/jsonc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jsonc/-/jsonc-2.0.0.tgz", + "integrity": "sha512-B281bLCT2TRMQa+AQUQY5AGcqSOXBOKaYGP4wDzoA/+QswUfN8sODektbPEs9Baq7LGKun5jQbNFpzwGuVYKhw==", "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" + "fast-safe-stringify": "^2.0.6", + "graceful-fs": "^4.1.15", + "mkdirp": "^0.5.1", + "parse-json": "^4.0.0", + "strip-bom": "^4.0.0", + "strip-json-comments": "^3.0.1" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/node_modules/slice-ansi": { - "version": "3.0.0", - "dev": true, - "license": "MIT", + "node_modules/jsonc/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "minimist": "^1.2.6" }, - "engines": { - "node": ">=8" + "bin": { + "mkdirp": "bin/cmd.js" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "dev": true, - "license": "MIT", + "node_modules/jsonc/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dependencies": { - "p-locate": "^5.0.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/lodash": { - "version": "4.17.21", - "license": "MIT" - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "dev": true, - "license": "MIT" - }, - "node_modules/log-update": { - "version": "4.0.0", - "dev": true, - "license": "MIT", + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12", + "npm": ">=6" } }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "dev": true, - "license": "MIT", + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" } }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "dev": true, - "license": "MIT", + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jssha": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.1.tgz", + "integrity": "sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==", "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/long": { - "version": "5.2.0", - "license": "Apache-2.0" + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", "dependencies": { - "yallist": "^4.0.0" + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "dependencies": { + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", + "debug": "^4.3.4", + "jose": "^4.14.6", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=14" } }, - "node_modules/lru-memoizer": { - "version": "2.1.4", - "license": "MIT", + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", "dependencies": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "~4.0.0" + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" } }, - "node_modules/lru-memoizer/node_modules/lru-cache": { - "version": "4.0.2", - "license": "ISC", + "node_modules/keypress": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", + "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, "dependencies": { - "pseudomap": "^1.0.1", - "yallist": "^2.0.0" + "json-buffer": "3.0.1" } }, - "node_modules/lru-memoizer/node_modules/yallist": { - "version": "2.1.2", - "license": "ISC" - }, - "node_modules/luxon": { - "version": "3.3.0", - "license": "MIT", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/make-dir": { + "node_modules/language-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/language-map/-/language-map-1.5.0.tgz", + "integrity": "sha512-n7gFZpe+DwEAX9cXVTw43i3wiudWDDtSn28RmdnS/HCPr284dQI/SztsamWanRr75oSlKSaGbV2nmWCTzGCoVg==" + }, + "node_modules/leven": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", + "node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=14" } }, - "node_modules/make-error": { - "version": "1.3.6", - "dev": true, - "license": "ISC" + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, - "node_modules/makeerror": { - "version": "1.0.12", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "tmpl": "1.0.5" + "uc.micro": "^2.0.0" } }, - "node_modules/markdown-it": { - "version": "13.0.1", + "node_modules/lint-staged": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", + "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", "dev": true, - "license": "MIT", "dependencies": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "3.0.0", + "listr2": "8.0.0", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.4" }, "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-it/node_modules/entities": { - "version": "3.0.1", - "dev": true, - "license": "BSD-2-Clause", + "lint-staged": "bin/lint-staged.js" + }, "engines": { - "node": ">=0.12" + "node": ">=18.12.0" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://opencollective.com/lint-staged" } }, - "node_modules/markdownlint": { - "version": "0.28.2", + "node_modules/lint-staged/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, - "license": "MIT", "dependencies": { - "markdown-it": "13.0.1", - "markdownlint-micromark": "0.1.2" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=14.18.0" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/markdownlint-cli2": { - "version": "0.7.1", + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "license": "MIT", - "dependencies": { - "globby": "13.1.4", - "markdownlint": "0.28.2", - "markdownlint-cli2-formatter-default": "0.0.4", - "micromatch": "4.0.5", - "strip-json-comments": "5.0.0", - "yaml": "2.2.2" - }, - "bin": { - "markdownlint-cli2": "markdownlint-cli2.js", - "markdownlint-cli2-config": "markdownlint-cli2-config.js", - "markdownlint-cli2-fix": "markdownlint-cli2-fix.js" - }, "engines": { - "node": ">=14.18.0" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdownlint-cli2-formatter-default": { - "version": "0.0.4", + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "license": "MIT", - "peerDependencies": { - "markdownlint-cli2": ">=0.0.4" + "engines": { + "node": ">=16.17.0" } }, - "node_modules/markdownlint-cli2/node_modules/globby": { - "version": "13.1.4", + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "license": "MIT", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -7438,10 +9350,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdownlint-cli2/node_modules/slash": { + "node_modules/lint-staged/node_modules/mimic-fn": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -7449,7483 +9362,805 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdownlint-cli2/node_modules/strip-json-comments": { - "version": "5.0.0", + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, - "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, "engines": { - "node": ">=14.16" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdownlint-micromark": { - "version": "0.1.2", + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, - "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { - "node": ">=14.18.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mdurl": { - "version": "1.0.1", + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "license": "MIT" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/memory-cache": { - "version": "0.2.0", - "license": "BSD-2-Clause" - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "license": "MIT" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", + "node_modules/lint-staged/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/methods": { - "version": "1.1.2", - "license": "MIT", + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/micromatch": { - "version": "4.0.5", + "node_modules/listr2": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", + "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", "dev": true, - "license": "MIT", "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=8.6" + "node": ">=18.0.0" } }, - "node_modules/mime": { - "version": "1.6.0", - "license": "MIT", - "bin": { - "mime": "cli.js" + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "license": "MIT", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "license": "MIT", + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, "dependencies": { - "mime-db": "1.52.0" + "type-fest": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "license": "ISC", + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "get-east-asian-width": "^1.0.0" }, "engines": { - "node": "*" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimist": { - "version": "1.2.6", - "license": "MIT" - }, - "node_modules/mkdirp": { - "version": "1.0.4", + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/module-details-from-path": { - "version": "1.0.3", - "license": "MIT" - }, - "node_modules/moment": { - "version": "2.29.4", - "license": "MIT", + "node_modules/log-update/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, "engines": { - "node": "*" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/morgan": { - "version": "1.10.0", - "license": "MIT", - "dependencies": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "engines": { - "node": ">= 0.8.0" + "node": "14 || >=16.14" } }, - "node_modules/morgan/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", + "node_modules/lru-memoizer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", + "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", "dependencies": { - "ms": "2.0.0" + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" } }, - "node_modules/morgan/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", + "dependencies": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } }, - "node_modules/ms": { + "node_modules/lru-memoizer/node_modules/yallist": { "version": "2.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" }, - "node_modules/mv": { - "version": "2.1.1", - "license": "MIT", - "optional": true, - "dependencies": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, + "node_modules/luxon": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", + "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", "engines": { - "node": ">=0.8.0" + "node": ">=12" } }, - "node_modules/mv/node_modules/glob": { - "version": "6.0.4", - "license": "ISC", - "optional": true, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "semver": "^7.5.3" }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mv/node_modules/mkdirp": { - "version": "0.5.6", - "license": "MIT", - "optional": true, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" + "tmpl": "1.0.5" } }, - "node_modules/mv/node_modules/rimraf": { - "version": "2.4.5", - "license": "ISC", - "optional": true, + "node_modules/markdown-it": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.0.0.tgz", + "integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==", + "dev": true, "dependencies": { - "glob": "^6.0.1" + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.0.0" }, "bin": { - "rimraf": "bin.js" + "markdown-it": "bin/markdown-it.mjs" } }, - "node_modules/nan": { - "version": "2.15.0", - "license": "MIT", - "optional": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", + "node_modules/markdownlint": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.33.0.tgz", + "integrity": "sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==", "dev": true, - "license": "MIT" - }, - "node_modules/ncp": { - "version": "2.0.0", - "license": "MIT", - "optional": true, - "bin": { - "ncp": "bin/ncp" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "license": "MIT", + "dependencies": { + "markdown-it": "14.0.0", + "markdownlint-micromark": "0.1.8" + }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" } }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.6.11", - "license": "MIT", + "node_modules/markdownlint-cli2": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.12.0.tgz", + "integrity": "sha512-5nddNaPY1WC7BE1mkF8fiEkRDW8XbODwqYBPL3eyvFh7tLk74no+P8JRbCjghF7ozahCW5pF0TZ3ZS30m9H1Eg==", + "dev": true, "dependencies": { - "whatwg-url": "^5.0.0" + "globby": "14.0.0", + "markdownlint": "0.33.0", + "markdownlint-cli2-formatter-default": "0.0.4", + "micromatch": "4.0.5", + "strip-json-comments": "5.0.1", + "yaml": "2.3.4" }, - "engines": { - "node": "4.x || >=6.0.0" + "bin": { + "markdownlint-cli2": "markdownlint-cli2.js" }, - "peerDependencies": { - "encoding": "^0.1.0" + "engines": { + "node": ">=18" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/DavidAnson" } }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "node_modules/markdownlint-cli2-formatter-default": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.4.tgz", + "integrity": "sha512-xm2rM0E+sWgjpPn1EesPXx5hIyrN2ddUnUwnbCsD/ONxYtw3PX6LydvdH6dciWAoFDpwzbHM1TO7uHfcMd6IYg==", + "dev": true, + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" } }, - "node_modules/node-forge": { - "version": "1.3.1", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/node-jose": { - "version": "2.2.0", - "license": "Apache-2.0", - "dependencies": { - "base64url": "^3.0.1", - "buffer": "^6.0.3", - "es6-promise": "^4.2.8", - "lodash": "^4.17.21", - "long": "^5.2.0", - "node-forge": "^1.2.1", - "pako": "^2.0.4", - "process": "^0.11.10", - "uuid": "^9.0.0" - } - }, - "node_modules/node-jose/node_modules/uuid": { - "version": "9.0.0", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/node-releases": { - "version": "2.0.10", - "dev": true, - "license": "MIT" - }, - "node_modules/nodemailer": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.4.tgz", - "integrity": "sha512-CXjQvrQZV4+6X5wP6ZIgdehJamI63MFoYFGGPtHudWym9qaEHDNdPzaj5bfMCvxG1vhAileSWW90q7nL0N36mA==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/oauth": { - "version": "0.9.15", - "license": "MIT" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-path": { - "version": "0.11.8", - "license": "MIT", - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/octicons": { - "version": "5.0.1", - "license": "(OFL-1.1 OR MIT)" - }, - "node_modules/on-finished": { - "version": "2.3.0", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.0", - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/packet-reader": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/pako": { - "version": "2.0.4", - "license": "(MIT AND Zlib)" - }, - "node_modules/parent-module": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", + "node_modules/markdownlint-cli2/node_modules/globby": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", + "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/passport": { - "version": "0.6.0", - "license": "MIT", "dependencies": { - "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" + "@sindresorhus/merge-streams": "^1.0.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">= 0.4.0" + "node": ">=18" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-azure-ad": { - "version": "4.3.5", - "license": "MIT", - "dependencies": { - "async": "^3.2.3", - "base64url": "^3.0.0", - "bunyan": "^1.8.14", - "cache-manager": "^3.6.1", - "https-proxy-agent": "^5.0.0", - "jws": "^3.1.3", - "lodash": "^4.11.2", - "node-jose": "^2.2.0", - "oauth": "0.9.15", - "passport": "^0.6.0", - "valid-url": "^1.0.6" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/passport-azure-ad/node_modules/async": { - "version": "3.2.4", - "license": "MIT" - }, - "node_modules/passport-azure-ad/node_modules/jwa": { - "version": "1.4.1", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/passport-azure-ad/node_modules/jws": { - "version": "3.2.2", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/passport-github": { - "version": "1.1.0", - "license": "MIT", - "dependencies": { - "passport-oauth2": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/passport-oauth2": { - "version": "1.6.1", - "license": "MIT", - "dependencies": { - "base64url": "3.x.x", - "oauth": "0.9.x", - "passport-strategy": "1.x.x", - "uid2": "0.0.x", - "utils-merge": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-strategy": { - "version": "1.0.0", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "license": "MIT" - }, - "node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pause": { - "version": "0.0.1" - }, - "node_modules/pg": { - "version": "8.11.0", - "license": "MIT", - "dependencies": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-connection-string": "^2.6.0", - "pg-pool": "^3.6.0", - "pg-protocol": "^1.6.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" - }, - "engines": { - "node": ">= 8.0.0" - }, - "optionalDependencies": { - "pg-cloudflare": "^1.1.0" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } - } - }, - "node_modules/pg-cloudflare": { - "version": "1.1.0", - "license": "MIT", - "optional": true - }, - "node_modules/pg-connection-string": { - "version": "2.6.0", - "license": "MIT" - }, - "node_modules/pg-escape": { - "version": "0.2.0", - "license": "MIT" - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "license": "ISC", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-numeric": { - "version": "1.0.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=4" - } - }, - "node_modules/pg-pool": { - "version": "3.6.0", - "license": "MIT", - "peerDependencies": { - "pg": ">=8.0" - } - }, - "node_modules/pg-protocol": { - "version": "1.6.0", - "license": "MIT" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pgpass": { - "version": "1.0.5", - "license": "MIT", - "dependencies": { - "split2": "^4.1.0" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pidtree": { - "version": "0.6.0", - "dev": true, - "license": "MIT", - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postgres-array": { - "version": "2.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-range": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "29.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/priorityqueuejs": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/process": { - "version": "0.11.10", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/promise": { - "version": "7.3.1", - "license": "MIT", - "dependencies": { - "asap": "~2.0.3" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "license": "ISC" - }, - "node_modules/pug": { - "version": "3.0.2", - "license": "MIT", - "dependencies": { - "pug-code-gen": "^3.0.2", - "pug-filters": "^4.0.0", - "pug-lexer": "^5.0.1", - "pug-linker": "^4.0.0", - "pug-load": "^3.0.0", - "pug-parser": "^6.0.0", - "pug-runtime": "^3.0.1", - "pug-strip-comments": "^2.0.0" - } - }, - "node_modules/pug-attrs": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "constantinople": "^4.0.1", - "js-stringify": "^1.0.2", - "pug-runtime": "^3.0.0" - } - }, - "node_modules/pug-code-gen": { - "version": "3.0.2", - "license": "MIT", - "dependencies": { - "constantinople": "^4.0.1", - "doctypes": "^1.1.0", - "js-stringify": "^1.0.2", - "pug-attrs": "^3.0.0", - "pug-error": "^2.0.0", - "pug-runtime": "^3.0.0", - "void-elements": "^3.1.0", - "with": "^7.0.0" - } - }, - "node_modules/pug-error": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/pug-filters": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "constantinople": "^4.0.1", - "jstransformer": "1.0.0", - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0", - "resolve": "^1.15.1" - } - }, - "node_modules/pug-lexer": { - "version": "5.0.1", - "license": "MIT", - "dependencies": { - "character-parser": "^2.2.0", - "is-expression": "^4.0.0", - "pug-error": "^2.0.0" - } - }, - "node_modules/pug-linker": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0" - } - }, - "node_modules/pug-load": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "object-assign": "^4.1.1", - "pug-walk": "^2.0.0" - } - }, - "node_modules/pug-parser": { - "version": "6.0.0", - "license": "MIT", - "dependencies": { - "pug-error": "^2.0.0", - "token-stream": "1.0.0" - } - }, - "node_modules/pug-runtime": { - "version": "3.0.1", - "license": "MIT" - }, - "node_modules/pug-strip-comments": { - "version": "2.0.0", - "license": "MIT", - "dependencies": { - "pug-error": "^2.0.0" - } - }, - "node_modules/pug-walk": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "6.0.2", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "node_modules/qs": { - "version": "6.11.0", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/random-bytes": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react-is": { - "version": "18.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/redis": { - "version": "4.6.8", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", - "integrity": "sha512-S7qNkPUYrsofQ0ztWlTHSaK0Qqfl1y+WMIxrzeAGNG+9iUZB4HGeBgkHxE6uJJ6iXrkvLd1RVJ2nvu6H1sAzfQ==", - "dependencies": { - "@redis/bloom": "1.2.0", - "@redis/client": "1.5.9", - "@redis/graph": "1.1.0", - "@redis/json": "1.0.4", - "@redis/search": "1.1.3", - "@redis/time-series": "1.0.5" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-in-the-middle": { - "version": "5.2.0", - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve": { - "version": "1.22.2", - "license": "MIT", - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-global": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^0.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.3.0", - "dev": true, - "license": "MIT" - }, - "node_modules/rhea": { - "version": "3.0.2", - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.3.3" - } - }, - "node_modules/rhea-promise": { - "version": "3.0.1", - "license": "Apache-2.0", - "dependencies": { - "debug": "^3.1.0", - "rhea": "^3.0.0", - "tslib": "^2.2.0" - } - }, - "node_modules/rhea-promise/node_modules/debug": { - "version": "3.2.7", - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.8.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "license": "MIT" - }, - "node_modules/safe-json-stringify": { - "version": "1.2.0", - "license": "MIT", - "optional": true - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.2.4", - "license": "ISC" - }, - "node_modules/secure-compare": { - "version": "3.0.1", - "license": "MIT" - }, - "node_modules/semaphore": { - "version": "1.1.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/semver": { - "version": "7.5.1", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.18.0", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "license": "MIT" - }, - "node_modules/send/node_modules/on-finished": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serve-favicon": { - "version": "2.5.0", - "license": "MIT", - "dependencies": { - "etag": "~1.8.1", - "fresh": "0.5.2", - "ms": "2.1.1", - "parseurl": "~1.3.2", - "safe-buffer": "5.1.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-favicon/node_modules/ms": { - "version": "2.1.1", - "license": "MIT" - }, - "node_modules/serve-favicon/node_modules/safe-buffer": { - "version": "5.1.1", - "license": "MIT" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "license": "MIT", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "license": "ISC" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shimmer": { - "version": "1.2.1", - "license": "BSD-2-Clause" - }, - "node_modules/side-channel": { - "version": "1.0.4", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "node_modules/simple-oauth2": { - "version": "5.0.0", - "license": "Apache-2.0", - "dependencies": { - "@hapi/hoek": "^10.0.1", - "@hapi/wreck": "^18.0.0", - "debug": "^4.3.4", - "joi": "^17.6.4" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/split2": { - "version": "4.1.0", - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-chain": { - "version": "1.3.7", - "license": "MIT" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stoppable": { - "version": "1.1.0", - "license": "MIT", - "engines": { - "node": ">=4", - "npm": ">=6" - } - }, - "node_modules/string-argv": { - "version": "0.3.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strnum": { - "version": "1.0.5", - "license": "MIT" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/throat": { - "version": "6.0.2", - "license": "MIT" - }, - "node_modules/through": { - "version": "2.3.8", - "dev": true, - "license": "MIT" - }, - "node_modules/tmp": { - "version": "0.2.1", - "license": "MIT", - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/tmp-promise": { - "version": "3.0.3", - "license": "MIT", - "dependencies": { - "tmp": "^0.2.0" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/token-stream": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/true-myth": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": "10.* || >= 12.*" - } - }, - "node_modules/ts-jest": { - "version": "29.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-morph": { - "version": "13.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@ts-morph/common": "~0.12.3", - "code-block-writer": "^11.0.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-prune": { - "version": "0.10.3", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^6.2.1", - "cosmiconfig": "^7.0.1", - "json5": "^2.1.3", - "lodash": "^4.17.21", - "true-myth": "^4.1.0", - "ts-morph": "^13.0.1" - }, - "bin": { - "ts-prune": "lib/index.js" - } - }, - "node_modules/ts-prune/node_modules/commander": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/ts-prune/node_modules/cosmiconfig": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "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/ts-prune/node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/tslib": { - "version": "2.3.1", - "license": "0BSD" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "dev": true, - "license": "0BSD" - }, - "node_modules/tunnel": { - "version": "0.0.6", - "license": "MIT", - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "5.0.4", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/uc.micro": { - "version": "1.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/uid-safe": { - "version": "2.1.5", - "license": "MIT", - "dependencies": { - "random-bytes": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/uid2": { - "version": "0.0.4", - "license": "MIT" - }, - "node_modules/unique-string": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universal-github-app-jwt": { - "version": "1.1.1", - "license": "MIT", - "dependencies": { - "@types/jsonwebtoken": "^9.0.0", - "jsonwebtoken": "^9.0.0" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "license": "ISC" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.11", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util": { - "version": "0.12.5", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/v8-to-istanbul": { - "version": "9.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/valid-url": { - "version": "1.0.9" - }, - "node_modules/validator": { - "version": "13.9.0", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/void-elements": { - "version": "3.1.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.8", - "dev": true, - "license": "MIT" - }, - "node_modules/vscode-uri": { - "version": "3.0.7", - "dev": true, - "license": "MIT" - }, - "node_modules/walk-back": { - "version": "5.1.0", - "license": "MIT", - "engines": { - "node": ">=12.17" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/with": { - "version": "7.0.2", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "assert-never": "^1.2.1", - "babel-walk": "3.0.0-canary-5" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/xml": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.2.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 14" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.1", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@azure/abort-controller": { - "version": "1.0.4", - "requires": { - "tslib": "^2.0.0" - } - }, - "@azure/core-amqp": { - "version": "3.3.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "buffer": "^6.0.0", - "events": "^3.0.0", - "jssha": "^3.1.0", - "process": "^0.11.10", - "rhea": "^3.0.0", - "rhea-promise": "^3.0.0", - "tslib": "^2.2.0", - "util": "^0.12.1" - }, - "dependencies": { - "@azure/core-util": { - "version": "1.3.2", - "requires": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - } - } - } - }, - "@azure/core-asynciterator-polyfill": { - "version": "1.0.2" - }, - "@azure/core-auth": { - "version": "1.4.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - } - }, - "@azure/core-client": { - "version": "1.5.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-asynciterator-polyfill": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.5.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - } - }, - "@azure/core-http-compat": { - "version": "1.3.0", - "requires": { - "@azure/abort-controller": "^1.0.4", - "@azure/core-client": "^1.3.0", - "@azure/core-rest-pipeline": "^1.3.0" - } - }, - "@azure/core-lro": { - "version": "2.2.4", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - } - }, - "@azure/core-paging": { - "version": "1.5.0", - "requires": { - "tslib": "^2.2.0" - } - }, - "@azure/core-rest-pipeline": { - "version": "1.10.1", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.4.0", - "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "form-data": "^4.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/core-tracing": { - "version": "1.0.0-preview.13", - "requires": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" - } - }, - "@azure/core-util": { - "version": "1.2.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - } - }, - "@azure/core-xml": { - "version": "1.3.3", - "requires": { - "fast-xml-parser": "^4.0.8", - "tslib": "^2.2.0" - } - }, - "@azure/cosmos": { - "version": "3.17.3", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.2.0", - "@azure/core-tracing": "^1.0.0", - "debug": "^4.1.1", - "fast-json-stable-stringify": "^2.1.0", - "jsbi": "^3.1.3", - "node-abort-controller": "^3.0.0", - "priorityqueuejs": "^1.0.0", - "semaphore": "^1.0.5", - "tslib": "^2.2.0", - "universal-user-agent": "^6.0.0", - "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/data-tables": { - "version": "13.2.2", - "requires": { - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.0.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-xml": "^1.0.0", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/identity": { - "version": "3.2.2", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.4.0", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^2.32.2", - "@azure/msal-common": "^9.0.2", - "@azure/msal-node": "^1.14.6", - "events": "^3.0.0", - "jws": "^4.0.0", - "open": "^8.0.0", - "stoppable": "^1.1.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/keyvault-secrets": { - "version": "4.7.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.5.0", - "@azure/core-http-compat": "^1.3.0", - "@azure/core-lro": "^2.2.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-rest-pipeline": "^1.8.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/logger": { - "version": "1.0.3", - "requires": { - "tslib": "^2.2.0" - } - }, - "@azure/msal-browser": { - "version": "2.37.0", - "requires": { - "@azure/msal-common": "13.0.0" - }, - "dependencies": { - "@azure/msal-common": { - "version": "13.0.0" - } - } - }, - "@azure/msal-common": { - "version": "9.1.1" - }, - "@azure/msal-node": { - "version": "1.17.2", - "requires": { - "@azure/msal-common": "13.0.0", - "jsonwebtoken": "^9.0.0", - "uuid": "^8.3.0" - }, - "dependencies": { - "@azure/msal-common": { - "version": "13.0.0" - } - } - }, - "@azure/opentelemetry-instrumentation-azure-sdk": { - "version": "1.0.0-beta.3", - "requires": { - "@azure/core-tracing": "^1.0.0", - "@azure/logger": "^1.0.0", - "@opentelemetry/api": "^1.4.0", - "@opentelemetry/core": "^1.9.0", - "@opentelemetry/instrumentation": "^0.35.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/service-bus": { - "version": "7.9.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-amqp": "^3.3.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.0.0", - "@azure/core-paging": "^1.4.0", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.1.1", - "@azure/core-xml": "^1.0.0", - "@azure/logger": "^1.0.0", - "@types/is-buffer": "^2.0.0", - "buffer": "^6.0.0", - "is-buffer": "^2.0.3", - "jssha": "^3.1.0", - "long": "^5.2.0", - "process": "^0.11.10", - "rhea-promise": "^3.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "requires": { - "tslib": "^2.2.0" - } - }, - "@azure/core-util": { - "version": "1.3.2", - "requires": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - } - } - } - }, - "@azure/storage-blob": { - "version": "12.14.0", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-http": "^3.0.0", - "@azure/core-lro": "^2.2.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "events": "^3.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-http": { - "version": "3.0.1", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" - } - }, - "xml2js": { - "version": "0.5.0", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - } - } - }, - "@azure/storage-queue": { - "version": "12.14.0", - "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.14.0.tgz", - "integrity": "sha512-1j6uxhzCcbEDVPOTNWIJ5CsLzOAU5U/bXgGZeT25fy6IghFTC1JlPGALez2CWJ9fBVj6AmSnsiBXL/77iXhSpg==", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-http": "^3.0.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-http": { - "version": "3.0.1", - "requires": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" - } - }, - "xml2js": { - "version": "0.5.0", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - } - } - }, - "@babel/code-frame": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.21.7", - "dev": true - }, - "@babel/core": { - "version": "7.21.8", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.9.0", - "dev": true - }, - "semver": { - "version": "6.3.0", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/types": "^7.21.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "semver": { - "version": "6.3.0", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.21.5", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.21.0", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/types": "^7.21.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-simple-access": "^7.21.5", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.21.5", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/types": "^7.21.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.21.5" - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1" - }, - "@babel/helper-validator-option": { - "version": "7.21.0", - "dev": true - }, - "@babel/helpers": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.21.8" - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/template": { - "version": "7.20.7", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - } - }, - "@babel/traverse": { - "version": "7.21.5", - "dev": true, - "requires": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.21.5", - "requires": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "dev": true - }, - "@cspell/cspell-bundled-dicts": { - "version": "6.31.1", - "dev": true, - "requires": { - "@cspell/dict-ada": "^4.0.1", - "@cspell/dict-aws": "^3.0.0", - "@cspell/dict-bash": "^4.1.1", - "@cspell/dict-companies": "^3.0.9", - "@cspell/dict-cpp": "^5.0.2", - "@cspell/dict-cryptocurrencies": "^3.0.1", - "@cspell/dict-csharp": "^4.0.2", - "@cspell/dict-css": "^4.0.5", - "@cspell/dict-dart": "^2.0.2", - "@cspell/dict-django": "^4.0.2", - "@cspell/dict-docker": "^1.1.6", - "@cspell/dict-dotnet": "^5.0.0", - "@cspell/dict-elixir": "^4.0.2", - "@cspell/dict-en_us": "^4.3.2", - "@cspell/dict-en-common-misspellings": "^1.0.2", - "@cspell/dict-en-gb": "1.1.33", - "@cspell/dict-filetypes": "^3.0.0", - "@cspell/dict-fonts": "^3.0.1", - "@cspell/dict-fullstack": "^3.1.5", - "@cspell/dict-gaming-terms": "^1.0.4", - "@cspell/dict-git": "^2.0.0", - "@cspell/dict-golang": "^6.0.1", - "@cspell/dict-haskell": "^4.0.1", - "@cspell/dict-html": "^4.0.3", - "@cspell/dict-html-symbol-entities": "^4.0.0", - "@cspell/dict-java": "^5.0.5", - "@cspell/dict-k8s": "^1.0.1", - "@cspell/dict-latex": "^4.0.0", - "@cspell/dict-lorem-ipsum": "^3.0.0", - "@cspell/dict-lua": "^4.0.1", - "@cspell/dict-node": "^4.0.2", - "@cspell/dict-npm": "^5.0.5", - "@cspell/dict-php": "^4.0.1", - "@cspell/dict-powershell": "^5.0.1", - "@cspell/dict-public-licenses": "^2.0.2", - "@cspell/dict-python": "^4.0.2", - "@cspell/dict-r": "^2.0.1", - "@cspell/dict-ruby": "^5.0.0", - "@cspell/dict-rust": "^4.0.1", - "@cspell/dict-scala": "^5.0.0", - "@cspell/dict-software-terms": "^3.1.6", - "@cspell/dict-sql": "^2.1.0", - "@cspell/dict-svelte": "^1.0.2", - "@cspell/dict-swift": "^2.0.1", - "@cspell/dict-typescript": "^3.1.1", - "@cspell/dict-vue": "^3.0.0" - } - }, - "@cspell/cspell-pipe": { - "version": "6.31.1", - "dev": true - }, - "@cspell/cspell-service-bus": { - "version": "6.31.1", - "dev": true - }, - "@cspell/cspell-types": { - "version": "6.31.1", - "dev": true - }, - "@cspell/dict-ada": { - "version": "4.0.1", - "dev": true - }, - "@cspell/dict-aws": { - "version": "3.0.0", - "dev": true - }, - "@cspell/dict-bash": { - "version": "4.1.1", - "dev": true - }, - "@cspell/dict-companies": { - "version": "3.0.10", - "dev": true - }, - "@cspell/dict-cpp": { - "version": "5.0.3", - "dev": true - }, - "@cspell/dict-cryptocurrencies": { - "version": "3.0.1", - "dev": true - }, - "@cspell/dict-csharp": { - "version": "4.0.2", - "dev": true - }, - "@cspell/dict-css": { - "version": "4.0.6", - "dev": true - }, - "@cspell/dict-dart": { - "version": "2.0.2", - "dev": true - }, - "@cspell/dict-django": { - "version": "4.0.2", - "dev": true - }, - "@cspell/dict-docker": { - "version": "1.1.6", - "dev": true - }, - "@cspell/dict-dotnet": { - "version": "5.0.0", - "dev": true - }, - "@cspell/dict-elixir": { - "version": "4.0.3", - "dev": true - }, - "@cspell/dict-en_us": { - "version": "4.3.2", - "dev": true - }, - "@cspell/dict-en-common-misspellings": { - "version": "1.0.2", - "dev": true - }, - "@cspell/dict-en-gb": { - "version": "1.1.33", - "dev": true - }, - "@cspell/dict-filetypes": { - "version": "3.0.0", - "dev": true - }, - "@cspell/dict-fonts": { - "version": "3.0.2", - "dev": true - }, - "@cspell/dict-fullstack": { - "version": "3.1.5", - "dev": true - }, - "@cspell/dict-gaming-terms": { - "version": "1.0.4", - "dev": true - }, - "@cspell/dict-git": { - "version": "2.0.0", - "dev": true - }, - "@cspell/dict-golang": { - "version": "6.0.1", - "dev": true - }, - "@cspell/dict-haskell": { - "version": "4.0.1", - "dev": true - }, - "@cspell/dict-html": { - "version": "4.0.3", - "dev": true - }, - "@cspell/dict-html-symbol-entities": { - "version": "4.0.0", - "dev": true - }, - "@cspell/dict-java": { - "version": "5.0.5", - "dev": true - }, - "@cspell/dict-k8s": { - "version": "1.0.1", - "dev": true - }, - "@cspell/dict-latex": { - "version": "4.0.0", - "dev": true - }, - "@cspell/dict-lorem-ipsum": { - "version": "3.0.0", - "dev": true - }, - "@cspell/dict-lua": { - "version": "4.0.1", - "dev": true - }, - "@cspell/dict-node": { - "version": "4.0.2", - "dev": true - }, - "@cspell/dict-npm": { - "version": "5.0.5", - "dev": true - }, - "@cspell/dict-php": { - "version": "4.0.1", - "dev": true - }, - "@cspell/dict-powershell": { - "version": "5.0.1", - "dev": true - }, - "@cspell/dict-public-licenses": { - "version": "2.0.2", - "dev": true - }, - "@cspell/dict-python": { - "version": "4.0.4", - "dev": true - }, - "@cspell/dict-r": { - "version": "2.0.1", - "dev": true - }, - "@cspell/dict-ruby": { - "version": "5.0.0", - "dev": true - }, - "@cspell/dict-rust": { - "version": "4.0.1", - "dev": true - }, - "@cspell/dict-scala": { - "version": "5.0.0", - "dev": true - }, - "@cspell/dict-software-terms": { - "version": "3.1.8", - "dev": true - }, - "@cspell/dict-sql": { - "version": "2.1.0", - "dev": true - }, - "@cspell/dict-svelte": { - "version": "1.0.2", - "dev": true - }, - "@cspell/dict-swift": { - "version": "2.0.1", - "dev": true - }, - "@cspell/dict-typescript": { - "version": "3.1.1", - "dev": true - }, - "@cspell/dict-vue": { - "version": "3.0.0", - "dev": true - }, - "@cspell/dynamic-import": { - "version": "6.31.1", - "dev": true, - "requires": { - "import-meta-resolve": "^2.2.2" - } - }, - "@cspell/strong-weak-map": { - "version": "6.31.1", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.5.1", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.0.3", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.2", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@eslint/js": { - "version": "8.41.0", - "dev": true - }, - "@hapi/boom": { - "version": "10.0.1", - "requires": { - "@hapi/hoek": "^11.0.2" - }, - "dependencies": { - "@hapi/hoek": { - "version": "11.0.2" - } - } - }, - "@hapi/bourne": { - "version": "3.0.0" - }, - "@hapi/hoek": { - "version": "10.0.1" - }, - "@hapi/topo": { - "version": "5.1.0", - "requires": { - "@hapi/hoek": "^9.0.0" - }, - "dependencies": { - "@hapi/hoek": { - "version": "9.3.0" - } - } - }, - "@hapi/wreck": { - "version": "18.0.1", - "requires": { - "@hapi/boom": "^10.0.1", - "@hapi/bourne": "^3.0.0", - "@hapi/hoek": "^11.0.2" - }, - "dependencies": { - "@hapi/hoek": { - "version": "11.0.2" - } - } - }, - "@humanwhocodes/config-array": { - "version": "0.11.8", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "dev": true - }, - "@jest/console": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0" - } - }, - "@jest/expect": { - "version": "29.5.0", - "dev": true, - "requires": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" - } - }, - "@jest/expect-utils": { - "version": "29.5.0", - "dev": true, - "requires": { - "jest-get-type": "^29.4.3" - } - }, - "@jest/fake-timers": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - } - }, - "@jest/globals": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" - } - }, - "@jest/reporters": { - "version": "29.5.0", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - } - }, - "@jest/schemas": { - "version": "29.4.3", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/source-map": { - "version": "29.4.3", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/test-result": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - } - }, - "@jest/types": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.18", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true - } - } - }, - "@microsoft/applicationinsights-web-snippet": { - "version": "1.0.1" - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@octokit/auth-app": { - "version": "4.0.13", - "requires": { - "@octokit/auth-oauth-app": "^5.0.0", - "@octokit/auth-oauth-user": "^2.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "deprecation": "^2.3.1", - "lru-cache": "^9.0.0", - "universal-github-app-jwt": "^1.1.1", - "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "9.1.1" - } - } - }, - "@octokit/auth-oauth-app": { - "version": "5.0.5", - "requires": { - "@octokit/auth-oauth-device": "^4.0.0", - "@octokit/auth-oauth-user": "^2.0.0", - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "@types/btoa-lite": "^1.0.0", - "btoa-lite": "^1.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/auth-oauth-device": { - "version": "4.0.4", - "requires": { - "@octokit/oauth-methods": "^2.0.0", - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/auth-oauth-user": { - "version": "2.1.1", - "requires": { - "@octokit/auth-oauth-device": "^4.0.0", - "@octokit/oauth-methods": "^2.0.0", - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "btoa-lite": "^1.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/auth-token": { - "version": "3.0.3", - "requires": { - "@octokit/types": "^9.0.0" - } - }, - "@octokit/core": { - "version": "4.2.1", - "requires": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/endpoint": { - "version": "7.0.5", - "requires": { - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/graphql": { - "version": "5.0.5", - "requires": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/oauth-authorization-url": { - "version": "5.0.0" - }, - "@octokit/oauth-methods": { - "version": "2.0.5", - "requires": { - "@octokit/oauth-authorization-url": "^5.0.0", - "@octokit/request": "^6.2.3", - "@octokit/request-error": "^3.0.3", - "@octokit/types": "^9.0.0", - "btoa-lite": "^1.0.0" - } - }, - "@octokit/openapi-types": { - "version": "17.2.0" - }, - "@octokit/plugin-paginate-graphql": { - "version": "2.0.1", - "requires": {} - }, - "@octokit/plugin-paginate-rest": { - "version": "6.1.2", - "requires": { - "@octokit/tsconfig": "^1.0.2", - "@octokit/types": "^9.2.3" - } - }, - "@octokit/plugin-request-log": { - "version": "1.0.4", - "requires": {} - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "7.1.2", - "requires": { - "@octokit/types": "^9.2.3", - "deprecation": "^2.3.1" - } - }, - "@octokit/request": { - "version": "6.2.5", - "requires": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/request-error": { - "version": "3.0.3", - "requires": { - "@octokit/types": "^9.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/rest": { - "version": "19.0.11", - "requires": { - "@octokit/core": "^4.2.1", - "@octokit/plugin-paginate-rest": "^6.1.2", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^7.1.2" - } - }, - "@octokit/tsconfig": { - "version": "1.0.2" - }, - "@octokit/types": { - "version": "9.2.3", - "requires": { - "@octokit/openapi-types": "^17.2.0" - } - }, - "@opentelemetry/api": { - "version": "1.4.1" - }, - "@opentelemetry/core": { - "version": "1.13.0", - "requires": { - "@opentelemetry/semantic-conventions": "1.13.0" - } - }, - "@opentelemetry/instrumentation": { - "version": "0.35.1", - "requires": { - "require-in-the-middle": "^5.0.3", - "semver": "^7.3.2", - "shimmer": "^1.2.1" - } - }, - "@opentelemetry/resources": { - "version": "1.13.0", - "requires": { - "@opentelemetry/core": "1.13.0", - "@opentelemetry/semantic-conventions": "1.13.0" - } - }, - "@opentelemetry/sdk-trace-base": { - "version": "1.13.0", - "requires": { - "@opentelemetry/core": "1.13.0", - "@opentelemetry/resources": "1.13.0", - "@opentelemetry/semantic-conventions": "1.13.0" - } - }, - "@opentelemetry/semantic-conventions": { - "version": "1.13.0" - }, - "@redis/bloom": { - "version": "1.2.0", - "requires": {} - }, - "@redis/client": { - "version": "1.5.9", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.9.tgz", - "integrity": "sha512-SffgN+P1zdWJWSXBvJeynvEnmnZrYmtKSRW00xl8pOPFOMJjxRR9u0frSxJpPR6Y4V+k54blJjGW7FgxbTI7bQ==", - "requires": { - "cluster-key-slot": "1.1.2", - "generic-pool": "3.9.0", - "yallist": "4.0.0" - } - }, - "@redis/graph": { - "version": "1.1.0", - "requires": {} - }, - "@redis/json": { - "version": "1.0.4", - "requires": {} - }, - "@redis/search": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz", - "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==", - "requires": {} - }, - "@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "requires": {} - }, - "@sideway/address": { - "version": "4.1.4", - "requires": { - "@hapi/hoek": "^9.0.0" - }, - "dependencies": { - "@hapi/hoek": { - "version": "9.3.0" - } - } - }, - "@sideway/formula": { - "version": "3.0.1" - }, - "@sideway/pinpoint": { - "version": "2.0.0" - }, - "@sinclair/typebox": { - "version": "0.25.24", - "dev": true - }, - "@sinonjs/commons": { - "version": "2.0.0", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.0.2", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0" - } - }, - "@tootallnate/once": { - "version": "2.0.0" - }, - "@ts-morph/common": { - "version": "0.12.3", - "dev": true, - "requires": { - "fast-glob": "^3.2.7", - "minimatch": "^3.0.4", - "mkdirp": "^1.0.4", - "path-browserify": "^1.0.1" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "dev": true - }, - "@types/babel__core": { - "version": "7.20.0", - "dev": true, - "requires": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.18.5", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/btoa-lite": { - "version": "1.0.0" - }, - "@types/connect": { - "version": "3.4.35", - "requires": { - "@types/node": "*" - } - }, - "@types/debug": { - "version": "4.1.7", - "dev": true, - "requires": { - "@types/ms": "*" - } - }, - "@types/express": { - "version": "4.17.17", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.34", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "@types/express-session": { - "version": "1.17.7", - "dev": true, - "requires": { - "@types/express": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.6", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/is-buffer": { - "version": "2.0.0", - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "29.5.1", - "dev": true, - "requires": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.11", - "dev": true - }, - "@types/jsonwebtoken": { - "version": "9.0.2", - "requires": { - "@types/node": "*" - } - }, - "@types/lodash": { - "version": "4.14.194", - "dev": true - }, - "@types/luxon": { - "version": "3.3.0", - "dev": true - }, - "@types/memory-cache": { - "version": "0.2.2", - "dev": true - }, - "@types/mime": { - "version": "1.3.2" - }, - "@types/morgan": { - "version": "1.9.4", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/ms": { - "version": "0.7.31", - "dev": true - }, - "@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" - }, - "@types/node-fetch": { - "version": "2.6.1", - "requires": { - "@types/node": "*", - "form-data": "^3.0.0" - }, - "dependencies": { - "form-data": { - "version": "3.0.1", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } - } - }, - "@types/node-jose": { - "version": "1.1.10", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/oauth": { - "version": "0.9.1", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/object-path": { - "version": "0.11.1", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "dev": true - }, - "@types/passport": { - "version": "1.0.12", - "dev": true, - "requires": { - "@types/express": "*" - } - }, - "@types/passport-azure-ad": { - "version": "4.3.1", - "dev": true, - "requires": { - "@types/express": "*", - "@types/passport": "*" - } - }, - "@types/passport-github": { - "version": "1.1.7", - "dev": true, - "requires": { - "@types/express": "*", - "@types/passport": "*", - "@types/passport-oauth2": "*" - } - }, - "@types/passport-oauth2": { - "version": "1.4.11", - "dev": true, - "requires": { - "@types/express": "*", - "@types/oauth": "*", - "@types/passport": "*" - } - }, - "@types/pg": { - "version": "8.10.1", - "dev": true, - "requires": { - "@types/node": "*", - "pg-protocol": "*", - "pg-types": "^4.0.1" - }, - "dependencies": { - "pg-types": { - "version": "4.0.1", - "dev": true, - "requires": { - "pg-int8": "1.0.1", - "pg-numeric": "1.0.2", - "postgres-array": "~3.0.1", - "postgres-bytea": "~3.0.0", - "postgres-date": "~2.0.1", - "postgres-interval": "^3.0.0", - "postgres-range": "^1.1.1" - } - }, - "postgres-array": { - "version": "3.0.2", - "dev": true - }, - "postgres-bytea": { - "version": "3.0.0", - "dev": true, - "requires": { - "obuf": "~1.1.2" - } - }, - "postgres-date": { - "version": "2.0.1", - "dev": true - }, - "postgres-interval": { - "version": "3.0.0", - "dev": true - } - } - }, - "@types/prettier": { - "version": "2.7.2", - "dev": true - }, - "@types/pug": { - "version": "2.0.6", - "dev": true - }, - "@types/qs": { - "version": "6.9.7" - }, - "@types/range-parser": { - "version": "1.2.4" - }, - "@types/recursive-readdir": { - "version": "2.2.1", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/semver": { - "version": "7.5.0", - "dev": true - }, - "@types/send": { - "version": "0.17.1", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.13.10", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/simple-oauth2": { - "version": "5.0.4", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "dev": true - }, - "@types/tunnel": { - "version": "0.0.3", - "requires": { - "@types/node": "*" - } - }, - "@types/validator": { - "version": "13.7.17", - "dev": true - }, - "@types/yargs": { - "version": "17.0.24", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.59.7", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/type-utils": "5.59.7", - "@typescript-eslint/utils": "5.59.7", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.59.7", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.59.7", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.59.7", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.59.7", - "@typescript-eslint/utils": "5.59.7", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.59.7", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.7", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.59.7", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.7", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" - } - }, - "accepts": { - "version": "1.3.8", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.8.0", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.2.0", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "requires": { - "debug": "4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.3", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "app-root-path": { - "version": "3.1.0" - }, - "applicationinsights": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-2.7.0.tgz", - "integrity": "sha512-/vV5X6M4TlRA5NxNZAdCE0gukzfK24mb3z18D5Kl/CyIfSVIkafsIji3mK+Zi5q+7dn6H1CkFazlcnLf40anHw==", - "requires": { - "@azure/core-auth": "^1.4.0", - "@azure/core-rest-pipeline": "1.10.1", - "@azure/core-util": "1.2.0", - "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.3", - "@microsoft/applicationinsights-web-snippet": "^1.0.1", - "@opentelemetry/api": "^1.0.4", - "@opentelemetry/core": "^1.12.0", - "@opentelemetry/sdk-trace-base": "^1.12.0", - "@opentelemetry/semantic-conventions": "^1.12.0", - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "1.1.0", - "diagnostic-channel-publishers": "1.0.6" - } - }, - "arg": { - "version": "4.1.3", - "dev": true - }, - "argparse": { - "version": "2.0.1" - }, - "array-flatten": { - "version": "1.1.1" - }, - "array-timsort": { - "version": "1.0.3", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "dev": true - }, - "asap": { - "version": "2.0.6" - }, - "assert-never": { - "version": "1.2.1" - }, - "astral-regex": { - "version": "2.0.0", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1" - } - } - }, - "async-prompt": { - "version": "1.0.1", - "requires": { - "keypress": "~0.2.1" - } - }, - "asynckit": { - "version": "0.4.0" - }, - "available-typed-arrays": { - "version": "1.0.5" - }, - "axios": { - "version": "1.4.0", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "babel-jest": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/transform": "^29.5.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "29.5.0", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.5.0", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "babel-walk": { - "version": "3.0.0-canary-5", - "requires": { - "@babel/types": "^7.9.6" - } - }, - "balanced-match": { - "version": "1.0.2" - }, - "base64-js": { - "version": "1.5.1" - }, - "base64url": { - "version": "3.0.1" - }, - "basic-auth": { - "version": "2.0.1", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "before-after-hook": { - "version": "2.2.2" - }, - "body-parser": { - "version": "1.20.2", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browserslist": { - "version": "4.21.5", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" - } - }, - "bs-logger": { - "version": "0.2.6", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "btoa-lite": { - "version": "1.0.0" - }, - "buffer": { - "version": "6.0.3", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1" - }, - "buffer-from": { - "version": "1.1.2", - "dev": true - }, - "buffer-writer": { - "version": "2.0.0" - }, - "builtins": { - "version": "5.0.1", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "bunyan": { - "version": "1.8.15", - "requires": { - "dtrace-provider": "~0.8", - "moment": "^2.19.3", - "mv": "~2", - "safe-json-stringify": "~1" - } - }, - "bytes": { - "version": "3.1.2" - }, - "cache-manager": { - "version": "3.6.3", - "requires": { - "async": "3.2.3", - "lodash.clonedeep": "^4.5.0", - "lru-cache": "6.0.0" - }, - "dependencies": { - "async": { - "version": "3.2.3" - } - } - }, - "call-bind": { - "version": "1.0.2", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001486", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "dev": true - }, - "character-parser": { - "version": "2.2.0", - "requires": { - "is-regex": "^1.0.3" - } - }, - "ci-info": { - "version": "3.8.0", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "dev": true - }, - "clean-stack": { - "version": "2.2.0", - "dev": true - }, - "clear-module": { - "version": "4.1.2", - "dev": true, - "requires": { - "parent-module": "^2.0.0", - "resolve-from": "^5.0.0" - } - }, - "cli-cursor": { - "version": "3.1.0", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-truncate": { - "version": "3.1.0", - "dev": true, - "requires": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "dev": true - }, - "string-width": { - "version": "5.1.2", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.0.1", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "cliui": { - "version": "8.0.1", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "cls-hooked": { - "version": "4.2.2", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1" - } - } - }, - "cluster-key-slot": { - "version": "1.1.2" - }, - "co": { - "version": "4.6.0", - "dev": true - }, - "code-block-writer": { - "version": "11.0.3", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "dev": true - }, - "color-contrast-checker": { - "version": "2.1.0" - }, - "color-convert": { - "version": "2.0.1", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "dev": true - }, - "colorette": { - "version": "2.0.20", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "10.0.1", - "dev": true - }, - "comment-json": { - "version": "4.2.3", - "dev": true, - "requires": { - "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", - "esprima": "^4.0.1", - "has-own-prop": "^2.0.0", - "repeat-string": "^1.6.1" - } - }, - "compressible": { - "version": "2.0.18", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "bytes": { - "version": "3.0.0" - }, - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - } - } - }, - "concat-map": { - "version": "0.0.1" - }, - "configstore": { - "version": "5.0.1", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "write-file-atomic": { - "version": "3.0.3", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - } - } - }, - "connect-redis": { - "version": "7.1.0", - "requires": {} - }, - "constantinople": { - "version": "4.0.1", - "requires": { - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.1" - } - }, - "content-disposition": { - "version": "0.5.4", - "requires": { - "safe-buffer": "5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "content-type": { - "version": "1.0.5" - }, - "continuation-local-storage": { - "version": "3.2.1", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "convert-source-map": { - "version": "2.0.0", - "dev": true - }, - "cookie": { - "version": "0.5.0" - }, - "cookie-signature": { - "version": "1.0.6" - }, - "core-util-is": { - "version": "1.0.3", - "dev": true - }, - "cors": { - "version": "2.8.5", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "8.0.0", - "dev": true, - "requires": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - } - }, - "create-require": { - "version": "1.1.1", - "dev": true - }, - "crypto-random-string": { - "version": "2.0.0", - "dev": true - }, - "cspell": { - "version": "6.31.1", - "dev": true, - "requires": { - "@cspell/cspell-pipe": "6.31.1", - "@cspell/dynamic-import": "6.31.1", - "chalk": "^4.1.2", - "commander": "^10.0.0", - "cspell-gitignore": "6.31.1", - "cspell-glob": "6.31.1", - "cspell-io": "6.31.1", - "cspell-lib": "6.31.1", - "fast-glob": "^3.2.12", - "fast-json-stable-stringify": "^2.1.0", - "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", - "imurmurhash": "^0.1.4", - "semver": "^7.3.8", - "strip-ansi": "^6.0.1", - "vscode-uri": "^3.0.7" - } - }, - "cspell-dictionary": { - "version": "6.31.1", - "dev": true, - "requires": { - "@cspell/cspell-pipe": "6.31.1", - "@cspell/cspell-types": "6.31.1", - "cspell-trie-lib": "6.31.1", - "fast-equals": "^4.0.3", - "gensequence": "^5.0.2" - } - }, - "cspell-gitignore": { - "version": "6.31.1", - "dev": true, - "requires": { - "cspell-glob": "6.31.1", - "find-up": "^5.0.0" - } - }, - "cspell-glob": { - "version": "6.31.1", - "dev": true, - "requires": { - "micromatch": "^4.0.5" - } - }, - "cspell-grammar": { - "version": "6.31.1", - "dev": true, - "requires": { - "@cspell/cspell-pipe": "6.31.1", - "@cspell/cspell-types": "6.31.1" - } - }, - "cspell-io": { - "version": "6.31.1", - "dev": true, - "requires": { - "@cspell/cspell-service-bus": "6.31.1", - "node-fetch": "^2.6.9" - } - }, - "cspell-lib": { - "version": "6.31.1", - "dev": true, - "requires": { - "@cspell/cspell-bundled-dicts": "6.31.1", - "@cspell/cspell-pipe": "6.31.1", - "@cspell/cspell-types": "6.31.1", - "@cspell/strong-weak-map": "6.31.1", - "clear-module": "^4.1.2", - "comment-json": "^4.2.3", - "configstore": "^5.0.1", - "cosmiconfig": "8.0.0", - "cspell-dictionary": "6.31.1", - "cspell-glob": "6.31.1", - "cspell-grammar": "6.31.1", - "cspell-io": "6.31.1", - "cspell-trie-lib": "6.31.1", - "fast-equals": "^4.0.3", - "find-up": "^5.0.0", - "gensequence": "^5.0.2", - "import-fresh": "^3.3.0", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0", - "vscode-languageserver-textdocument": "^1.0.8", - "vscode-uri": "^3.0.7" - } - }, - "cspell-trie-lib": { - "version": "6.31.1", - "dev": true, - "requires": { - "@cspell/cspell-pipe": "6.31.1", - "@cspell/cspell-types": "6.31.1", - "gensequence": "^5.0.2" - } - }, - "debug": { - "version": "4.3.4", - "requires": { - "ms": "2.1.2" - } - }, - "dedent": { - "version": "0.7.0", - "dev": true - }, - "deeks": { - "version": "2.6.0" - }, - "deep-is": { - "version": "0.1.4", - "dev": true - }, - "deepmerge": { - "version": "4.3.1" - }, - "define-lazy-prop": { - "version": "2.0.0" - }, - "delayed-stream": { - "version": "1.0.0" - }, - "depd": { - "version": "2.0.0" - }, - "deprecation": { - "version": "2.3.1" - }, - "destroy": { - "version": "1.2.0" - }, - "detect-newline": { - "version": "3.1.0", - "dev": true - }, - "diagnostic-channel": { - "version": "1.1.0", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1" - } - } - }, - "diagnostic-channel-publishers": { - "version": "1.0.6", - "requires": {} - }, - "diff": { - "version": "4.0.2", - "dev": true - }, - "diff-sequences": { - "version": "29.4.3", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doc-path": { - "version": "3.0.6" - }, - "doctrine": { - "version": "3.0.0", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "doctypes": { - "version": "1.1.0" - }, - "dot-prop": { - "version": "5.3.0", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" - }, - "dtrace-provider": { - "version": "0.8.8", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, - "eastasianwidth": { - "version": "0.2.0", - "dev": true - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "ee-first": { - "version": "1.1.1" - }, - "electron-to-chromium": { - "version": "1.4.392", - "dev": true - }, - "emitter-listener": { - "version": "1.1.2", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emittery": { - "version": "0.13.1", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "dev": true - }, - "encodeurl": { - "version": "1.0.2" - }, - "error-ex": { - "version": "1.3.2", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-promise": { - "version": "4.2.8" - }, - "escalade": { - "version": "3.1.1", - "dev": true - }, - "escape-html": { - "version": "1.0.3" - }, - "escape-string-regexp": { - "version": "4.0.0", - "dev": true - }, - "eslint": { - "version": "8.41.0", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.41.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "eslint-scope": { - "version": "7.2.0", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "dev": true - } - } - }, - "eslint-config-prettier": { - "version": "8.8.0", - "dev": true, - "requires": {} - }, - "eslint-plugin-es-x": { - "version": "6.2.1", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.5.0" - } - }, - "eslint-plugin-n": { - "version": "16.0.0", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^6.1.0", - "ignore": "^5.1.1", - "is-core-module": "^2.12.0", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.0" - } - }, - "eslint-plugin-prettier": { - "version": "4.2.1", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "3.4.1", - "dev": true - }, - "espree": { - "version": "9.5.2", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esprima": { - "version": "4.0.1", - "dev": true - }, - "esquery": { - "version": "1.5.0", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "dev": true - }, - "etag": { - "version": "1.8.1" - }, - "events": { - "version": "3.3.0" - }, - "execa": { - "version": "5.1.1", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - } - } - }, - "exit": { - "version": "0.1.2", - "dev": true - }, - "expect": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" - } - }, - "express": { - "version": "4.18.2", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "body-parser": { - "version": "1.20.1", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - }, - "raw-body": { - "version": "2.5.1", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "express-async-handler": { - "version": "1.1.4" - }, - "express-session": { - "version": "1.17.3", - "requires": { - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.2.1", - "uid-safe": "~2.1.5" - }, - "dependencies": { - "cookie": { - "version": "0.4.2" - }, - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "express-sslify": { - "version": "1.2.0" - }, - "fast-deep-equal": { - "version": "3.1.3", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "dev": true - }, - "fast-equals": { - "version": "4.0.3", - "dev": true - }, - "fast-glob": { - "version": "3.2.12", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0" - }, - "fast-levenshtein": { - "version": "2.0.6", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.1.1" - }, - "fast-xml-parser": { - "version": "4.2.2", - "requires": { - "strnum": "^1.0.5" - } - }, - "fastq": { - "version": "1.15.0", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.2", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-size": { - "version": "1.0.0" - }, - "fill-range": { - "version": "7.0.1", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.2.0", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - } - } - }, - "find-up": { - "version": "5.0.0", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.5", - "dev": true - }, - "follow-redirects": { - "version": "1.15.2" - }, - "for-each": { - "version": "0.3.3", - "requires": { - "is-callable": "^1.1.3" - } - }, - "form-data": { - "version": "4.0.0", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0" - }, - "fresh": { - "version": "0.5.2" - }, - "fs.realpath": { - "version": "1.0.0" - }, - "fsevents": { - "version": "2.3.2", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1" - }, - "generic-pool": { - "version": "3.9.0" - }, - "gensequence": { - "version": "5.0.2", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.0", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-package-type": { - "version": "0.1.0", - "dev": true - }, - "get-stdin": { - "version": "8.0.0", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "dev": true - }, - "github-username-regex": { - "version": "1.0.0" - }, - "glob": { - "version": "7.2.0", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "global-dirs": { - "version": "0.1.1", - "dev": true, - "requires": { - "ini": "^1.3.4" - } - }, - "globals": { - "version": "13.20.0", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.1.0", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.10" - }, - "grapheme-splitter": { - "version": "1.0.4", - "dev": true - }, - "graphemer": { - "version": "1.4.0", - "dev": true - }, - "has": { - "version": "1.0.3", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "dev": true - }, - "has-own-prop": { - "version": "2.0.0", - "dev": true - }, - "has-symbols": { - "version": "1.0.3" - }, - "has-tostringtag": { - "version": "1.0.0", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hsts": { - "version": "2.2.0", - "requires": { - "depd": "2.0.0" - } - }, - "html-escaper": { - "version": "2.0.2", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-proxy-agent": { - "version": "5.0.0", - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "dev": true - }, - "husky": { - "version": "8.0.3", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1" - }, - "ignore": { - "version": "5.2.0", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "parent-module": { - "version": "1.0.1", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "dev": true - } - } - }, - "import-local": { - "version": "3.1.0", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "import-meta-resolve": { - "version": "2.2.2", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4" - }, - "ini": { - "version": "1.3.8", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1" - }, - "is-arguments": { - "version": "1.1.1", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1" - }, - "is-buffer": { - "version": "2.0.5" - }, - "is-callable": { - "version": "1.2.7" - }, - "is-core-module": { - "version": "2.12.0", - "requires": { - "has": "^1.0.3" - } - }, - "is-docker": { - "version": "2.2.1" - }, - "is-expression": { - "version": "4.0.0", - "requires": { - "acorn": "^7.1.1", - "object-assign": "^4.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1" - } - } - }, - "is-extglob": { - "version": "2.1.1", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "dev": true - }, - "is-obj": { - "version": "2.0.0", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0" - }, - "is-promise": { - "version": "2.2.2" - }, - "is-regex": { - "version": "1.1.4", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-stream": { - "version": "2.0.1", - "dev": true - }, - "is-typed-array": { - "version": "1.1.10", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "requires": { - "is-docker": "^2.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.5", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", - "import-local": "^3.0.2", - "jest-cli": "^29.5.0" - } - }, - "jest-changed-files": { - "version": "29.5.0", - "dev": true, - "requires": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - } - }, - "jest-circus": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-cli": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "29.5.0", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-docblock": { - "version": "29.4.3", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" - } - }, - "jest-environment-node": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - } - }, - "jest-get-type": { - "version": "29.4.3", - "dev": true - }, - "jest-haste-map": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-junit": { - "version": "16.0.0", - "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "strip-ansi": "^6.0.1", - "uuid": "^8.3.2", - "xml": "^1.0.1" - } - }, - "jest-leak-detector": { - "version": "29.5.0", - "dev": true, - "requires": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-matcher-utils": { - "version": "29.5.0", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-message-util": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-util": "^29.5.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.3", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "29.4.3", - "dev": true - }, - "jest-resolve": { - "version": "29.5.0", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "29.5.0", - "dev": true, - "requires": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" - } - }, - "jest-runner": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - } - }, - "jest-runtime": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "29.5.0", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - } - }, - "jest-util": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "leven": "^3.1.0", - "pretty-format": "^29.5.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "dev": true - } - } - }, - "jest-watcher": { - "version": "29.5.0", - "dev": true, - "requires": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.5.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "29.5.0", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "joi": { - "version": "17.9.2", - "requires": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - }, - "dependencies": { - "@hapi/hoek": { - "version": "9.3.0" - } - } - }, - "jose": { - "version": "4.14.4" - }, - "js-stringify": { - "version": "1.0.2" - }, - "js-tokens": { - "version": "4.0.0", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "requires": { - "argparse": "^2.0.1" - } - }, - "jsbi": { - "version": "3.2.5" - }, - "jsesc": { - "version": "2.5.2", - "dev": true - }, - "json-2-csv": { - "version": "3.18.0", - "requires": { - "deeks": "2.6.0", - "doc-path": "3.0.6" - } - }, - "json-parse-better-errors": { - "version": "1.0.2" - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true - }, - "json5": { - "version": "2.2.3", - "dev": true - }, - "jsonc": { - "version": "2.0.0", - "requires": { - "fast-safe-stringify": "^2.0.6", - "graceful-fs": "^4.1.15", - "mkdirp": "^0.5.1", - "parse-json": "^4.0.0", - "strip-bom": "^4.0.0", - "strip-json-comments": "^3.0.1" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.6", - "requires": { - "minimist": "^1.2.6" - } - }, - "parse-json": { - "version": "4.0.0", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } - } - }, - "jsonwebtoken": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", - "integrity": "sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==", - "requires": { - "jws": "^3.2.2", - "lodash": "^4.17.21", - "ms": "^2.1.1", - "semver": "^7.3.8" - }, - "dependencies": { - "jwa": { - "version": "1.4.1", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "jssha": { - "version": "3.3.0" - }, - "jstransformer": { - "version": "1.0.0", - "requires": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" - } - }, - "jwa": { - "version": "2.0.0", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jwks-rsa": { - "version": "3.0.1", - "requires": { - "@types/express": "^4.17.14", - "@types/jsonwebtoken": "^9.0.0", - "debug": "^4.3.4", - "jose": "^4.10.4", - "limiter": "^1.1.5", - "lru-memoizer": "^2.1.4" - } - }, - "jws": { - "version": "4.0.0", - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "keypress": { - "version": "0.2.1" - }, - "kleur": { - "version": "3.0.3", - "dev": true - }, - "language-map": { - "version": "1.5.0" - }, - "leven": { - "version": "3.1.0", - "dev": true - }, - "levn": { - "version": "0.4.1", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lilconfig": { - "version": "2.1.0", - "dev": true - }, - "limiter": { - "version": "1.1.5" - }, - "lines-and-columns": { - "version": "1.2.4", - "dev": true - }, - "linkify-it": { - "version": "4.0.1", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, - "lint-staged": { - "version": "13.2.2", - "dev": true, - "requires": { - "chalk": "5.2.0", - "cli-truncate": "^3.1.0", - "commander": "^10.0.0", - "debug": "^4.3.4", - "execa": "^7.0.0", - "lilconfig": "2.1.0", - "listr2": "^5.0.7", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-inspect": "^1.12.3", - "pidtree": "^0.6.0", - "string-argv": "^0.3.1", - "yaml": "^2.2.2" - }, - "dependencies": { - "chalk": { - "version": "5.2.0", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "execa": { - "version": "7.1.1", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - } - }, - "human-signals": { - "version": "4.3.1", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "dev": true - }, - "mimic-fn": { - "version": "4.0.0", - "dev": true - }, - "npm-run-path": { - "version": "5.1.0", - "dev": true, - "requires": { - "path-key": "^4.0.0" - }, - "dependencies": { - "path-key": { - "version": "4.0.0", - "dev": true - } - } - }, - "onetime": { - "version": "6.0.0", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "strip-final-newline": { - "version": "3.0.0", - "dev": true - } - } - }, - "listr2": { - "version": "5.0.8", - "dev": true, - "requires": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.8.0", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "cli-truncate": { - "version": "2.1.0", - "dev": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - } - }, - "slice-ansi": { - "version": "3.0.0", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - } - } - }, - "locate-path": { - "version": "6.0.0", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21" - }, - "lodash.clonedeep": { - "version": "4.5.0" - }, - "lodash.memoize": { - "version": "4.1.2", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "dev": true - }, - "log-update": { - "version": "4.0.0", - "dev": true, - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "slice-ansi": { - "version": "4.0.0", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "long": { - "version": "5.2.0" - }, - "lru-cache": { - "version": "6.0.0", - "requires": { - "yallist": "^4.0.0" - } - }, - "lru-memoizer": { - "version": "2.1.4", - "requires": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "~4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "4.0.2", - "requires": { - "pseudomap": "^1.0.1", - "yallist": "^2.0.0" - } - }, - "yallist": { - "version": "2.1.2" - } - } - }, - "luxon": { - "version": "3.3.0" - }, - "make-dir": { - "version": "3.1.0", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "dev": true - }, - "makeerror": { - "version": "1.0.12", - "dev": true, - "requires": { - "tmpl": "1.0.5" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "markdown-it": { - "version": "13.0.1", + "node_modules/markdownlint-cli2/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, - "requires": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "engines": { + "node": ">=12" }, - "dependencies": { - "entities": { - "version": "3.0.1", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "markdownlint": { - "version": "0.28.2", + "node_modules/markdownlint-cli2/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, - "requires": { - "markdown-it": "13.0.1", - "markdownlint-micromark": "0.1.2" + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "markdownlint-cli2": { - "version": "0.7.1", + "node_modules/markdownlint-cli2/node_modules/strip-json-comments": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", + "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", "dev": true, - "requires": { - "globby": "13.1.4", - "markdownlint": "0.28.2", - "markdownlint-cli2-formatter-default": "0.0.4", - "micromatch": "4.0.5", - "strip-json-comments": "5.0.0", - "yaml": "2.2.2" - }, - "dependencies": { - "globby": { - "version": "13.1.4", - "dev": true, - "requires": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^4.0.0" - } - }, - "slash": { - "version": "4.0.0", - "dev": true - }, - "strip-json-comments": { - "version": "5.0.0", - "dev": true - } + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "markdownlint-cli2-formatter-default": { - "version": "0.0.4", + "node_modules/markdownlint-micromark": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.8.tgz", + "integrity": "sha512-1ouYkMRo9/6gou9gObuMDnvZM8jC/ly3QCFQyoSPCS2XV1ZClU0xpKbL1Ar3bWWRT1RnBZkWUEiNKrI2CwiBQA==", "dev": true, - "requires": {} - }, - "markdownlint-micromark": { - "version": "0.1.2", - "dev": true + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } }, - "mdurl": { - "version": "1.0.1", + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, - "media-typer": { - "version": "0.3.0" + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } }, - "memory-cache": { - "version": "0.2.0" + "node_modules/memory-cache": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", + "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==" }, - "merge-descriptors": { - "version": "1.0.1" + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, - "merge-stream": { + "node_modules/merge-stream": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "merge2": { + "node_modules/merge2": { "version": "1.4.1", - "dev": true + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } }, - "methods": { - "version": "1.1.2" + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } }, - "micromatch": { + "node_modules/micromatch": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "requires": { + "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, - "mime": { - "version": "1.6.0" + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } }, - "mime-db": { - "version": "1.52.0" + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/mime-types": { "version": "2.1.35", - "requires": { + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, - "mimic-fn": { + "node_modules/mimic-fn": { "version": "2.1.0", - "dev": true + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "minimatch": { - "version": "3.1.2", - "requires": { - "brace-expansion": "^1.1.7" + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "minimist": { - "version": "1.2.6" + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } }, - "mkdirp": { + "node_modules/mkdirp": { "version": "1.0.4", - "dev": true + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } }, - "module-details-from-path": { - "version": "1.0.3" + "node_modules/module-details-from-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" }, - "moment": { - "version": "2.29.4" + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } }, - "morgan": { + "node_modules/morgan": { "version": "1.10.0", - "requires": { + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", "depd": "~2.0.0", "on-finished": "~2.3.0", "on-headers": "~1.0.2" }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - } + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "ms": { - "version": "2.1.2" + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "mv": { + "node_modules/mv": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", "optional": true, - "requires": { + "dependencies": { "mkdirp": "~0.5.1", "ncp": "~2.0.0", "rimraf": "~2.4.0" }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/mv/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, "dependencies": { - "glob": { - "version": "6.0.4", - "optional": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "mkdirp": { - "version": "0.5.6", - "optional": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "rimraf": { - "version": "2.4.5", - "optional": true, - "requires": { - "glob": "^6.0.1" - } - } + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "nan": { - "version": "2.15.0", - "optional": true + "node_modules/mv/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "optional": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } }, - "natural-compare": { - "version": "1.4.0", - "dev": true + "node_modules/mv/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mv/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "optional": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mv/node_modules/rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "optional": true, + "dependencies": { + "glob": "^6.0.1" + }, + "bin": { + "rimraf": "bin.js" + } }, - "natural-compare-lite": { + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "optional": true + }, + "node_modules/natural-compare": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "ncp": { + "node_modules/ncp": { "version": "2.0.0", - "optional": true + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "optional": true, + "bin": { + "ncp": "bin/ncp" + } }, - "negotiator": { - "version": "0.6.3" + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } }, - "node-abort-controller": { - "version": "3.1.1" + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" }, - "node-fetch": { - "version": "2.6.11", - "requires": { + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { "whatwg-url": "^5.0.0" }, - "dependencies": { - "tr46": { - "version": "0.0.3" - }, - "webidl-conversions": { - "version": "3.0.1" - }, - "whatwg-url": { - "version": "5.0.0", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true } } }, - "node-forge": { - "version": "1.3.1" + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } }, - "node-int64": { + "node_modules/node-int64": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node-jose": { + "node_modules/node-jose": { "version": "2.2.0", - "requires": { + "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.2.0.tgz", + "integrity": "sha512-XPCvJRr94SjLrSIm4pbYHKLEaOsDvJCpyFw/6V/KK/IXmyZ6SFBzAUDO9HQf4DB/nTEFcRGH87mNciOP23kFjw==", + "dependencies": { "base64url": "^3.0.1", "buffer": "^6.0.3", "es6-promise": "^4.2.8", @@ -14935,156 +10170,274 @@ "pako": "^2.0.4", "process": "^0.11.10", "uuid": "^9.0.0" - }, - "dependencies": { - "uuid": { - "version": "9.0.0" - } } }, - "node-releases": { - "version": "2.0.10", + "node_modules/node-jose/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, - "nodemailer": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.4.tgz", - "integrity": "sha512-CXjQvrQZV4+6X5wP6ZIgdehJamI63MFoYFGGPtHudWym9qaEHDNdPzaj5bfMCvxG1vhAileSWW90q7nL0N36mA==" + "node_modules/nodemailer": { + "version": "6.9.8", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.8.tgz", + "integrity": "sha512-cfrYUk16e67Ks051i4CntM9kshRYei1/o/Gi8K1d+R34OIs21xdFnW7Pt7EucmVKA0LKtqUGNcjMZ7ehjl49mQ==", + "engines": { + "node": ">=6.0.0" + } }, - "normalize-path": { + "node_modules/normalize-path": { "version": "3.0.0", - "dev": true + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "npm-run-path": { + "node_modules/npm-run-path": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "requires": { + "dependencies": { "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "oauth": { - "version": "0.9.15" + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" }, - "object-assign": { - "version": "4.1.1" + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } }, - "object-inspect": { - "version": "1.12.3" + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "object-path": { - "version": "0.11.8" + "node_modules/object-path": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz", + "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==", + "engines": { + "node": ">= 10.12.0" + } }, - "obuf": { + "node_modules/obuf": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, - "octicons": { - "version": "5.0.1" - }, - "on-finished": { - "version": "2.3.0", - "requires": { + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "on-headers": { - "version": "1.0.2" + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } }, - "once": { + "node_modules/once": { "version": "1.4.0", - "requires": { + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { "wrappy": "1" } }, - "onetime": { + "node_modules/onetime": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { + "dependencies": { "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "open": { - "version": "8.4.0", - "requires": { + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "optionator": { - "version": "0.9.1", + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, - "requires": { + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "p-limit": { + "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "requires": { + "dependencies": { "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "requires": { + "dependencies": { "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-map": { - "version": "4.0.0", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "requires": { - "aggregate-error": "^3.0.0" + "engines": { + "node": ">=6" } }, - "p-try": { - "version": "2.2.0", - "dev": true - }, - "packet-reader": { - "version": "1.0.0" + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, - "pako": { - "version": "2.0.4" + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" }, - "parent-module": { + "node_modules/parent-module": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", + "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", "dev": true, - "requires": { + "dependencies": { "callsites": "^3.1.0" + }, + "engines": { + "node": ">=8" } }, - "parse-json": { + "node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "parseurl": { - "version": "1.3.3" + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } }, - "passport": { - "version": "0.6.0", - "requires": { + "node_modules/passport": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", + "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", + "dependencies": { "passport-strategy": "1.x.x", "pause": "0.0.1", "utils-merge": "^1.0.1" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" } }, - "passport-azure-ad": { + "node_modules/passport-azure-ad": { "version": "4.3.5", - "requires": { + "resolved": "https://registry.npmjs.org/passport-azure-ad/-/passport-azure-ad-4.3.5.tgz", + "integrity": "sha512-LBpXEght7hCMuMNFK4oegdN0uPBa3lpDMy71zQoB0zPg1RrGwdzpjwTiN1WzN0hY77fLyjz9tBr3TGAxnSgtEg==", + "dependencies": { "async": "^3.2.3", "base64url": "^3.0.0", "bunyan": "^1.8.14", @@ -15097,266 +10450,565 @@ "passport": "^0.6.0", "valid-url": "^1.0.6" }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/passport-azure-ad/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", "dependencies": { - "async": { - "version": "3.2.4" - }, - "jwa": { - "version": "1.4.1", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - } + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/passport-azure-ad/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/passport-azure-ad/node_modules/passport": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", + "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1", + "utils-merge": "^1.0.1" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" } }, - "passport-github": { + "node_modules/passport-github": { "version": "1.1.0", - "requires": { + "resolved": "https://registry.npmjs.org/passport-github/-/passport-github-1.1.0.tgz", + "integrity": "sha512-XARXJycE6fFh/dxF+Uut8OjlwbFEXgbPVj/+V+K7cvriRK7VcAOm+NgBmbiLM9Qv3SSxEAV+V6fIk89nYHXa8A==", + "dependencies": { "passport-oauth2": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" } }, - "passport-oauth2": { - "version": "1.6.1", - "requires": { + "node_modules/passport-oauth2": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz", + "integrity": "sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==", + "dependencies": { "base64url": "3.x.x", "oauth": "0.9.x", "passport-strategy": "1.x.x", "uid2": "0.0.x", "utils-merge": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" } }, - "passport-strategy": { - "version": "1.0.0" + "node_modules/passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", + "engines": { + "node": ">= 0.4.0" + } }, - "path-browserify": { + "node_modules/path-browserify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "dev": true }, - "path-exists": { + "node_modules/path-exists": { "version": "4.0.0", - "dev": true + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-is-absolute": { - "version": "1.0.1" + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/path-key": { "version": "3.1.1", - "dev": true + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-parse": { - "version": "1.0.7" + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "path-to-regexp": { - "version": "0.1.7" + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, - "path-type": { + "node_modules/path-type": { "version": "4.0.0", - "dev": true + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "pause": { - "version": "0.0.1" + "node_modules/pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" }, - "pg": { - "version": "8.11.0", - "requires": { + "node_modules/pg": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-cloudflare": "^1.1.0", - "pg-connection-string": "^2.6.0", - "pg-pool": "^3.6.0", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", "pg-protocol": "^1.6.0", "pg-types": "^2.1.0", "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } } }, - "pg-cloudflare": { - "version": "1.1.0", + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", "optional": true }, - "pg-connection-string": { - "version": "2.6.0" + "node_modules/pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, + "node_modules/pg-escape": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/pg-escape/-/pg-escape-0.2.0.tgz", + "integrity": "sha512-QfXcpxyN9vT+kvexQpTeNyiwCxs4LPXLAV/C0EeLTJPCF61swhGdDlnHcuDgxJudgKGfQYiCkegg0GsSKSvvEg==" }, - "pg-escape": { - "version": "0.2.0" + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } }, - "pg-int8": { - "version": "1.0.1" + "node_modules/pg-numeric": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "pg-numeric": { - "version": "1.0.2", - "dev": true + "node_modules/pg-pool": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "peerDependencies": { + "pg": ">=8.0" + } }, - "pg-pool": { - "version": "3.6.0", - "requires": {} + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" }, - "pg-protocol": { - "version": "1.6.0" + "node_modules/pg-types": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", + "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", + "dev": true, + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.0.1", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" + } }, - "pg-types": { + "node_modules/pg/node_modules/pg-types": { "version": "2.2.0", - "requires": { + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pg/node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/pg/node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg/node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg/node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "pgpass": { + "node_modules/pgpass": { "version": "1.0.5", - "requires": { + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { "split2": "^4.1.0" } }, - "picocolors": { + "node_modules/picocolors": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "picomatch": { + "node_modules/picomatch": { "version": "2.3.1", - "dev": true + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "pidtree": { + "node_modules/pidtree": { "version": "0.6.0", - "dev": true + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } }, - "pirates": { - "version": "4.0.5", - "dev": true + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "requires": { + "dependencies": { "find-up": "^4.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "find-up": { - "version": "4.1.0", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "postgres-array": { - "version": "2.0.0" + "node_modules/postgres-array": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "postgres-bytea": { - "version": "1.0.0" + "node_modules/postgres-bytea": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dev": true, + "dependencies": { + "obuf": "~1.1.2" + }, + "engines": { + "node": ">= 6" + } }, - "postgres-date": { - "version": "1.0.7" + "node_modules/postgres-date": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", + "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "postgres-interval": { - "version": "1.2.0", - "requires": { - "xtend": "^4.0.0" + "node_modules/postgres-interval": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "dev": true, + "engines": { + "node": ">=12" } }, - "postgres-range": { + "node_modules/postgres-range": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", + "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", "dev": true }, - "prelude-ls": { + "node_modules/prelude-ls": { "version": "1.2.1", - "dev": true + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "prettier": { - "version": "2.8.8", - "dev": true + "node_modules/prettier": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } }, - "prettier-linter-helpers": { + "node_modules/prettier-linter-helpers": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, - "requires": { + "dependencies": { "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "pretty-format": { - "version": "29.5.0", + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", + "dependencies": { + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "dev": true - } + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "priorityqueuejs": { - "version": "1.0.0" + "node_modules/priorityqueuejs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz", + "integrity": "sha512-lg++21mreCEOuGWTbO5DnJKAdxfjrdN0S9ysoW9SzdSJvbkWpkaDdpG/cdsPCsEnoLUwmd9m3WcZhngW7yKA2g==" }, - "process": { - "version": "0.11.10" + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } }, - "promise": { + "node_modules/promise": { "version": "7.3.1", - "requires": { + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dependencies": { "asap": "~2.0.3" } }, - "prompts": { + "node_modules/prompts": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, - "requires": { + "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" } }, - "proxy-addr": { + "node_modules/proxy-addr": { "version": "2.0.7", - "requires": { + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" } }, - "proxy-from-env": { - "version": "1.1.0" + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "pseudomap": { - "version": "1.0.2" + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, - "pug": { + "node_modules/pug": { "version": "3.0.2", - "requires": { + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "dependencies": { "pug-code-gen": "^3.0.2", "pug-filters": "^4.0.0", "pug-lexer": "^5.0.1", @@ -15367,17 +11019,21 @@ "pug-strip-comments": "^2.0.0" } }, - "pug-attrs": { + "node_modules/pug-attrs": { "version": "3.0.0", - "requires": { + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dependencies": { "constantinople": "^4.0.1", "js-stringify": "^1.0.2", "pug-runtime": "^3.0.0" } }, - "pug-code-gen": { + "node_modules/pug-code-gen": { "version": "3.0.2", - "requires": { + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", "js-stringify": "^1.0.2", @@ -15388,12 +11044,16 @@ "with": "^7.0.0" } }, - "pug-error": { - "version": "2.0.0" + "node_modules/pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" }, - "pug-filters": { + "node_modules/pug-filters": { "version": "4.0.0", - "requires": { + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dependencies": { "constantinople": "^4.0.1", "jstransformer": "1.0.0", "pug-error": "^2.0.0", @@ -15401,235 +11061,480 @@ "resolve": "^1.15.1" } }, - "pug-lexer": { + "node_modules/pug-lexer": { "version": "5.0.1", - "requires": { + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dependencies": { "character-parser": "^2.2.0", "is-expression": "^4.0.0", "pug-error": "^2.0.0" } }, - "pug-linker": { + "node_modules/pug-linker": { "version": "4.0.0", - "requires": { + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dependencies": { "pug-error": "^2.0.0", "pug-walk": "^2.0.0" } }, - "pug-load": { + "node_modules/pug-load": { "version": "3.0.0", - "requires": { + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dependencies": { "object-assign": "^4.1.1", "pug-walk": "^2.0.0" } }, - "pug-parser": { + "node_modules/pug-parser": { "version": "6.0.0", - "requires": { + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dependencies": { "pug-error": "^2.0.0", "token-stream": "1.0.0" } }, - "pug-runtime": { - "version": "3.0.1" + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" }, - "pug-strip-comments": { + "node_modules/pug-strip-comments": { "version": "2.0.0", - "requires": { + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dependencies": { "pug-error": "^2.0.0" } }, - "pug-walk": { - "version": "2.0.0" + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" }, - "punycode": { - "version": "2.1.1", - "dev": true + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "pure-rand": { - "version": "6.0.2", - "dev": true + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] }, - "qs": { + "node_modules/qs": { "version": "6.11.0", - "requires": { + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "queue-microtask": { + "node_modules/queue-microtask": { "version": "1.2.3", - "dev": true + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "random-bytes": { - "version": "1.0.0" + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "engines": { + "node": ">= 0.8" + } }, - "range-parser": { - "version": "1.2.1" + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } }, - "raw-body": { + "node_modules/raw-body": { "version": "2.5.2", - "requires": { + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "react-is": { + "node_modules/react-is": { "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "recursive-readdir": { + "node_modules/recursive-readdir": { "version": "2.2.3", - "requires": { + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "redis": { - "version": "4.6.8", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", - "integrity": "sha512-S7qNkPUYrsofQ0ztWlTHSaK0Qqfl1y+WMIxrzeAGNG+9iUZB4HGeBgkHxE6uJJ6iXrkvLd1RVJ2nvu6H1sAzfQ==", - "requires": { + "node_modules/redis": { + "version": "4.6.12", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.12.tgz", + "integrity": "sha512-41Xuuko6P4uH4VPe5nE3BqXHB7a9lkFL0J29AlxKaIfD6eWO8VO/5PDF9ad2oS+mswMsfFxaM5DlE3tnXT+P8Q==", + "dependencies": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.9", - "@redis/graph": "1.1.0", - "@redis/json": "1.0.4", - "@redis/search": "1.1.3", + "@redis/client": "1.5.13", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.6", + "@redis/search": "1.1.6", "@redis/time-series": "1.0.5" } }, - "repeat-string": { + "node_modules/repeat-string": { "version": "1.6.1", - "dev": true + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "engines": { + "node": ">=0.10" + } }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", - "dev": true + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "require-in-the-middle": { - "version": "5.2.0", - "requires": { + "node_modules/require-in-the-middle": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz", + "integrity": "sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw==", + "dependencies": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", "resolve": "^1.22.1" + }, + "engines": { + "node": ">=8.6.0" } }, - "resolve": { - "version": "1.22.2", - "requires": { - "is-core-module": "^2.11.0", + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "resolve-cwd": { + "node_modules/resolve-cwd": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "requires": { + "dependencies": { "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", - "dev": true + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "resolve-global": { + "node_modules/resolve-pkg-maps": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, - "requires": { - "global-dirs": "^0.1.1" + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "resolve.exports": { + "node_modules/resolve.exports": { "version": "2.0.2", - "dev": true + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "restore-cursor": { - "version": "3.1.0", + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, - "requires": { + "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "reusify": { + "node_modules/reusify": { "version": "1.0.4", - "dev": true + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, - "rfdc": { - "version": "1.3.0", + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", "dev": true }, - "rhea": { + "node_modules/rhea": { "version": "3.0.2", - "requires": { + "resolved": "https://registry.npmjs.org/rhea/-/rhea-3.0.2.tgz", + "integrity": "sha512-0G1ZNM9yWin8VLvTxyISKH6KfR6gl1TW/1+5yMKPf2r1efhkzTLze09iFtT2vpDjuWIVtSmXz8r18lk/dO8qwQ==", + "dependencies": { "debug": "^4.3.3" } }, - "rhea-promise": { + "node_modules/rhea-promise": { "version": "3.0.1", - "requires": { + "resolved": "https://registry.npmjs.org/rhea-promise/-/rhea-promise-3.0.1.tgz", + "integrity": "sha512-Fcqgml7lgoyi7fH1ClsSyFr/xwToijEN3rULFgrIcL+7EHeduxkWogFxNHjFzHf2YGScAckJDaDxS1RdlTUQYw==", + "dependencies": { "debug": "^3.1.0", "rhea": "^3.0.0", "tslib": "^2.2.0" - }, + } + }, + "node_modules/rhea-promise/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { - "debug": { - "version": "3.2.7", - "requires": { - "ms": "^2.1.1" - } - } + "ms": "^2.1.1" } }, - "rimraf": { - "version": "3.0.2", - "requires": { - "glob": "^7.1.3" + "node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "run-parallel": { - "version": "1.2.0", + "node_modules/rimraf/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, - "requires": { - "queue-microtask": "^1.2.2" + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "rxjs": { - "version": "7.8.1", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "requires": { - "tslib": "^2.1.0" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "safe-buffer": { - "version": "5.1.2" + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "safe-json-stringify": { + "node_modules/safe-json-stringify": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", "optional": true }, - "safer-buffer": { - "version": "2.1.2" + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sax": { - "version": "1.2.4" + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" }, - "secure-compare": { - "version": "3.0.1" + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==" }, - "semaphore": { - "version": "1.1.0" + "node_modules/semaphore": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", + "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==", + "engines": { + "node": ">=0.8.0" + } }, - "semver": { - "version": "7.5.1", - "requires": { + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "send": { + "node_modules/send": { "version": "0.18.0", - "requires": { + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -15644,294 +11549,686 @@ "range-parser": "~1.2.1", "statuses": "2.0.1" }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0" - } - } - }, - "ms": { - "version": "2.1.3" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - } + "ms": "2.0.0" } }, - "serve-favicon": { + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-favicon": { "version": "2.5.0", - "requires": { + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==", + "dependencies": { "etag": "~1.8.1", "fresh": "0.5.2", "ms": "2.1.1", "parseurl": "~1.3.2", "safe-buffer": "5.1.1" }, - "dependencies": { - "ms": { - "version": "2.1.1" - }, - "safe-buffer": { - "version": "5.1.1" - } + "engines": { + "node": ">= 0.8.0" } }, - "serve-static": { + "node_modules/serve-favicon/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serve-favicon/node_modules/safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "node_modules/serve-static": { "version": "1.15.0", - "requires": { + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", + "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "dependencies": { + "define-data-property": "^1.1.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" } }, - "setprototypeof": { - "version": "1.2.0" + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, - "shebang-command": { + "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { + "dependencies": { "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "3.0.0", - "dev": true + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "shimmer": { - "version": "1.2.1" + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" }, - "side-channel": { + "node_modules/side-channel": { "version": "1.0.4", - "requires": { + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "simple-oauth2": { + "node_modules/simple-oauth2": { "version": "5.0.0", - "requires": { + "resolved": "https://registry.npmjs.org/simple-oauth2/-/simple-oauth2-5.0.0.tgz", + "integrity": "sha512-8291lo/z5ZdpmiOFzOs1kF3cxn22bMj5FFH+DNUppLJrpoIlM1QnFiE7KpshHu3J3i21TVcx4yW+gXYjdCKDLQ==", + "dependencies": { "@hapi/hoek": "^10.0.1", "@hapi/wreck": "^18.0.0", "debug": "^4.3.4", "joi": "^17.6.4" } }, - "sisteransi": { + "node_modules/sisteransi": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, - "slash": { + "node_modules/slash": { "version": "3.0.0", - "dev": true + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "slice-ansi": { + "node_modules/slice-ansi": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "6.2.1", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "4.0.0", - "dev": true - } + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "source-map": { + "node_modules/source-map": { "version": "0.6.1", - "dev": true + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "source-map-support": { + "node_modules/source-map-support": { "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, - "requires": { + "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "split2": { - "version": "4.1.0" + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "stack-chain": { - "version": "1.3.7" + "node_modules/stack-chain": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", + "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==" }, - "stack-utils": { + "node_modules/stack-utils": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, - "requires": { + "dependencies": { "escape-string-regexp": "^2.0.0" }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "dev": true - } + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" } }, - "statuses": { - "version": "2.0.1" + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } }, - "stoppable": { - "version": "1.1.0" + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "engines": { + "node": ">=4", + "npm": ">=6" + } }, - "string-argv": { + "node_modules/string-argv": { "version": "0.3.2", - "dev": true + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } }, - "string-length": { + "node_modules/string-length": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, - "requires": { + "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "string-width": { + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "strip-ansi": { + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { + "dependencies": { "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "strip-bom": { - "version": "4.0.0" + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "engines": { + "node": ">=8" + } }, - "strip-final-newline": { + "node_modules/strip-final-newline": { "version": "2.0.0", - "dev": true + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "strip-json-comments": { - "version": "3.1.1" + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "strnum": { - "version": "1.0.5" + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" }, - "supports-color": { + "node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0" + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } }, - "test-exclude": { + "node_modules/test-exclude": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "requires": { + "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" } }, - "text-table": { - "version": "0.2.0", - "dev": true + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "throat": { - "version": "6.0.2" + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } }, - "through": { - "version": "2.3.8", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "tmp": { + "node_modules/throat": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" + }, + "node_modules/tmp": { "version": "0.2.1", - "requires": { + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" } }, - "tmp-promise": { + "node_modules/tmp-promise": { "version": "3.0.3", - "requires": { + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dependencies": { "tmp": "^0.2.0" } }, - "tmpl": { + "node_modules/tmp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tmpl": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "to-fast-properties": { - "version": "2.0.0" + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } }, - "to-regex-range": { + "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" } }, - "toidentifier": { - "version": "1.0.1" + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" }, - "token-stream": { - "version": "1.0.0" + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, - "true-myth": { + "node_modules/true-myth": { "version": "4.1.1", - "dev": true + "resolved": "https://registry.npmjs.org/true-myth/-/true-myth-4.1.1.tgz", + "integrity": "sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg==", + "dev": true, + "engines": { + "node": "10.* || >= 12.*" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } }, - "ts-jest": { - "version": "29.1.0", + "node_modules/ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", "dev": true, - "requires": { + "dependencies": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", "jest-util": "^29.0.0", "json5": "^2.2.3", "lodash.memoize": "4.x", "make-error": "1.x", - "semver": "7.x", + "semver": "^7.5.3", "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } } }, - "ts-morph": { + "node_modules/ts-morph": { "version": "13.0.3", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-13.0.3.tgz", + "integrity": "sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw==", "dev": true, - "requires": { + "dependencies": { "@ts-morph/common": "~0.12.3", "code-block-writer": "^11.0.0" } }, - "ts-node": { - "version": "10.9.1", + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, - "requires": { + "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", @@ -15945,12 +12242,36 @@ "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "ts-prune": { + "node_modules/ts-prune": { "version": "0.10.3", + "resolved": "https://registry.npmjs.org/ts-prune/-/ts-prune-0.10.3.tgz", + "integrity": "sha512-iS47YTbdIcvN8Nh/1BFyziyUqmjXz7GVzWu02RaZXqb+e/3Qe1B7IQ4860krOeCGUeJmterAlaM2FRH0Ue0hjw==", "dev": true, - "requires": { + "dependencies": { "commander": "^6.2.1", "cosmiconfig": "^7.0.1", "json5": "^2.1.3", @@ -15958,131 +12279,219 @@ "true-myth": "^4.1.0", "ts-morph": "^13.0.1" }, - "dependencies": { - "commander": { - "version": "6.2.1", - "dev": true - }, - "cosmiconfig": { - "version": "7.1.0", - "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" - } - }, - "yaml": { - "version": "1.10.2", - "dev": true - } + "bin": { + "ts-prune": "lib/index.js" } }, - "tslib": { - "version": "2.3.1" - }, - "tsutils": { - "version": "3.21.0", + "node_modules/ts-prune/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "dev": true - } + "engines": { + "node": ">= 6" } }, - "tunnel": { - "version": "0.0.6" + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } }, - "type-check": { + "node_modules/type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { + "dependencies": { "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-detect": { + "node_modules/type-detect": { "version": "4.0.8", - "dev": true + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "type-fest": { + "node_modules/type-fest": { "version": "0.20.2", - "dev": true + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "type-is": { + "node_modules/type-is": { "version": "1.6.18", - "requires": { + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "typedarray-to-buffer": { + "node_modules/typedarray-to-buffer": { "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, - "requires": { + "dependencies": { "is-typedarray": "^1.0.0" } }, - "typescript": { - "version": "5.0.4", - "dev": true + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } }, - "uc.micro": { - "version": "1.0.6", + "node_modules/uc.micro": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.0.0.tgz", + "integrity": "sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==", "dev": true }, - "uid-safe": { + "node_modules/uid-safe": { "version": "2.1.5", - "requires": { + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dependencies": { "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "uid2": { - "version": "0.0.4" + "node_modules/uid2": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", + "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, - "unique-string": { - "version": "2.0.0", + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "universal-github-app-jwt": { - "version": "1.1.1", - "requires": { + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dev": true, + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universal-github-app-jwt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.2.tgz", + "integrity": "sha512-t1iB2FmLFE+yyJY9+3wMx0ejB+MQpEVkH0gQv7dR6FZyltyq+ZZO0uDpbopxhrZ3SLEO4dCEkIujOMldEQ2iOA==", + "dependencies": { "@types/jsonwebtoken": "^9.0.0", - "jsonwebtoken": "^9.0.0" + "jsonwebtoken": "^9.0.2" } }, - "universal-user-agent": { - "version": "6.0.0" + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" }, - "unpipe": { - "version": "1.0.0" + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } }, - "update-browserslist-db": { - "version": "1.0.11", + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, - "requires": { + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { + "dependencies": { "punycode": "^2.1.0" } }, - "util": { + "node_modules/util": { "version": "0.12.5", - "requires": { + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", @@ -16090,141 +12499,383 @@ "which-typed-array": "^1.1.2" } }, - "utils-merge": { - "version": "1.0.1" + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } }, - "uuid": { - "version": "8.3.2" + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } }, - "v8-compile-cache-lib": { + "node_modules/v8-compile-cache-lib": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "v8-to-istanbul": { - "version": "9.1.0", + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, - "requires": { + "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" + "convert-source-map": "^2.0.0" }, - "dependencies": { - "convert-source-map": { - "version": "1.9.0", - "dev": true - } + "engines": { + "node": ">=10.12.0" } }, - "valid-url": { - "version": "1.0.9" + "node_modules/valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" }, - "validator": { - "version": "13.9.0" + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } }, - "vary": { - "version": "1.1.2" + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } }, - "void-elements": { - "version": "3.1.0" + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "engines": { + "node": ">=0.10.0" + } }, - "vscode-languageserver-textdocument": { - "version": "1.0.8", + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz", + "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==", "dev": true }, - "vscode-uri": { - "version": "3.0.7", + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", "dev": true }, - "walk-back": { - "version": "5.1.0" + "node_modules/walk-back": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.0.tgz", + "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==", + "engines": { + "node": ">=12.17" + } }, - "walker": { + "node_modules/walker": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "requires": { + "dependencies": { "makeerror": "1.0.12" } }, - "which": { + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "which-typed-array": { - "version": "1.1.9", - "requires": { + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dependencies": { "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.4", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "with": { + "node_modules/with": { "version": "7.0.2", - "requires": { + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dependencies": { "@babel/parser": "^7.9.6", "@babel/types": "^7.9.6", "assert-never": "^1.2.1", "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" } }, - "word-wrap": { - "version": "1.2.3", - "dev": true + "node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, - "wrap-ansi": { + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { - "version": "1.0.2" + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "write-file-atomic": { - "version": "4.0.2", + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "xdg-basedir": { - "version": "4.0.0", + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "xml": { + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", "dev": true }, - "xmlbuilder": { - "version": "11.0.1" + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } }, - "xtend": { - "version": "4.0.2" + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", - "dev": true + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "yallist": { - "version": "4.0.0" + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "yaml": { - "version": "2.2.2", - "dev": true + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } }, - "yargs": { + "node_modules/yargs": { "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "requires": { + "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", @@ -16232,19 +12883,90 @@ "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, - "yargs-parser": { + "node_modules/yargs-parser": { "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "yn": { + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { "version": "3.1.1", - "dev": true + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", - "dev": true + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index a86483193..1b2d5c589 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,6 @@ { "name": "opensource-management-portal", "author": "Microsoft Corporation", - "contributors": [ - "Jeff Wilcox " - ], "version": "7.1.0", "license": "MIT", "private": true, @@ -20,20 +17,23 @@ ], "scripts": { "build": "tsc", + "dev:local": "DEBUG=startup EXIT_IMMEDIATELY=1 node ./dist/scripts/localEnvironment.js", "find-deadcode": "ts-prune", + "find-circular-dependencies": "npx madge --circular --extensions ts .", "fix:js": "eslint --fix .", - "fix:md": "markdownlint-cli2-fix \"**/*.md\"", + "fix:md": "markdownlint-cli2 --config ./.config/.markdownlint-cli2.jsonc --fix \"**/*.md\"", "fix": "npm run fix:js && npm run fix:md", "lint:js": "eslint .", - "lint:md": "markdownlint-cli2 \"**/*.md\"", - "lint:spell": "cspell --no-progress \"**\"", - "lint": "npm run lint:js && npm run lint:md && npm run lint:spell", - "prepare": "npx husky install", + "lint:json": "echo OK", + "lint:md": "markdownlint-cli2 --config ./.config/.markdownlint-cli2.jsonc \"**/*.md\"", + "lint:spell": "cspell --config ./.cspell.json --no-progress \"**\"", + "lint": "npm run lint:json && npm run lint:js && npm run lint:md && npm run lint:spell", + "prepare": "husky install || echo No Husky.", "start-4000": "PORT=4000 DEBUG=startup node ./dist/bin/www", "start-in-container": "node ./bin/www", "start": "node ./dist/bin/www", - "test:ci": "jest --watchAll=false --reporters=default --reporters=jest-junit", - "test": "jest" + "test:ci": "jest --config ./test/jest.config.ts --watchAll=false --reporters=default --reporters=jest-junit", + "test": "jest --config ./test/jest.config.ts" }, "lint-staged": { "*": [ @@ -41,7 +41,7 @@ "cspell --no-must-find-files" ], "*.{js,ts}": "eslint --fix", - "*.md": "markdownlint-cli2-fix" + "*.md": "markdownlint-cli2 --fix --config ./.config/.markdownlint-cli2.jsonc" }, "jest-junit": { "suiteNameTemplate": "{filepath}", @@ -65,21 +65,22 @@ "_end_microsoft_internal_": 0, "//...": "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ", "dependencies": { - "@azure/cosmos": "3.17.3", + "@azure/cosmos": "4.0.0", "@azure/data-tables": "13.2.2", - "@azure/identity": "3.2.2", + "@azure/identity": "4.0.0", "@azure/keyvault-secrets": "4.7.0", - "@azure/service-bus": "7.9.0", - "@azure/storage-blob": "12.14.0", - "@azure/storage-queue": "12.14.0", - "@octokit/plugin-paginate-graphql": "2.0.1", - "@octokit/request": "6.2.5", - "@octokit/auth-app": "4.0.13", - "@octokit/rest": "19.0.11", + "@azure/service-bus": "7.9.3", + "@azure/storage-blob": "12.17.0", + "@azure/storage-queue": "12.16.0", + "@octokit/plugin-paginate-graphql": "4.0.0", + "@octokit/request": "8.1.6", + "@octokit/auth-app": "6.0.3", + "@octokit/rest": "20.0.2", + "@primer/octicons": "19.8.0", "app-root-path": "3.1.0", - "applicationinsights": "2.7.0", + "applicationinsights": "2.9.2", "async-prompt": "1.0.1", - "axios": "1.4.0", + "axios": "1.6.5", "basic-auth": "2.0.1", "body-parser": "1.20.2", "color-contrast-checker": "2.1.0", @@ -90,7 +91,7 @@ "deepmerge": "4.3.1", "dotenv": "16.3.1", "express": "4.18.2", - "express-async-handler": "1.1.4", + "express-async-handler": "1.2.0", "express-session": "1.17.3", "express-sslify": "1.2.0", "file-size": "1.0.0", @@ -99,76 +100,76 @@ "js-yaml": "4.1.0", "json-2-csv": "^3.18.0", "jsonc": "2.0.0", - "jsonwebtoken": "9.0.1", - "jwks-rsa": "3.0.1", + "jsonwebtoken": "9.0.2", + "jwks-rsa": "3.1.0", "language-map": "1.5.0", "lodash": "4.17.21", - "luxon": "3.3.0", + "luxon": "3.4.4", "memory-cache": "0.2.0", - "moment": "2.29.4", + "moment": "2.30.1", "morgan": "1.10.0", "node-jose": "2.2.0", - "nodemailer": "6.9.4", + "nodemailer": "6.9.8", "object-path": "0.11.8", - "octicons": "5.0.1", - "passport": "0.6.0", + "passport": "0.7.0", "passport-azure-ad": "4.3.5", "passport-github": "1.1.0", - "pg": "8.11.0", + "pg": "8.11.3", "pg-escape": "0.2.0", "pug": "3.0.2", "pug-load": "3.0.0", "recursive-readdir": "2.2.3", - "redis": "4.6.8", + "redis": "4.6.12", "secure-compare": "3.0.1", - "semver": "7.5.1", + "semver": "7.5.4", "serve-favicon": "2.5.0", "simple-oauth2": "5.0.0", "throat": "6.0.2", "tmp-promise": "3.0.3", - "validator": "13.9.0", + "validator": "13.11.0", "walk-back": "5.1.0" }, "devDependencies": { - "@types/debug": "4.1.7", - "@types/express": "4.17.17", - "@types/express-session": "1.17.7", - "@types/jest": "29.5.1", - "@types/lodash": "4.14.194", - "@types/luxon": "3.3.0", - "@types/memory-cache": "0.2.2", - "@types/morgan": "1.9.4", - "@types/node": "20.4.2", - "@types/node-jose": "1.1.10", - "@types/object-path": "0.11.1", - "@types/passport": "1.0.12", - "@types/passport-azure-ad": "4.3.1", - "@types/passport-github": "1.1.7", - "@types/pg": "8.10.1", - "@types/pug": "2.0.6", - "@types/recursive-readdir": "2.2.1", - "@types/semver": "7.5.0", - "@types/simple-oauth2": "5.0.4", - "@types/validator": "13.7.17", - "@typescript-eslint/eslint-plugin": "5.59.7", - "@typescript-eslint/parser": "5.59.7", - "cspell": "6.31.1", - "eslint": "8.41.0", - "eslint-config-prettier": "8.8.0", - "eslint-plugin-n": "16.0.0", - "eslint-plugin-prettier": "4.2.1", + "@types/cors": "2.8.17", + "@types/debug": "4.1.12", + "@types/express": "4.17.21", + "@types/express-session": "1.17.10", + "@types/jest": "29.5.11", + "@types/lodash": "4.14.202", + "@types/luxon": "3.4.0", + "@types/memory-cache": "0.2.5", + "@types/morgan": "1.9.9", + "@types/node": "20.11.0", + "@types/node-jose": "1.1.13", + "@types/object-path": "0.11.4", + "@types/passport": "1.0.16", + "@types/passport-azure-ad": "4.3.5", + "@types/passport-github": "1.1.12", + "@types/pg": "8.10.9", + "@types/pug": "2.0.10", + "@types/recursive-readdir": "2.2.4", + "@types/semver": "7.5.6", + "@types/simple-oauth2": "5.0.7", + "@types/validator": "13.11.8", + "@typescript-eslint/eslint-plugin": "6.18.1", + "@typescript-eslint/parser": "6.18.1", + "cspell": "8.3.2", + "eslint": "8.56.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-n": "16.6.2", + "eslint-plugin-prettier": "5.1.3", "husky": "8.0.3", - "jest": "29.5.0", + "jest": "29.7.0", "jest-junit": "16.0.0", - "lint-staged": "13.2.2", - "markdownlint-cli2": "0.7.1", - "prettier": "2.8.8", - "ts-jest": "29.1.0", - "ts-node": "10.9.1", + "lint-staged": "15.2.0", + "markdownlint-cli2": "0.12.0", + "prettier": "3.1.1", + "ts-jest": "29.1.1", + "ts-node": "10.9.2", "ts-prune": "0.10.3", - "typescript": "5.0.4" + "typescript": "5.3.3" }, "engines": { - "node": ">=16" + "node": ">=18" } } diff --git a/routes/administration/app.ts b/routes/administration/app.ts index ea3419bb3..b5add5da4 100644 --- a/routes/administration/app.ts +++ b/routes/administration/app.ts @@ -3,19 +3,19 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { OrganizationSetting, IBasicGitHubAppInstallation, - SpecialTeam, -} from '../../entities/organizationSettings/organizationSetting'; + SystemTeam, +} from '../../business/entities/organizationSettings/organizationSetting'; import { IndividualContext } from '../../business/user'; import { Operations, Organization } from '../../business'; -import GitHubApplication from '../../business/application'; +import GitHubApplication, { isInstallationConfigured } from '../../business/application'; import { ReposAppRequest, IGitHubAppInstallation, @@ -27,7 +27,7 @@ import { router.use( '/:appId', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const providers = getProviders(req); const appId = Number(req.params.appId); const app = providers.operations.getApplicationById(appId); @@ -43,7 +43,7 @@ router.use( router.get( '/:appId', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const githubApplication = req['githubApplication'] as GitHubApplication; const installationIdString = req.query.installation_id; const setupAction = req.query.setup_action; @@ -71,7 +71,7 @@ router.get( router.use( '/:appId/installations/:installationId', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const githubApplication = req['githubApplication'] as GitHubApplication; const installationIdString = req.params.installationId; const { operations, organizationSettingsProvider } = getProviders(req); @@ -101,21 +101,6 @@ router.use( }) ); -function isInstallationConfigured( - settings: OrganizationSetting, - installation: IGitHubAppInstallation -): boolean { - if (!settings || !settings.installations) { - return false; - } - for (const install of settings.installations) { - if (install.installationId === installation.id) { - return true; - } - } - return false; -} - async function getDynamicSettingsFromLegacySettings( operations: Operations, staticSettings: any, @@ -166,7 +151,7 @@ async function getDynamicSettingsFromLegacySettings( router.post( '/:appId/installations/:installationId', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const hasBurnButtonClicked = req.body['burn-org-app']; const hasImportButtonClicked = req.body['adopt-import-settings']; const hasCreateButtonClicked = req.body['adopt-new-org']; @@ -229,9 +214,9 @@ router.post( if (result?.state === OrganizationMembershipState.Pending) { return res.send( `You need to accept the membership now at: https://github.com/${unconfiguredOrganization.name}` - ); + ) as unknown as void; } else { - return res.send('OK. Elevation should be all set.'); + return res.send('OK. Elevation should be all set.') as unknown as void; } } catch (error) { return next(error); @@ -311,22 +296,25 @@ router.post( // explicitly now allowing globalSudo to be set here throw new Error(`Unsupported team type: ${teamType}`); } - let specialTeamType: SpecialTeam = null; + let specialTeamType: SystemTeam = null; switch (teamType) { case 'everyone': - specialTeamType = SpecialTeam.Everyone; + specialTeamType = SystemTeam.Everyone; + break; + case 'openAccess': + specialTeamType = SystemTeam.OpenAccess; break; case 'systemAdmin': - specialTeamType = SpecialTeam.SystemAdmin; + specialTeamType = SystemTeam.SystemAdmin; break; case 'systemWrite': - specialTeamType = SpecialTeam.SystemWrite; + specialTeamType = SystemTeam.SystemWrite; break; case 'systemRead': - specialTeamType = SpecialTeam.SystemRead; + specialTeamType = SystemTeam.SystemRead; break; case 'sudo': - specialTeamType = SpecialTeam.Sudo; + specialTeamType = SystemTeam.Sudo; break; // case 'globalSudo': // specialTeamType = SpecialTeam.GlobalSudo; @@ -375,7 +363,7 @@ router.post( router.get( '/:appId/installations/:installationId', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const githubApplication = req['githubApplication'] as GitHubApplication; const providers = getProviders(req); const individualContext = req.individualContext; diff --git a/routes/administration/apps.ts b/routes/administration/apps.ts index bec5cb2bc..8221d430d 100644 --- a/routes/administration/apps.ts +++ b/routes/administration/apps.ts @@ -3,39 +3,22 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../transitional'; -import { sortByCaseInsensitive } from '../../utils'; +import { getProviders } from '../../lib/transitional'; +import { sortByCaseInsensitive } from '../../lib/utils'; import GitHubApplication from '../../business/application'; -import { OrganizationSetting } from '../../entities/organizationSettings/organizationSetting'; import { ReposAppRequest, UserAlertType } from '../../interfaces'; - -interface IByOrgViewAppInstallation { - app: GitHubApplication; - installationId?: number; -} - -enum OrgStatus { - Active = 'Active', - Adopted = 'Adopted', - NotAdopted = 'NotAdopted', -} - -interface IByOrgView { - organizationName: string; - status: OrgStatus; - appInstallations: Map; - dynamicSettings: OrganizationSetting; - configuredInstallations: number[]; - id?: number; -} +import { + ManagedOrganizationAppConfigurationsByOrgView, + ManagedOrganizationStatus, +} from '../../api/client/context/administration/types'; router.post( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const providers = getProviders(req); const { deletesettingsorgname } = req.body; if (!deletesettingsorgname) { @@ -69,20 +52,20 @@ router.post( router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const providers = getProviders(req); const operations = providers.operations; const apps = providers.operations.getApplications(); const individualContext = req.individualContext; const organizationSettingsProvider = providers.organizationSettingsProvider; - const byOrg = new Map(); + const byOrg = new Map(); function getOrg(name: string) { let o = byOrg.get(name); if (!o) { o = { organizationName: name, id: undefined, - status: OrgStatus.NotAdopted, + status: ManagedOrganizationStatus.NotAdopted, appInstallations: new Map(), dynamicSettings: null, configuredInstallations: [], @@ -96,19 +79,19 @@ router.get( } for (const app of apps) { const appInstalls = await app.getInstallations({ maxAgeSeconds: 5 }); - const { valid } = GitHubApplication.filterInstallations(appInstalls); - for (const vi of valid) { - const organizationName = vi.account.login; + const { valid: validInstallations } = GitHubApplication.filterInstallations(appInstalls); + for (const valid of validInstallations) { + const organizationName = valid.account.login; const o = getOrg(organizationName.toLowerCase()); o.appInstallations.set(app.id, { app, - installationId: vi.id, + installationId: valid.id, }); - o.id = Number(vi.target_id); - if (!o.dynamicSettings && vi.target_type === 'Organization') { + o.id = Number(valid.target_id); + if (!o.dynamicSettings && valid.target_type === 'Organization') { try { o.dynamicSettings = await organizationSettingsProvider.getOrganizationSetting( - vi.target_id.toString() + valid.target_id.toString() ); } catch (ignore) { /* ignored */ @@ -117,10 +100,10 @@ router.get( o.configuredInstallations = o.dynamicSettings.installations.map( (install) => install.installationId ); - o.status = OrgStatus.Adopted; + o.status = ManagedOrganizationStatus.Adopted; } if (o.dynamicSettings && o.dynamicSettings.active === true) { - o.status = OrgStatus.Active; + o.status = ManagedOrganizationStatus.Active; } } } diff --git a/routes/administration/index.ts b/routes/administration/index.ts index 7fcc6c437..605915110 100644 --- a/routes/administration/index.ts +++ b/routes/administration/index.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import getCompanySpecificDeployment from '../../middleware/companySpecificDeployment'; @@ -20,7 +20,7 @@ import _ from 'lodash'; router.use( '*', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const { corporateAdministrationProfile } = getProviders(req); if (corporateAdministrationProfile && corporateAdministrationProfile.urls) { req.individualContext.setInitialViewProperty('_corpAdminUrls', corporateAdministrationProfile.urls); @@ -41,7 +41,7 @@ try { router.use('/app', RouteApp); router.use('/apps', RouteApps); -router.get('/', (req: ReposAppRequest, res, next) => { +router.get('/', (req: ReposAppRequest, res: Response, next: NextFunction) => { const individualContext = req.individualContext; individualContext.webContext.render({ view: 'administration', diff --git a/routes/approvals.ts b/routes/approvals.ts index d00d69b50..15ea37dcf 100644 --- a/routes/approvals.ts +++ b/routes/approvals.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); router.get('/', (req, res) => { diff --git a/routes/diagnostics.ts b/routes/diagnostics.ts index 9ae9392aa..b3e09342b 100644 --- a/routes/diagnostics.ts +++ b/routes/diagnostics.ts @@ -4,10 +4,11 @@ // import { Request, Router } from 'express'; +import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { IAppSession, ReposAppRequest } from '../interfaces'; -import { getProviders } from '../transitional'; +import { CreateError, getProviders } from '../lib/transitional'; const redacted = '*****'; @@ -96,4 +97,15 @@ router.get('/', (req: IRequestWithSession, res) => { }); }); +router.get( + '/advanced', + asyncHandler(async (req: ReposAppRequest, res, next) => { + if (req.user?.azure?.oid !== 'b9f9877e-1cae-445e-bc28-3c943078c8e7') { + return next(CreateError.NotAuthorized('You are not authorized to view this page.')); + } + const obj: any = Object.assign({}, process.env); + return res.json(obj) as unknown as void; + }) +); + export default router; diff --git a/routes/explore.ts b/routes/explore.ts index b912b71cb..efeee696f 100644 --- a/routes/explore.ts +++ b/routes/explore.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../interfaces'; -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; router.get('/', (req: ReposAppRequest, res) => { const config = getProviders(req).config; diff --git a/routes/index-authenticated.ts b/routes/index-authenticated.ts index 688be52f5..a5ee54b79 100644 --- a/routes/index-authenticated.ts +++ b/routes/index-authenticated.ts @@ -5,11 +5,11 @@ import _ from 'lodash'; -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { hasStaticReactClientApp, getProviders } from '../transitional'; +import { hasStaticReactClientApp, getProviders } from '../lib/transitional'; import { Organization } from '../business/organization'; @@ -27,15 +27,17 @@ import linkRoute from './link'; import linkedUserRoute from './index-linked'; import linkCleanupRoute from './link-cleanup'; -import SettingsRoute from './settings'; +import routeSettings from './settings'; import getCompanySpecificDeployment from '../middleware/companySpecificDeployment'; const hasReactApp = hasStaticReactClientApp(); const reactRoute = hasReactApp ? injectReactClient() : undefined; -import RoutePlaceholders from './placeholders'; -import RouteReleasesSpa from './releasesSpa'; +import routePlaceholders from './placeholders'; +import routeReleasesSpa from './releasesSpa'; + import { ReposAppRequest, UserAlertType } from '../interfaces'; +import { Repository } from '../business'; // - - - Middleware: require that they have a passport - - - router.use(asyncHandler(requireAuthenticatedUserOrSignIn)); @@ -48,10 +50,10 @@ router.use(asyncHandler(AddLinkToRequest)); router.use(asyncHandler(blockEnterpriseManagedUsersAuthentication)); -router.use('/placeholder', RoutePlaceholders); +router.use('/placeholder', routePlaceholders); router.use('/link/cleanup', reactRoute || linkCleanupRoute); router.use('/link', reactRoute || linkRoute); -router.use('/releases', reactRoute || RouteReleasesSpa); +router.use('/releases', reactRoute || routeReleasesSpa); if (reactRoute) { // client-only routes @@ -67,9 +69,9 @@ const dynamicStartupInstance = getCompanySpecificDeployment(); dynamicStartupInstance?.routes?.connectAuthenticatedRoutes && dynamicStartupInstance.routes.connectAuthenticatedRoutes(router, reactRoute); -router.use('/settings', SettingsRoute); +router.use('/settings', reactRoute || routeSettings); -router.get('/news', (req: ReposAppRequest, res, next) => { +router.get('/news', (req: ReposAppRequest, res: Response, next: NextFunction) => { const config = getProviders(req).config; if (config && config.news && config.news.all && config.news.all.length) { return req.individualContext.webContext.render({ @@ -81,6 +83,40 @@ router.get('/news', (req: ReposAppRequest, res, next) => { } }); +router.use( + '/', + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { + // Helper method to allow pasting a GitHub URL into the app to go to a repo + const { rid, oid, action } = req.query; + const { operations } = getProviders(req); + if (!rid && !oid) { + return next(); + } + const repositoryId = Number(rid); + const organizationId = Number(oid); + let organization: Organization = null; + let repository: Repository = null; + try { + organization = operations.getOrganizationById(organizationId); + } catch (error) { + // no-op continue + return next(); + } + if (organization) { + try { + repository = await organization.getRepositoryById(repositoryId); + return res.redirect( + `/orgs/${organization.name}/repos/${repository.name}${action ? `/${action}` : ''}` + ); + } catch (error) { + // no-op continue + return next(); + } + } + return next(); + }) +); + // Link cleanups and check their signed-in username vs their link router.use(RequireLinkMatchesGitHubSessionExceptPrefixedRoute('/unlink')); @@ -88,7 +124,7 @@ router.use(RequireLinkMatchesGitHubSessionExceptPrefixedRoute('/unlink')); router.get( '/', reactRoute || - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const onboarding = req.query.onboarding !== undefined; const individualContext = req.individualContext; const link = individualContext.link; diff --git a/routes/index-linked.ts b/routes/index-linked.ts index fef788ced..5c064e058 100644 --- a/routes/index-linked.ts +++ b/routes/index-linked.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { CreateError, hasStaticReactClientApp, getProviders } from '../transitional'; +import { CreateError, hasStaticReactClientApp, getProviders } from '../lib/transitional'; import { IndividualContext } from '../business/user'; -import { storeOriginalUrlAsVariable } from '../utils'; +import { storeOriginalUrlAsVariable } from '../lib/utils'; import { AuthorizeOnlyCorporateAdministrators } from '../middleware/business/corporateAdministrators'; import RouteAdministration from './administration'; @@ -38,7 +38,7 @@ const reactRoute = hasReactApp ? injectReactClient() : undefined; // * only for the traditional app. The React app does not require a link to browse orgs. //----------------------------------------------------------------------------- if (!hasReactApp) { - router.use(function (req: ReposAppRequest, res, next) { + router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { const individualContext = req.individualContext as IndividualContext; const link = individualContext.link; if (link && link.thirdPartyId) { @@ -65,7 +65,7 @@ router.use('/administration', asyncHandler(AuthorizeOnlyCorporateAdministrators) router.use( '/https?*github.com/:org/:repo', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { // Helper method to allow pasting a GitHub URL into the app to go to a repo const { org, repo } = req.params; const { operations } = getProviders(req); diff --git a/routes/index.ts b/routes/index.ts index 84d7d2fd0..16cc579aa 100644 --- a/routes/index.ts +++ b/routes/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import { webContextMiddleware } from '../middleware/business/setContext'; @@ -16,7 +16,7 @@ import ExploreRoute from './explore'; import ApprovalsRoute from './approvals'; import AuthenticatedRoute from './index-authenticated'; -import { hasStaticReactClientApp } from '../transitional'; +import { hasStaticReactClientApp } from '../lib/transitional'; import { injectReactClient } from '../middleware'; router.use('/api/client', clientApiRoute); diff --git a/routes/link-cleanup.ts b/routes/link-cleanup.ts index ff7156a32..d8ba92b7e 100644 --- a/routes/link-cleanup.ts +++ b/routes/link-cleanup.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../interfaces'; @@ -17,7 +17,7 @@ import { ReposAppRequest } from '../interfaces'; // linksForCleanup?: any; // } -router.use((req: ReposAppRequest, res, next) => { +router.use((req: ReposAppRequest, res: Response, next: NextFunction) => { // TODO: revisit implementation return next(); @@ -104,7 +104,7 @@ router.use((req: ReposAppRequest, res, next) => { // renderCleanupPage(req, res, null, null); // }); -// router.post('/', (req: IRequestWithSessionPlus, res, next) => { +// router.post('/', (req: IRequestWithSessionPlus, res: Response, next: NextFunction) => { // let action = 'unlink'; // let id = req.body.unlink; // if (!req.body.unlink && req.session && req.session.enableMultipleAccounts === true && req.body.select) { diff --git a/routes/link.ts b/routes/link.ts index 312325395..eab59a277 100644 --- a/routes/link.ts +++ b/routes/link.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); @@ -14,9 +14,9 @@ import { ICorporateLink, LinkOperationSource, } from '../interfaces'; -import { getProviders, splitSemiColonCommas } from '../transitional'; +import { getProviders, splitSemiColonCommas } from '../lib/transitional'; import { IndividualContext } from '../business/user'; -import { isCodespacesAuthenticating, storeOriginalUrlAsReferrer, wrapError } from '../utils'; +import { isCodespacesAuthenticating, storeOriginalUrlAsReferrer, wrapError } from '../lib/utils'; import validator from 'validator'; @@ -31,7 +31,7 @@ interface IRequestHacked extends ReposAppRequest { overrideLinkUserPrincipalName?: any; } -router.use((req: IRequestHacked, res, next) => { +router.use((req: IRequestHacked, res: Response, next: NextFunction) => { const config = getProviders(req).config; if ( config && @@ -50,7 +50,7 @@ router.use((req: IRequestHacked, res, next) => { router.use( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { // Make sure both account types are authenticated before showing the link pg [wi 12690] const individualContext = req.individualContext; if (!individualContext.corporateIdentity || !individualContext.getGitHubIdentity()) { @@ -64,7 +64,7 @@ router.use( // TODO: graph provider non-guest check should be middleware and in the link business process router.use( - asyncHandler(async (req: IRequestHacked, res, next) => { + asyncHandler(async (req: IRequestHacked, res: Response, next: NextFunction) => { const individualContext = req.individualContext as IndividualContext; const providers = getProviders(req); const insights = providers.insights; @@ -155,7 +155,7 @@ router.use( router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const { config } = getProviders(req); const individualContext = req.individualContext; const link = individualContext.link; @@ -233,7 +233,7 @@ router.get('/enableMultipleAccounts', function (req: IRequestWithSession, res) { router.post( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const individualContext = req.individualContext as IndividualContext; try { await interactiveLinkUser(false, individualContext, req, res, next); @@ -291,7 +291,7 @@ export async function interactiveLinkUser( router.use('/remove', unlinkRoute); -router.get('/reconnect', function (req: ReposAppRequest, res, next) { +router.get('/reconnect', function (req: ReposAppRequest, res: Response, next: NextFunction) { const config = getProviders(req).config; if (config.authentication.scheme !== 'aad') { return next( diff --git a/routes/org/2fa.ts b/routes/org/2fa.ts index aa1fd3a7a..b4b1b8ac9 100644 --- a/routes/org/2fa.ts +++ b/routes/org/2fa.ts @@ -3,18 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import moment from 'moment'; import { NoCacheNoBackground, ReposAppRequest } from '../../interfaces'; -import { wrapError } from '../../utils'; +import { wrapError } from '../../lib/utils'; router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const organization = req.organization; const onboarding = req.query.onboarding; const joining = req.query.joining; diff --git a/routes/org/index.ts b/routes/org/index.ts index 28281c3b1..d66f45efb 100644 --- a/routes/org/index.ts +++ b/routes/org/index.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import express, { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { IAggregateUserSummary } from '../../business/user/aggregate'; -import { TeamJoinApprovalEntity } from '../../entities/teamJoinApproval/teamJoinApproval'; +import { TeamJoinApprovalEntity } from '../../business/entities/teamJoinApproval/teamJoinApproval'; import { Team } from '../../business'; import { ReposAppRequest, OrganizationMembershipState } from '../../interfaces'; import { @@ -31,7 +31,7 @@ interface ILocalOrgRequest extends ReposAppRequest { orgPermissions?: IRequestOrganizationPermissions; } -router.use(function (req: ReposAppRequest, res, next) { +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { const onboarding = req.query.onboarding; const organization = req.organization; req.individualContext.webContext.pushBreadcrumb(organization.name, onboarding ? false : undefined); @@ -43,7 +43,7 @@ router.use(function (req: ReposAppRequest, res, next) { }); // Campaign-related redirect to take the user to GitHub -router.get('/', (req: ReposAppRequest, res, next) => { +router.get('/', (req: ReposAppRequest, res: Response, next: NextFunction) => { const providers = getProviders(req); if (!providers || !providers.campaign) { return next(); @@ -63,7 +63,7 @@ router.use('/teams', RouteTeams); router.use(asyncHandler(AddOrganizationPermissionsToRequest)); router.use( - asyncHandler(async (req: ILocalOrgRequest, res, next) => { + asyncHandler(async (req: ILocalOrgRequest, res: Response, next: NextFunction) => { const organization = req.organization; const orgPermissions = req.orgPermissions; if (!orgPermissions) { @@ -90,7 +90,7 @@ router.use( router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const providers = getProviders(req); const approvalProvider = providers.approvalProvider; const organization = req.organization; @@ -107,9 +107,8 @@ router.get( pendingApprovals: null as TeamJoinApprovalEntity[], organizationAdmins, }; - results.organizationOverview = await individualContext.aggregations.getAggregatedOrganizationOverview( - organization - ); + results.organizationOverview = + await individualContext.aggregations.getAggregatedOrganizationOverview(organization); // Check for pending approvals const teamsMaintained = results.organizationOverview.teams.maintainer as Team[]; if (teamsMaintained && teamsMaintained.length && teamsMaintained.length > 0) { @@ -147,7 +146,7 @@ router.use('/wizard', RouteNewRepoSpa); router.use( '/:repoName', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const repoName = req.params.repoName; const organization = req.organization; const attemptedRepository = organization.repository(repoName); diff --git a/routes/org/join.ts b/routes/org/join.ts index 30c4435d8..c136320ea 100644 --- a/routes/org/join.ts +++ b/routes/org/join.ts @@ -10,9 +10,10 @@ import asyncHandler from 'express-async-handler'; const router: Router = Router(); import querystring from 'querystring'; -import { CreateError, getProviders } from '../../transitional'; + +import { CreateError, getProviders } from '../../lib/transitional'; import { IndividualContext } from '../../business/user'; -import { sleep, storeOriginalUrlAsReferrer, wrapError } from '../../utils'; +import { sleep, storeOriginalUrlAsReferrer, wrapError } from '../../lib/utils'; import RequireActiveGitHubSession from '../../middleware/github/requireActiveSession'; import { jsonError } from '../../middleware/jsonError'; import { Organization, Team } from '../../business'; @@ -31,8 +32,8 @@ import getCompanySpecificDeployment from '../../middleware/companySpecificDeploy //------------- // Join checks //------------- -router.use(function (req: ReposAppRequest, res, next) { - const { organization } = req; +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { + const organization = req.organization; let err = null; if (organization.locked) { diff --git a/routes/org/leave.ts b/routes/org/leave.ts index 2ee5b6cff..60b3b654f 100644 --- a/routes/org/leave.ts +++ b/routes/org/leave.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../transitional'; -import { wrapError } from '../../utils'; +import { getProviders } from '../../lib/transitional'; +import { wrapError } from '../../lib/utils'; import { Organization } from '../../business'; import { OrganizationMembershipState, ReposAppRequest, UserAlertType } from '../../interfaces'; @@ -25,7 +25,7 @@ interface ILocalLeaveRequest extends ReposAppRequest { } router.use( - asyncHandler(async (req: ILocalLeaveRequest, res, next) => { + asyncHandler(async (req: ILocalLeaveRequest, res: Response, next: NextFunction) => { const organization = req.organization as Organization; req.orgLeave = { state: null, @@ -58,7 +58,7 @@ router.get('/', function (req: ILocalLeaveRequest, res) { router.post( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const organization = req.organization; const providers = getProviders(req); const operations = providers.operations; diff --git a/routes/org/membership.ts b/routes/org/membership.ts index 1e5614ce6..1ab72ab62 100644 --- a/routes/org/membership.ts +++ b/routes/org/membership.ts @@ -3,18 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; import { ReposAppRequest, UserAlertType } from '../../interfaces'; -import { wrapError } from '../../utils'; +import { wrapError } from '../../lib/utils'; import RequireActiveGitHubSession from '../../middleware/github/requireActiveSession'; const router: Router = Router(); router.get( '/', RequireActiveGitHubSession, - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const organization = req.organization; if (!organization) { // TODO: Was this ever a possible situation? What's going on here? Probably was v1 (single-org) @@ -56,7 +56,7 @@ router.get( router.post( '/', RequireActiveGitHubSession, - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const username = req.individualContext.getGitHubIdentity().username; const organization = req.organization; if (!organization) { diff --git a/routes/org/newRepoSpa.ts b/routes/org/newRepoSpa.ts index 3adafdcb5..715c45aa5 100644 --- a/routes/org/newRepoSpa.ts +++ b/routes/org/newRepoSpa.ts @@ -3,14 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { getRepositoryMetadataProvider, ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { Organization } from '../../business/organization'; -import NewRepositoryLockdownSystem from '../../features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../../business/features/newRepositories/newRepositoryLockdown'; router.get( '/', diff --git a/routes/org/people.ts b/routes/org/people.ts index 5fefb4fba..ceabce61c 100644 --- a/routes/org/people.ts +++ b/routes/org/people.ts @@ -3,14 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../../interfaces'; import RoutePeopleSearch from '../peopleSearch'; -router.use(function (req: ReposAppRequest, res, next) { +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { req.individualContext.webContext.pushBreadcrumb('People'); req.reposContext = { section: 'people', diff --git a/routes/org/profileReview.ts b/routes/org/profileReview.ts index 0faf21174..ab65d191f 100644 --- a/routes/org/profileReview.ts +++ b/routes/org/profileReview.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import asyncHandler from 'express-async-handler'; import { ReposAppRequest } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; interface IUserProfileWarnings { company?: string; @@ -17,7 +17,7 @@ interface IUserProfileWarnings { router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const organization = req.organization; const { operations } = getProviders(req); const config = operations.config; diff --git a/routes/org/repoAdministrativeLock.ts b/routes/org/repoAdministrativeLock.ts index 94323057d..a0dcd5d5e 100644 --- a/routes/org/repoAdministrativeLock.ts +++ b/routes/org/repoAdministrativeLock.ts @@ -4,19 +4,19 @@ // import asyncHandler from 'express-async-handler'; -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { Repository } from '../../business/repository'; -import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; +import { RepositoryMetadataEntity } from '../../business/entities/repositoryMetadata/repositoryMetadata'; import { Organization } from '../../business/organization'; -import NewRepositoryLockdownSystem from '../../features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../../business/features/newRepositories/newRepositoryLockdown'; import { getRepositoryMetadataProvider, ReposAppRequest, UserAlertType } from '../../interfaces'; router.use( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const organization = req.organization as Organization; if (!organization.isNewRepositoryLockdownSystemEnabled()) { return next(new Error('This endpoint is not available as configured')); @@ -27,7 +27,7 @@ router.use( router.use( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const individualContext = req.individualContext; const isPortalAdministrator = await individualContext.isPortalAdministrator(); if (!isPortalAdministrator) { @@ -42,7 +42,7 @@ router.use( router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const repository = req['repository'] as Repository; const repositoryMetadata = req['repositoryMetadata'] as RepositoryMetadataEntity; return renderPage(req, repositoryMetadata, repository); @@ -51,9 +51,9 @@ router.get( router.post( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const providers = getProviders(req); - const operations = providers.operations; + const { insights, operations } = providers; const repository = req['repository'] as Repository; const entity = repository.getEntity(); if (!entity.parent) { @@ -68,6 +68,7 @@ router.post( const repositoryMetadataProvider = getRepositoryMetadataProvider(operations); const organization = repository.organization; const lockdownSystem = new NewRepositoryLockdownSystem({ + insights, operations, organization, repository, diff --git a/routes/org/repoWorkflowEngine.ts b/routes/org/repoWorkflowEngine.ts index e1979b26c..4a79b069d 100644 --- a/routes/org/repoWorkflowEngine.ts +++ b/routes/org/repoWorkflowEngine.ts @@ -3,13 +3,14 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; import fs from 'fs'; import path from 'path'; import recursiveReadDirectory from 'recursive-readdir'; -import { wrapError, sleep } from '../../utils'; +import { wrapError, sleep } from '../../lib/utils'; import { Organization } from '../../business'; -import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; +import { RepositoryMetadataEntity } from '../../business/entities/repositoryMetadata/repositoryMetadata'; import { Repository } from '../../business'; import { CreateRepositoryEntrypoint, ICreateRepositoryApiResult } from '../../api/createRepo'; import { @@ -20,13 +21,14 @@ import { IAlternateTokenOption, IOperationsRepositoryMetadataProvider, IProviders, + IReposAppWithTeam, throwIfNotCapable, } from '../../interfaces'; -import { ErrorHelper } from '../../transitional'; +import { ErrorHelper } from '../../lib/transitional'; import { setupRepositoryReadmeSubstring, setupRepositorySubstring, -} from '../../features/newRepositories/strings'; +} from '../../business/features/newRepositories/strings'; export interface IApprovalPackage { id: string; @@ -83,7 +85,11 @@ export class RepoWorkflowEngine { private log: IRepositoryWorkflowOutput[] = []; private repository: Repository; - constructor(private providers: IProviders, organization: Organization, approvalPackage: IApprovalPackage) { + constructor( + private providers: IProviders, + organization: Organization, + approvalPackage: IApprovalPackage + ) { this.request = approvalPackage.repositoryMetadata; // this.user = approvalPackage.requestingUser; this.id = approvalPackage.id; @@ -185,7 +191,7 @@ export class RepoWorkflowEngine { }); } - editPost(req, res, next) { + editPost(req: IReposAppWithTeam, res: Response, next: NextFunction) { const { operations } = this.providers; const ops = throwIfNotCapable( operations, diff --git a/routes/org/repos.ts b/routes/org/repos.ts index 33b06df44..c3560ffff 100644 --- a/routes/org/repos.ts +++ b/routes/org/repos.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); @@ -13,13 +13,13 @@ import moment from 'moment'; import lowercaser from '../../middleware/lowercaser'; import routeAdministrativeLock from './repoAdministrativeLock'; -import NewRepositoryLockdownSystem from '../../features/newRepositories/newRepositoryLockdown'; +import NewRepositoryLockdownSystem from '../../business/features/newRepositories/newRepositoryLockdown'; import { IGraphEntry } from '../../lib/graphProvider'; import { IMail } from '../../lib/mailProvider'; import { IndividualContext } from '../../business/user'; import { Repository, Collaborator, TeamPermission, Organization, OrganizationMember } from '../../business'; -import { RepositoryMetadataEntity } from '../../entities/repositoryMetadata/repositoryMetadata'; +import { RepositoryMetadataEntity } from '../../business/entities/repositoryMetadata/repositoryMetadata'; import { ReposAppRequest, GitHubCollaboratorAffiliationQuery, @@ -35,7 +35,7 @@ import { getContextualRepositoryPermissions, IContextualRepositoryPermissions, } from '../../middleware/github/repoPermissions'; -import { getProviders, CreateError, ErrorHelper } from '../../transitional'; +import { getProviders, CreateError, ErrorHelper } from '../../lib/transitional'; import RouteReposPager from '../reposPager'; @@ -60,7 +60,7 @@ const teamsFilterType = { systemTeamsOnly: 'systemTeamsOnly', }; -router.use(function (req: ReposAppRequest, res, next) { +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { req.individualContext.webContext.pushBreadcrumb('Repositories'); req.reposContext = { section: 'repos', @@ -85,10 +85,10 @@ function sliceCollaboratorsForView(collaborators) { const destination = permission.admin ? collabView.administrators : permission.push - ? collabView.writers - : permission.pull - ? collabView.readers - : null; + ? collabView.writers + : permission.pull + ? collabView.readers + : null; if (destination) { destination.push(collab); } @@ -160,7 +160,7 @@ export async function findRepoCollaboratorsExcludingOwners( router.use( '/:repoName', - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { const repoName = req.params.repoName; const organization = req.organization; const repository = organization.repository(repoName); @@ -175,7 +175,7 @@ router.use('/:repoName/administrativeLock', routeAdministrativeLock); router.use( '/:repoName/delete', - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { const individualContext = req.individualContext; const repository = req.repository; const organization = req.organization; @@ -205,7 +205,7 @@ router.use( router.get( '/:repoName/delete', - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { return req.individualContext.webContext.render({ title: 'Delete the repo you created', view: 'repos/delete', @@ -218,13 +218,14 @@ router.get( router.post( '/:repoName/delete', - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { // NOTE: this code is also duplicated for now in the client/internal/* folder // CONSIDER: de-duplicate - const { operations } = getProviders(req); + const { insights, operations } = getProviders(req); const { organization, repository } = req; const repositoryMetadataProvider = getRepositoryMetadataProvider(operations); const lockdownSystem = new NewRepositoryLockdownSystem({ + insights, operations, organization, repository, @@ -249,121 +250,34 @@ export interface IRenameOutput { } router.post( - '/:repoName/defaultBranch', + '/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: ILocalRequest, res, next) { - try { - const targetBranchName = req.body.targetBranchName || 'main'; - const providers = getProviders(req); - const activeContext = (req.individualContext || req.apiContext) as IndividualContext; - const repoPermissions = getContextualRepositoryPermissions(req); - const repository = req.repository as Repository; - const outcome = await renameRepositoryDefaultBranchEndToEnd( - providers, - activeContext, - repoPermissions, - repository, - targetBranchName, - false - ); - req.individualContext.webContext.render({ - view: 'repos/repoBranchRenamed', - title: outcome.message, - state: { - output: outcome.output, - repository, - }, - }); - } catch (error) { - return next(error); + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { + const repoPermissions = req.repoPermissions; + if (!repoPermissions.allowAdministration) { + return next(new Error('You do not have administrative permission on this repository')); } + // only supporting the 'take public' operation now + const takePublic = req.body['make-repo-public']; + if (!takePublic) { + return next(new Error('Unsupported operation')); + } + const repository = req.repository as Repository; + await repository.editPublicPrivate({ private: false }); + req.individualContext.webContext.saveUserAlert( + `${repository.full_name} is now public.`, + 'Repository publish', + UserAlertType.Success + ); + await repository.getDetails(NoCacheNoBackground); + return res.redirect(`/${repository.organization.name}/repos/${repository.name}?published`); }) ); -export async function renameRepositoryDefaultBranchEndToEnd( - providers: IProviders, - activeContext: IndividualContext, - repoPermissions: IContextualRepositoryPermissions, - repository: Repository, - targetBranchName: string, - waitForRefresh: boolean -): Promise { - const corporateUsername = activeContext.corporateIdentity.username; - if (!corporateUsername) { - throw CreateError.InvalidParameters('no corporate username in the session'); - } - if (!targetBranchName) { - throw CreateError.InvalidParameters('invalid target branch name'); - } - if (!repoPermissions) { - throw CreateError.InvalidParameters('no repo permissions'); - } - if (!repoPermissions.allowAdministration) { - throw CreateError.NotAuthorized('You do not have administrative permission on this repository'); - } - await repository.getDetails(); - function finishUp(): Promise { - return new Promise((resolve) => { - triggerRenameNotification(providers, repository, corporateUsername, targetBranchName, output) - .then((ok) => { - /* ignore */ - }) - .catch((error) => { - console.error(`Notify rename trigger: ${error}`); - }); - repository - .getDetails(NoCacheNoBackground) - .then((ok) => { - return resolve(); - }) - .catch((error) => { - console.error(`Background refresh error: ${error}`); - return resolve(); - }); - }); - } - const output = await repository.renameDefaultBranch(targetBranchName); - if (waitForRefresh) { - await finishUp(); - } else { - process.nextTick(() => { - finishUp() - .then((ok) => { - /* ignore */ - }) - .catch((error) => { - /* ignore */ - }); - }); - } - return { - message: `Branch renamed to ${targetBranchName} for ${repository.name}`, - output, - }; -} - -// Disabling this function as it is high risk: uses GHEC enterprise admin PAT and makes repo public outside of Org owner involvement -// router.post('/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), asyncHandler(async function (req: ILocalRequest, res, next) { -// const repoPermissions = req.repoPermissions; -// if (!repoPermissions.allowAdministration) { -// return next(new Error('You do not have administrative permission on this repository')); -// } -// // only supporting the 'take public' operation now -// const takePublic = req.body['make-repo-public']; -// if (!takePublic) { -// return next(new Error('Unsupported operation')); -// } -// const repository = req.repository as Repository; -// await repository.editPublicPrivate({ private: false }); -// req.individualContext.webContext.saveUserAlert(`${repository.full_name} is now public.`, 'Repository publish', UserAlertType.Success); -// await repository.getDetails(NoCacheNoBackground); -// return res.redirect(`/${repository.organization.name}/repos/${repository.name}?published`); -// })); - router.get( '/:repoName', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { const { linkProvider, config, graphProvider } = getProviders(req); const repoPermissions = req.repoPermissions; const referer = req.headers.referer as string; @@ -465,38 +379,6 @@ router.get( }) ); -router.get( - '/:repoName/defaultBranch', - asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: ILocalRequest, res, next) { - const referer = req.headers.referer as string; - const fromReposPage = referer && (referer.endsWith('repos') || referer.endsWith('repos/')); - const organization = req.organization; - const repoPermissions = req.repoPermissions; - const repository = req.repository; - const repositoryMetadataEntity = req.repositoryMetadata; - await repository.getDetails(); - const title = `${repository.name} - Default Branch Name`; - const details = await repository.organization.getDetails(); - const organizationSupportsUpdatesApp = await organization.supportsUpdatesApp(); - organization.id = details.id; - req.individualContext.webContext.render({ - view: 'repos/defaultBranch', - title, - state: { - organization, - organizationSupportsUpdatesApp, - repo: decorateRepoForView(repository), - reposSubView: 'defaultBranch', - repository, - fromReposPage, - repoPermissions, - repositoryMetadataEntity, - }, - }); - }) -); - export interface IRepositoryPermissionsView {} export async function calculateGroupedPermissionsViewForRepository(repository: Repository): Promise { @@ -506,7 +388,7 @@ export async function calculateGroupedPermissionsViewForRepository(repository: R collaborators, // Collaborator[] outsideCollaborators, // Collaborator[] } = await calculateRepoPermissions(organization, repository); - const systemTeams = combineAllTeams(organization.specialRepositoryPermissionTeams); // number[] + const systemTeams = combineAllTeams(organization.specialSystemTeams); // number[] const teamBasedPermissions = consolidateTeamPermissions(permissions, systemTeams); // busted? const groupedPermissions = slicePermissionsForView( filterSystemTeams(teamsFilterType.systemTeamsExcluded, systemTeams, permissions) @@ -549,7 +431,7 @@ export async function calculateGroupedPermissionsViewForRepository(repository: R router.get( '/:repoName/permissions', asyncHandler(AddRepositoryPermissionsToRequest), - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { const referer = req.headers.referer as string; const fromReposPage = referer && (referer.endsWith('repos') || referer.endsWith('repos/')); const organization = req.organization; @@ -563,7 +445,7 @@ router.get( organization, repository ); - const systemTeams = combineAllTeams(organization.specialRepositoryPermissionTeams); + const systemTeams = combineAllTeams(organization.specialSystemTeams); const teamBasedPermissions = consolidateTeamPermissions(permissions, systemTeams); const title = `${repository.name} - Repository`; const details = await repository.organization.getDetails(); @@ -599,7 +481,7 @@ router.get( router.get( '/:repoName/history', - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { const { auditLogRecordProvider } = getProviders(req); const referer = req.headers.referer as string; const fromReposPage = referer && (referer.endsWith('repos') || referer.endsWith('repos/')); @@ -754,7 +636,7 @@ function teamsToSet(teams) { return set; } -// function requireAdministration(req, res, next) { +// function requireAdministration(req, res: Response, next: NextFunction) { // const repoPermissions = req.repoPermissions; // if (!repoPermissions) { // return next(new Error('Not configured for repo permissions')); @@ -765,55 +647,4 @@ function teamsToSet(teams) { // return next(new Error('You are not authorized to administer this repository.')); // } -async function triggerRenameNotification( - providers: IProviders, - repository: Repository, - corporateUsername: string, - targetBranchName: string, - output: ITemporaryCommandOutput[] -): Promise { - const { config, insights, operations, mailAddressProvider, viewServices } = providers; - insights.trackMetric({ name: 'RenameDefaultBranches', value: 1 }); - insights.trackEvent({ - name: 'RenameDefaultBranch', - properties: { - orgName: repository.organization.name, - repoName: repository.name, - targetBranchName, - }, - }); - const mailAddress = await mailAddressProvider.getAddressFromUpn(corporateUsername); - const emailTemplate = 'repoDefaultBranchRenamed'; - const mail: IMail = { - to: [mailAddress], - cc: [operations.getInfrastructureNotificationsMail()], - subject: `${repository.organization.name}/${repository.name} default branch is now ${targetBranchName}`, - content: undefined, - }; - const contentOptions = { - reason: `You are receiving this e-mail as a transaction record from your action to rename the default branch of this repository you administer.`, - headline: `${targetBranchName} branch`, - notification: 'information', - app: config.brand?.companyName ? `${config.brand.companyName} GitHub` : 'GitHub', - output, - repository, - organization: repository.organization, - viewServices, - }; - try { - mail.content = await operations.emailRender(emailTemplate, contentOptions); - await operations.sendMail(mail); - } catch (mailError) { - console.warn(mailError); - insights.trackException({ - exception: mailError, - properties: { - repositoryName: repository.full_name, - organizationName: repository.organization.name, - eventName: 'SendRenameDefaultBranchMail', - }, - }); - } -} - export default router; diff --git a/routes/org/team/approval/index.ts b/routes/org/team/approval/index.ts index ffe17b298..33e06c147 100644 --- a/routes/org/team/approval/index.ts +++ b/routes/org/team/approval/index.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { ErrorHelper, getProviders } from '../../../../transitional'; +import { ErrorHelper, getProviders } from '../../../../lib/transitional'; import { Team } from '../../../../business'; import { PermissionWorkflowEngine } from '../approvals'; import RenderHtmlMail from '../../../../lib/emailRender'; @@ -62,7 +62,7 @@ router.get('/setNote/:action', function (req: ILocalRequest, res) { router.post( '/', - asyncHandler(async (req: ILocalRequest, res, next) => { + asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { const providers = getProviders(req); const { individualContext } = req; const engine = req.approvalEngine as PermissionWorkflowEngine; diff --git a/routes/org/team/approvals.ts b/routes/org/team/approvals.ts index 88108ed18..7420ee162 100644 --- a/routes/org/team/approvals.ts +++ b/routes/org/team/approvals.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import RouteApproval from './approval'; -import { getProviders } from '../../../transitional'; -import { wrapError } from '../../../utils'; +import { getProviders } from '../../../lib/transitional'; +import { wrapError } from '../../../lib/utils'; import { Team } from '../../../business'; -import { TeamJoinApprovalEntity } from '../../../entities/teamJoinApproval/teamJoinApproval'; +import { TeamJoinApprovalEntity } from '../../../business/entities/teamJoinApproval/teamJoinApproval'; import { Account } from '../../../business'; import { ReposAppRequest, IRequestTeams } from '../../../interfaces'; @@ -91,14 +91,14 @@ export class PermissionWorkflowEngine { // Find the request and assign the workflow engine -router.use(function (req: ReposAppRequest, res, next) { +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { req.individualContext.webContext.pushBreadcrumb('Approvals'); next(); }); router.get( '/', - asyncHandler(async (req: IRequestTeams, res, next) => { + asyncHandler(async (req: IRequestTeams, res: Response, next: NextFunction) => { const team = req.team2 as Team; const approvals = await team.getApprovals(); req.individualContext.webContext.render({ @@ -119,7 +119,7 @@ interface IRequestPlusApprovalEngine extends IRequestTeams { router.use( '/:requestid', - asyncHandler(async function (req: IRequestPlusApprovalEngine, res, next) { + asyncHandler(async function (req: IRequestPlusApprovalEngine, res: Response, next: NextFunction) { const team = req.team2 as Team; const requestid = req.params.requestid; const { approvalProvider, operations } = getProviders(req); diff --git a/routes/org/team/delete.ts b/routes/org/team/delete.ts index 92b05e2d6..9bd26af19 100644 --- a/routes/org/team/delete.ts +++ b/routes/org/team/delete.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import { ReposAppRequest, UserAlertType } from '../../../interfaces'; @@ -14,7 +14,7 @@ interface ILocalRequest extends ReposAppRequest { team2?: any; } -router.post('/', MiddlewareTeamAdminRequired, (req: ILocalRequest, res, next) => { +router.post('/', MiddlewareTeamAdminRequired, (req: ILocalRequest, res: Response, next: NextFunction) => { const organization = req.organization; const team2 = req.team2; team2.delete((error) => { diff --git a/routes/org/team/index-maintainer.ts b/routes/org/team/index-maintainer.ts index dba129c53..ef935c7c9 100644 --- a/routes/org/team/index-maintainer.ts +++ b/routes/org/team/index-maintainer.ts @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import { ReposAppRequest } from '../../../interfaces'; -import { wrapError } from '../../../utils'; +import { wrapError } from '../../../lib/utils'; const router: Router = Router(); import RouteApprovals from './approvals'; @@ -16,7 +16,7 @@ interface ILocalRequest extends ReposAppRequest { teamPermissions?: any; } -router.use(function (req: ILocalRequest, res, next) { +router.use(function (req: ILocalRequest, res: Response, next: NextFunction) { const teamPermissions = req.teamPermissions; if (!teamPermissions.allowAdministration) { const err = wrapError(null, 'You do not have permission to maintain this team.', true); diff --git a/routes/org/team/index.ts b/routes/org/team/index.ts index f96e01ee1..2b9def6f5 100644 --- a/routes/org/team/index.ts +++ b/routes/org/team/index.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import throat from 'throat'; -import { getProviders } from '../../../transitional'; -import { sortRepositoriesByNameCaseInsensitive, wrapError } from '../../../utils'; -import { TeamJoinApprovalEntity } from '../../../entities/teamJoinApproval/teamJoinApproval'; -import SelfServiceTeamMemberToMaintainerUpgrades from '../../../features/teamMemberToMaintainerUpgrade'; +import { getProviders } from '../../../lib/transitional'; +import { sortRepositoriesByNameCaseInsensitive, wrapError } from '../../../lib/utils'; +import { TeamJoinApprovalEntity } from '../../../business/entities/teamJoinApproval/teamJoinApproval'; +import SelfServiceTeamMemberToMaintainerUpgrades from '../../../business/features/teamMemberToMaintainerUpgrade'; import RouteMembers from './members'; import RouteReposPager from '../../reposPager'; import RouteDelete from './delete'; @@ -65,7 +65,7 @@ interface ILocalRequest extends ReposAppRequest { } router.use( - asyncHandler(async (req: ILocalRequest, res, next) => { + asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const login = req.individualContext.getGitHubIdentity().username; const team2 = req.team2 as Team; @@ -93,7 +93,7 @@ router.use( ); router.use( - asyncHandler(async (req: ILocalRequest, res, next) => { + asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { const { approvalProvider } = getProviders(req); const team2 = req.team2 as Team; if (!approvalProvider) { @@ -113,48 +113,53 @@ router.use( }) ); -router.use('/join', asyncHandler(AddOrganizationPermissionsToRequest), (req: ILocalRequest, res, next) => { - const organization = req.organization; - const team2 = req.team2; - const orgPermissions = req.orgPermissions; - - // Are they already a team member? - const currentMembershipStatus = req.membershipStatus; - if (currentMembershipStatus) { - return next( - wrapError(null, `You are already a ${currentMembershipStatus} of the ${team2.name} team`, true) - ); - } +router.use( + '/join', + asyncHandler(AddOrganizationPermissionsToRequest), + (req: ILocalRequest, res: Response, next: NextFunction) => { + const organization = req.organization; + const team2 = req.team2; + const orgPermissions = req.orgPermissions; + + // Are they already a team member? + const currentMembershipStatus = req.membershipStatus; + if (currentMembershipStatus) { + return next( + wrapError(null, `You are already a ${currentMembershipStatus} of the ${team2.name} team`, true) + ); + } - // Have they joined the organization yet? - const membershipStatus = orgPermissions.membershipStatus; - let error = null; - if (membershipStatus !== 'active') { - error = new Error(`You are not a member of the ${organization.name} GitHub organization.`); - error.title = 'Please join the organization before joining this team'; - error.detailed = - membershipStatus === 'pending' - ? 'You have not accepted your membership yet, or do not have two-factor authentication enabled.' - : 'After you join the organization, you can join this team.'; - error.skipOops = true; - error.skipLog = true; - error.fancyLink = { - link: `/${organization.name}`, - title: `Join the ${organization.name} organization`, - }; + // Have they joined the organization yet? + const membershipStatus = orgPermissions.membershipStatus; + let error = null; + if (membershipStatus !== 'active') { + error = new Error(`You are not a member of the ${organization.name} GitHub organization.`); + error.title = 'Please join the organization before joining this team'; + error.detailed = + membershipStatus === 'pending' + ? 'You have not accepted your membership yet, or do not have two-factor authentication enabled.' + : 'After you join the organization, you can join this team.'; + error.skipOops = true; + error.skipLog = true; + error.fancyLink = { + link: `/${organization.name}`, + title: `Join the ${organization.name} organization`, + }; + } + return next(error); } - return next(error); -}); +); router.get( '/join', - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { const team2 = req.team2 as Team; const organization = req.organization as Organization; - // The broad access "all members" team is always open for automatic joining without - // approval. This short circuit is to show that option. - const broadAccessTeams = new Set(organization.broadAccessTeams); - if (broadAccessTeams.has(team2.id)) { + // The broad access "all members" team and any "easy access" teams are + // always open for automatic joining without approval. This short circuit + // is to show that option. + const allowSelfJoinTeams = new Set([...organization.broadAccessTeams, ...organization.openAccessTeams]); + if (allowSelfJoinTeams.has(team2.id)) { req.individualContext.webContext.render({ view: 'org/team/join', title: `Join ${team2.name}`, @@ -181,7 +186,7 @@ router.get( router.post( '/selfServiceMaintainerUpgrade', - asyncHandler(async (req: ILocalRequest, res, next) => { + asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { const { selfServiceTeamMemberToMaintainerUpgrades } = req; if (!selfServiceTeamMemberToMaintainerUpgrades) { throw new Error('System not available'); @@ -214,7 +219,7 @@ export interface ITeamJoinRequestSubmitOutcome { router.post( '/join', - asyncHandler(async (req: ILocalRequest, res, next) => { + asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { if (req.existingRequest) { throw new Error('You have already created a team join request that is pending a decision.'); } @@ -251,7 +256,8 @@ export async function submitTeamJoinRequest( ): Promise { const { approvalProvider, config, graphProvider, mailProvider, insights, operations } = providers; const organization = team.organization; - const broadAccessTeams = new Set(organization.broadAccessTeams); + const { broadAccessTeams, openAccessTeams } = organization; + const allowSelfJoinTeams = new Set([...broadAccessTeams, ...openAccessTeams]); if (!approvalProvider) { return { error: new Error('No approval provider available') }; } @@ -259,8 +265,17 @@ export async function submitTeamJoinRequest( if (!username) { return { error: new Error('Active context required') }; } - if (broadAccessTeams.has(team.id)) { + if (allowSelfJoinTeams.has(team.id)) { try { + const eventName = broadAccessTeams.includes(team.id) ? 'JoinBroadAccessTeam' : 'JoinOpenAccessTeam'; + insights?.trackEvent({ + name: eventName, + properties: { + organization: organization.name, + id: team.id, + slug: team.slug, + }, + }); await team.addMembership(username); } catch (error) { insights?.trackEvent({ @@ -502,7 +517,7 @@ export async function submitTeamJoinRequest( router.use(asyncHandler(AddTeamPermissionsToRequest)); // The view uses this information today to show the sudo banner -router.use((req: ILocalRequest, res, next) => { +router.use((req: ILocalRequest, res: Response, next: NextFunction) => { if (req.teamPermissions.sudo === true) { req.sudoMode = true; } @@ -692,14 +707,18 @@ async function basicTeamsView(req: ILocalRequest, display: BasicTeamViewPage) { }); } -router.get('/', asyncHandler(AddOrganizationPermissionsToRequest), async (req: ILocalRequest, res, next) => { - await basicTeamsView(req, BasicTeamViewPage.Default); -}); +router.get( + '/', + asyncHandler(AddOrganizationPermissionsToRequest), + async (req: ILocalRequest, res: Response, next: NextFunction) => { + await basicTeamsView(req, BasicTeamViewPage.Default); + } +); router.get( '/history', asyncHandler(AddOrganizationPermissionsToRequest), - async (req: ILocalRequest, res, next) => { + async (req: ILocalRequest, res: Response, next: NextFunction) => { await basicTeamsView(req, BasicTeamViewPage.History); } ); @@ -707,7 +726,7 @@ router.get( router.get( '/repositories', asyncHandler(AddOrganizationPermissionsToRequest), - async (req: ILocalRequest, res, next) => { + async (req: ILocalRequest, res: Response, next: NextFunction) => { await basicTeamsView(req, BasicTeamViewPage.Repositories); } ); diff --git a/routes/org/team/leave.ts b/routes/org/team/leave.ts index 2c4f9eb67..1b6e20366 100644 --- a/routes/org/team/leave.ts +++ b/routes/org/team/leave.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); @@ -17,7 +17,7 @@ interface ILocalRequest extends ReposAppRequest { router.post( '/', - asyncHandler(async (req: ILocalRequest, res, next) => { + asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { const organization = req.organization as Organization; const team2 = req.team2 as Team; const username = req.individualContext.link.thirdPartyUsername; diff --git a/routes/org/team/maintainers.ts b/routes/org/team/maintainers.ts index d8ea7ff44..e4a42e22d 100644 --- a/routes/org/team/maintainers.ts +++ b/routes/org/team/maintainers.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders, validateGitHubLogin } from '../../../transitional'; +import { getProviders, validateGitHubLogin } from '../../../lib/transitional'; import { ReposAppRequest, RequestTeamMemberAddType, @@ -28,7 +28,7 @@ interface ILocalRequest extends ReposAppRequest { } router.use( - asyncHandler(async (req: ILocalRequest, res, next) => { + asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { // Get the latest maintainers, forced, with every request const team2 = req.team2 as Team; const maintainers = await refreshMaintainers(team2); @@ -51,7 +51,7 @@ router.get('/refresh', (req: ILocalRequest, res) => { router.post( '/:id/downgrade', MiddlewareTeamAdminRequired, - asyncHandler(async (req: ILocalRequest, res, next) => { + asyncHandler(async (req: ILocalRequest, res: Response, next: NextFunction) => { const team2 = req.team2 as Team; const id = req.params.id; const verifiedCurrentMaintainers = req.verifiedCurrentMaintainers; @@ -82,7 +82,7 @@ router.post( }) ); -router.use('/add', MiddlewareTeamAdminRequired, (req: ILocalRequest, res, next) => { +router.use('/add', MiddlewareTeamAdminRequired, (req: ILocalRequest, res: Response, next: NextFunction) => { req.team2AddType = RequestTeamMemberAddType.Maintainer; return next(); }); @@ -90,7 +90,7 @@ router.use('/add', MiddlewareTeamAdminRequired, (req: ILocalRequest, res, next) router.post( '/add', MiddlewareTeamAdminRequired, - asyncHandler(async function (req: ILocalRequest, res, next) { + asyncHandler(async function (req: ILocalRequest, res: Response, next: NextFunction) { const { operations } = getProviders(req); const login = validateGitHubLogin(req.body.username); const team2 = req.team2 as Team; diff --git a/routes/org/team/members.ts b/routes/org/team/members.ts index d9d911ca4..68339a928 100644 --- a/routes/org/team/members.ts +++ b/routes/org/team/members.ts @@ -3,13 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { Team, TeamMember } from '../../../business'; import { ReposAppRequest, RequestTeamMemberAddType, UserAlertType } from '../../../interfaces'; -import { getProviders, validateGitHubLogin } from '../../../transitional'; +import { getProviders, validateGitHubLogin } from '../../../lib/transitional'; import RoutePeopleSearch from '../../peopleSearch'; import MiddlewareTeamAdminRequired from './teamAdminRequired'; @@ -55,7 +55,7 @@ async function refreshMembersAndSummary(team2: Team, when): Promise { } router.use( - asyncHandler(async (req: ILocalTeamRequest, res, next) => { + asyncHandler(async (req: ILocalTeamRequest, res: Response, next: NextFunction) => { // Always make sure to have a relatively up-to-date membership cache available const team2 = req.team2 as Team; req.refreshedMembers = await refreshMembers( @@ -70,7 +70,7 @@ router.use( router.get( '/refresh', - asyncHandler(async (req: ILocalTeamRequest, res, next) => { + asyncHandler(async (req: ILocalTeamRequest, res: Response, next: NextFunction) => { // Refresh all the pages and also the cached single-page view shown on the team page const team2 = req.team2 as Team; await refreshMembersAndSummary(team2, 'whenever'); @@ -81,7 +81,7 @@ router.get( // Browse members router.use( '/browse', - (req: ILocalTeamRequest, res, next) => { + (req: ILocalTeamRequest, res: Response, next: NextFunction) => { req.team2RemoveType = 'member'; return next(); }, @@ -92,7 +92,7 @@ router.use( router.use( '/add', MiddlewareTeamAdminRequired, - (req: ILocalTeamRequest, res, next) => { + (req: ILocalTeamRequest, res: Response, next: NextFunction) => { req.team2AddType = RequestTeamMemberAddType.Member; return next(); }, @@ -102,7 +102,7 @@ router.use( router.post( '/remove', MiddlewareTeamAdminRequired, - asyncHandler(async (req: ILocalTeamRequest, res, next) => { + asyncHandler(async (req: ILocalTeamRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const username = validateGitHubLogin(req.body.username); const team2 = req.team2 as Team; @@ -120,7 +120,7 @@ router.post( router.post( '/add', MiddlewareTeamAdminRequired, - asyncHandler(async (req: ILocalTeamRequest, res, next) => { + asyncHandler(async (req: ILocalTeamRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const username = validateGitHubLogin(req.body.username); const organization = req.organization; diff --git a/routes/org/team/properties.ts b/routes/org/team/properties.ts index 0843c67ed..63f792b36 100644 --- a/routes/org/team/properties.ts +++ b/routes/org/team/properties.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import { ReposAppRequest, UserAlertType } from '../../../interfaces'; -import { wrapError } from '../../../utils'; +import { wrapError } from '../../../lib/utils'; import MiddlewareTeamAdminRequired from './teamAdminRequired'; @@ -16,48 +16,56 @@ interface IRequestWithTeamAndLegacy extends ReposAppRequest { teamUrl?: string; } -router.get('/', MiddlewareTeamAdminRequired, (req: IRequestWithTeamAndLegacy, res, next) => { - const team2 = req.team2; - team2.getDetails((error) => { - if (error) { - return next(wrapError(error, 'Had trouble getting the detailed properties for this team.')); - } - req.individualContext.webContext.pushBreadcrumb('Properties'); - req.individualContext.webContext.render({ - view: 'org/team/properties', - title: team2.name + ' - Properties', - state: { - team: team2, - teamUrl: req.teamUrl, - }, +router.get( + '/', + MiddlewareTeamAdminRequired, + (req: IRequestWithTeamAndLegacy, res: Response, next: NextFunction) => { + const team2 = req.team2; + team2.getDetails((error) => { + if (error) { + return next(wrapError(error, 'Had trouble getting the detailed properties for this team.')); + } + req.individualContext.webContext.pushBreadcrumb('Properties'); + req.individualContext.webContext.render({ + view: 'org/team/properties', + title: team2.name + ' - Properties', + state: { + team: team2, + teamUrl: req.teamUrl, + }, + }); }); - }); -}); + } +); -router.post('/', MiddlewareTeamAdminRequired, (req: IRequestWithTeamAndLegacy, res, next) => { - const team2 = req.team2; - const organization = req.organization; - const patch = { - name: req.body.ghname, - description: req.body.description, - }; - team2.edit(patch, (error) => { - if (error) { - return next(error); - } - req.individualContext.webContext.saveUserAlert( - 'Team properties updated on GitHub', - 'Properties Saved', - UserAlertType.Success - ); - team2.getDetails((getDetailsError) => { - if (getDetailsError) { - return next(getDetailsError); +router.post( + '/', + MiddlewareTeamAdminRequired, + (req: IRequestWithTeamAndLegacy, res: Response, next: NextFunction) => { + const team2 = req.team2; + const organization = req.organization; + const patch = { + name: req.body.ghname, + description: req.body.description, + }; + team2.edit(patch, (error) => { + if (error) { + return next(error); } - const slug = team2.slug; - return res.redirect('/' + organization.name + '/teams/' + slug); + req.individualContext.webContext.saveUserAlert( + 'Team properties updated on GitHub', + 'Properties Saved', + UserAlertType.Success + ); + team2.getDetails((getDetailsError) => { + if (getDetailsError) { + return next(getDetailsError); + } + const slug = team2.slug; + return res.redirect('/' + organization.name + '/teams/' + slug); + }); }); - }); -}); + } +); export default router; diff --git a/routes/org/team/teamAdminRequired.ts b/routes/org/team/teamAdminRequired.ts index 748ca8d51..6c40a9667 100644 --- a/routes/org/team/teamAdminRequired.ts +++ b/routes/org/team/teamAdminRequired.ts @@ -3,9 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +import { NextFunction, Response } from 'express'; + import { IReposError } from '../../../interfaces'; -export default function middlewareTeamAdminRequired(req, res, next) { +export default function middlewareTeamAdminRequired(req, res: Response, next: NextFunction) { const teamPermissions = req.teamPermissions; if (!teamPermissions) { return next(new Error('No team permissions information available')); diff --git a/routes/org/teams.ts b/routes/org/teams.ts index 74fc0bfd0..936e5ae5d 100644 --- a/routes/org/teams.ts +++ b/routes/org/teams.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { ReposAppRequest } from '../../interfaces'; -import { popSessionVariable } from '../../utils'; +import { popSessionVariable } from '../../lib/utils'; import lowercaser from '../../middleware/lowercaser'; import RouteTeam from './team/'; @@ -19,7 +19,7 @@ interface ITeamsRequest extends ReposAppRequest { teamUrl?: any; } -router.use(function (req: ReposAppRequest, res, next) { +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { req.individualContext.webContext.pushBreadcrumb('Teams'); req.reposContext = { section: 'teams', @@ -28,7 +28,7 @@ router.use(function (req: ReposAppRequest, res, next) { next(); }); -router.get('/', function (req, res, next) { +router.get('/', function (req, res: Response, next: NextFunction) { const beforeLinkReferrer = popSessionVariable(req, res, 'beforeLinkReferrer'); if (beforeLinkReferrer !== undefined) { return res.redirect(beforeLinkReferrer); @@ -40,7 +40,7 @@ router.get('/', lowercaser(['sort', 'set']), RouteTeamsPager); router.use( '/:teamSlug', - asyncHandler(async (req: ITeamsRequest, res, next) => { + asyncHandler(async (req: ITeamsRequest, res: Response, next: NextFunction) => { const organization = req.organization; const orgBaseUrl = organization.baseUrl; const slug = req.params.teamSlug as string; diff --git a/routes/orgAdmin.ts b/routes/orgAdmin.ts index f947ea224..9cc992d03 100644 --- a/routes/orgAdmin.ts +++ b/routes/orgAdmin.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; import { requirePortalAdministrationPermission } from '../middleware/business/administration'; import { PostgresLinkProvider } from '../lib/linkProviders/postgres/postgresLinkProvider'; @@ -16,7 +16,7 @@ import { Organization } from '../business'; import { Account } from '../business'; import { ILinkProvider } from '../lib/linkProviders'; import { ICorporateLink, ReposAppRequest, IProviders, UnlinkPurpose } from '../interfaces'; -import { isCodespacesAuthenticating } from '../utils'; +import { isCodespacesAuthenticating } from '../lib/utils'; // - - - Middleware: require that the user isa portal administrator to continue router.use(requirePortalAdministrationPermission); @@ -25,9 +25,11 @@ router.use(requirePortalAdministrationPermission); // These functions are not pretty. enum OperationsAction { - DestroyLink, - MarkAsServiceAccount, - UnmarkServiceAccount, + DestroyLink = 'Destroy link', + MarkAsServiceAccount = 'Mark as service account', + UnmarkServiceAccount = 'Unmark service account', + DestroyCollaboratorGrants = 'Destroy collaborator grants', + Destroy100 = 'Destroy 100', } enum UserQueryByType { @@ -207,10 +209,13 @@ async function loadInformation( if (queryCache && queryCache.supportsRepositoryCollaborators) { const result = await queryCache.userCollaboratorRepositories(thirdPartyId); const collaboratorRepositories = []; + const hasMany = result.length > 100; for (const { repository } of result) { try { - await repository.getDetails(); - collaboratorRepositories.push(repository.full_name); + if (!hasMany) { + await repository.getDetails(); + } + collaboratorRepositories.push(repository.organization.name + '/' + repository.name); } catch (ignoreError) { console.dir(ignoreError); } @@ -264,7 +269,7 @@ async function getGitHubAccountInformationById(operations: Operations, id: strin return account; } -router.get('/whois/id/:githubid', function (req: ReposAppRequest, res, next) { +router.get('/whois/id/:githubid', function (req: ReposAppRequest, res: Response, next: NextFunction) { const thirdPartyId = req.params.githubid; const providers = getProviders(req); queryByGitHubId(providers, thirdPartyId) @@ -296,7 +301,7 @@ interface IIDValue { router.get( '/whois/link/:linkid', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const linkId = req.params.linkid; const { linkProvider: lp } = getProviders(req); const linkProvider = lp as PostgresLinkProvider; @@ -315,7 +320,7 @@ router.get( router.post( '/whois/link/:linkid', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const { config } = getProviders(req); const linkId = req.params.linkid; const isLinkDelete = req.body['delete-link']; @@ -383,7 +388,7 @@ router.post( router.post( '/whois/link/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const { config, operations } = getProviders(req); const allowAdministratorManualLinking = operations?.config?.features?.allowAdministratorManualLinking; if (!allowAdministratorManualLinking) { @@ -436,13 +441,17 @@ router.post( }) ); -router.post('/whois/id/:githubid', function (req: ReposAppRequest, res, next) { +router.post('/whois/id/:githubid', function (req: ReposAppRequest, res: Response, next: NextFunction) { const thirdPartyId = req.params.githubid; const markAsServiceAccount = req.body['mark-as-service-account']; const unmarkServiceAccount = req.body['unmark-service-account']; + const removeCollaboration = req.body['remove-collaboration'] || req.body['remove-collaboration-100']; + const remove100 = req.body['remove-collaboration-100']; const providers = getProviders(req); let action = OperationsAction.DestroyLink; - if (markAsServiceAccount) { + if (removeCollaboration) { + action = remove100 ? OperationsAction.Destroy100 : OperationsAction.DestroyCollaboratorGrants; + } else if (markAsServiceAccount) { action = OperationsAction.MarkAsServiceAccount; } else if (unmarkServiceAccount) { action = OperationsAction.UnmarkServiceAccount; @@ -458,7 +467,7 @@ router.post('/whois/id/:githubid', function (req: ReposAppRequest, res, next) { } req.individualContext.webContext.render({ view: 'organization/whois/drop', - title: `Dropped link by ID ${thirdPartyId}`, + title: `${action} link by ID ${thirdPartyId}`, state, }); }) @@ -467,7 +476,7 @@ router.post('/whois/id/:githubid', function (req: ReposAppRequest, res, next) { }); }); -router.get('/whois/aad/:upn', function (req: ReposAppRequest, res, next) { +router.get('/whois/aad/:upn', function (req: ReposAppRequest, res: Response, next: NextFunction) { const upn = req.params.upn; const providers = getProviders(req); queryByCorporateUsername(providers, upn) @@ -488,7 +497,7 @@ router.get('/whois/aad/:upn', function (req: ReposAppRequest, res, next) { .catch(next); }); -router.get('/whois/github/:username', function (req: ReposAppRequest, res, next) { +router.get('/whois/github/:username', function (req: ReposAppRequest, res: Response, next: NextFunction) { const login = req.params.username; const providers = getProviders(req); queryByGitHubLogin(providers, login) @@ -507,13 +516,17 @@ router.get('/whois/github/:username', function (req: ReposAppRequest, res, next) .catch(next); }); -router.post('/whois/github/:username', function (req: ReposAppRequest, res, next) { +router.post('/whois/github/:username', function (req: ReposAppRequest, res: Response, next: NextFunction) { const username = req.params.username; const markAsServiceAccount = req.body['mark-as-service-account']; const unmarkServiceAccount = req.body['unmark-service-account']; + const removeCollaboration = req.body['remove-collaboration'] || req.body['remove-collaboration-100']; + const remove100 = req.body['remove-collaboration-100']; const providers = getProviders(req); let action = OperationsAction.DestroyLink; - if (markAsServiceAccount) { + if (removeCollaboration) { + action = remove100 ? OperationsAction.Destroy100 : OperationsAction.DestroyCollaboratorGrants; + } else if (markAsServiceAccount) { action = OperationsAction.MarkAsServiceAccount; } else if (unmarkServiceAccount) { action = OperationsAction.UnmarkServiceAccount; @@ -630,6 +643,13 @@ async function destructiveLogic( ); } + if (action === OperationsAction.DestroyCollaboratorGrants || action === OperationsAction.Destroy100) { + const account: Account = operations.getAccount(thirdPartyId); + const res = await account.removeCollaboratorPermissions(action === OperationsAction.Destroy100); + state.messages = res.history; + return state; + } + // Account termination if (linkQuery && linkQuery.link && !thirdPartyId) { thirdPartyId = linkQuery.link.thirdPartyId; @@ -672,7 +692,7 @@ router.get('/bulkRepoDelete', (req: ReposAppRequest, res) => { router.post( '/bulkRepoDelete', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { operations } = getProviders(req); let repositories = req.body.repositories; // TODO: FEATURE FLAG: add a feature flag whether this API is available. @@ -708,7 +728,7 @@ router.post( log.push(`Skipping, does not appear to be a GitHub repo URL: ${repositoryName}`); } } - return res.json(log); + return res.json(log) as unknown as void; }) ); diff --git a/routes/orgs.ts b/routes/orgs.ts index 3a0750280..08e812639 100644 --- a/routes/orgs.ts +++ b/routes/orgs.ts @@ -5,14 +5,14 @@ import querystring from 'querystring'; -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { IReposRequestWithOrganization } from '../interfaces'; import { injectReactClient, TryFallbackToBlob } from '../middleware'; -import { getProviders, hasStaticReactClientApp } from '../transitional'; -import { wrapError } from '../utils'; +import { getProviders, hasStaticReactClientApp } from '../lib/transitional'; +import { wrapError } from '../lib/utils'; import orgRoute from './org/'; @@ -26,7 +26,11 @@ if (hasReactApp) { router.use('/:orgName', asyncHandler(forwardToOrganizationRoutes)); -async function forwardToOrganizationRoutes(req: IReposRequestWithOrganization, res, next) { +async function forwardToOrganizationRoutes( + req: IReposRequestWithOrganization, + res: Response, + next: NextFunction +) { // This middleware contains both the original GitHub operations types // as well as the newer implementation. In time this will peel apart. const orgName = req.params.orgName; diff --git a/routes/people.ts b/routes/people.ts index 1f9e82ce4..b2592cadb 100644 --- a/routes/people.ts +++ b/routes/people.ts @@ -3,16 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; import { ReposAppRequest } from '../interfaces'; import RoutePeopleSearch from './peopleSearch'; import MiddlewareSystemWidePermissions from '../middleware/github/systemWidePermissions'; -router.use(function (req: ReposAppRequest, res, next) { +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { req.individualContext.webContext.pushBreadcrumb('People'); req.reposContext = { section: 'people', @@ -22,7 +22,7 @@ router.use(function (req: ReposAppRequest, res, next) { }); // Campaign-related redirect to take the user to GitHub -router.get('/github/:login', (req: ReposAppRequest, res, next) => { +router.get('/github/:login', (req: ReposAppRequest, res: Response, next: NextFunction) => { const providers = getProviders(req); if (!providers || !providers.campaign) { return next(); diff --git a/routes/peopleSearch.ts b/routes/peopleSearch.ts index 51c2746e7..023c08b60 100644 --- a/routes/peopleSearch.ts +++ b/routes/peopleSearch.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; import { RequestWithSystemwidePermissions, RequestTeamMemberAddType } from '../interfaces'; import { ensureAllLinksInMemory, getAllLinksFromRequest } from '../middleware/business/allLinks'; @@ -75,7 +75,7 @@ async function getPeopleAcrossOrganizations( router.get( '/', lowercaser(['sort']), - asyncHandler(async (req: IPeopleSearchRequest, res, next) => { + asyncHandler(async (req: IPeopleSearchRequest, res: Response, next: NextFunction) => { const linksFromMiddleware = getAllLinksFromRequest(req); const { operations } = getProviders(req); const org = req.organization ? req.organization.name : null; diff --git a/routes/placeholders.ts b/routes/placeholders.ts index cf28a6626..bb566fa43 100644 --- a/routes/placeholders.ts +++ b/routes/placeholders.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../interfaces'; -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; // These are Microsoft-specific, we'll remove these eventually. // TODO: remove from open source version since not helpful having random routes in place diff --git a/routes/releasesSpa.ts b/routes/releasesSpa.ts index fb683135f..a80cee5f5 100644 --- a/routes/releasesSpa.ts +++ b/routes/releasesSpa.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import { ReposAppRequest } from '../interfaces'; const router: Router = Router(); diff --git a/routes/repos.ts b/routes/repos.ts index 8d0daffb5..a8a0f7c2c 100644 --- a/routes/repos.ts +++ b/routes/repos.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import { ReposAppRequest } from '../interfaces'; @@ -11,7 +11,7 @@ import lowercaser from '../middleware/lowercaser'; import RouteReposPager from './reposPager'; -router.use(function (req: ReposAppRequest, res, next) { +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { req.individualContext.webContext.pushBreadcrumb('Repositories'); req.reposContext = { section: 'repos', diff --git a/routes/reposPager.ts b/routes/reposPager.ts index a44500fb9..17e5c7fb2 100644 --- a/routes/reposPager.ts +++ b/routes/reposPager.ts @@ -7,7 +7,7 @@ import asyncHandler from 'express-async-handler'; import { NextFunction, Response } from 'express'; import _ from 'lodash'; -import { daysInMilliseconds } from '../utils'; +import { daysInMilliseconds } from '../lib/utils'; import { Repository, IPersonalizedUserAggregateRepositoryPermission, @@ -20,7 +20,7 @@ import { import QueryCache from '../business/queryCache'; import { GitHubRepositoryType, IReposAppWithTeam } from '../interfaces'; import { IRequestTeamPermissions } from '../middleware/github/teamPermissions'; -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; import { UserContext } from '../business/user/aggregate'; interface IGetReposAndOptionalTeamPermissionsResponse { @@ -213,7 +213,7 @@ export default asyncHandler(async function (req: IReposAppWithTeam, res: Respons await search.search(page, req.query.sort as string); - // await Promise.all(search.repos.map(repo => repo.getDetails())); + await Promise.all(search.repos.map(repo => repo.getDetails())); req.individualContext.webContext.render({ view: 'repos/', diff --git a/routes/settings/approvals.ts b/routes/settings/approvals.ts index aa150ee3c..e71c73bbc 100644 --- a/routes/settings/approvals.ts +++ b/routes/settings/approvals.ts @@ -3,19 +3,19 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { IApprovalProvider } from '../../entities/teamJoinApproval/approvalProvider'; -import { TeamJoinApprovalEntity } from '../../entities/teamJoinApproval/teamJoinApproval'; -import { safeLocalRedirectUrl } from '../../utils'; +import { IApprovalProvider } from '../../business/entities/teamJoinApproval/approvalProvider'; +import { TeamJoinApprovalEntity } from '../../business/entities/teamJoinApproval/teamJoinApproval'; +import { safeLocalRedirectUrl } from '../../lib/utils'; import { Operations } from '../../business'; import { Team } from '../../business'; import { Organization } from '../../business'; import { IAggregateUserTeams } from '../../business/user/aggregate'; import { ReposAppRequest, IReposError, UserAlertType } from '../../interfaces'; -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; export interface ApprovalPair { team: Team; @@ -82,7 +82,7 @@ export async function Approvals_getUserRequests( router.get( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const { approvalProvider, operations } = getProviders(req); if (!approvalProvider) { return next(new Error('No approval provider instance available')); @@ -107,7 +107,7 @@ router.get( }) ); -router.post('/:requestid/cancel', function (req: ReposAppRequest, res, next) { +router.post('/:requestid/cancel', function (req: ReposAppRequest, res: Response, next: NextFunction) { const { approvalProvider } = getProviders(req); if (!approvalProvider) { return next(new Error('No approval provider instance available')); @@ -143,7 +143,7 @@ router.post('/:requestid/cancel', function (req: ReposAppRequest, res, next) { router.get( '/:requestid', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const requestid = req.params.requestid; const { approvalProvider, operations } = getProviders(req); req.individualContext.webContext.pushBreadcrumb('Your Request'); diff --git a/routes/settings/authorizations.ts b/routes/settings/authorizations.ts index 1cd16c480..17aae9bec 100644 --- a/routes/settings/authorizations.ts +++ b/routes/settings/authorizations.ts @@ -3,11 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../transitional'; +import { getProviders } from '../../lib/transitional'; import { Operations } from '../../business'; import { ReposAppRequest, ICorporateLink } from '../../interfaces'; @@ -54,7 +54,7 @@ function createValidator(operations: Operations, link: ICorporateLink, token: st }; } -router.use((req: IRequestWithAuthorizations, res, next) => { +router.use((req: IRequestWithAuthorizations, res: Response, next: NextFunction) => { // This is a lightweight, temporary implementation of authorization management to help clear // stored session tokens for apps like GitHub, VSTS, etc. const { operations } = getProviders(req); @@ -113,7 +113,7 @@ router.get('/', (req: IRequestWithAuthorizations, res) => { router.get( '/validate', - asyncHandler(async (req: IRequestWithAuthorizations, res, next) => { + asyncHandler(async (req: IRequestWithAuthorizations, res: Response, next: NextFunction) => { const authorizations = req.authorizations; for (const authorization of authorizations) { const validator = authorization.validator; diff --git a/routes/settings/campaigns.ts b/routes/settings/campaigns.ts index a5c7b5ef3..f2c8cb7aa 100644 --- a/routes/settings/campaigns.ts +++ b/routes/settings/campaigns.ts @@ -3,12 +3,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { ReposAppRequest, UserAlertType } from '../../interfaces'; -import { CreateError, getProviders } from '../../transitional'; +import { CreateError, getProviders } from '../../lib/transitional'; router.use('/:campaignGroupId', (req: ReposAppRequest, res: any, next) => { const { config } = getProviders(req); @@ -25,21 +25,21 @@ router.use('/:campaignGroupId', (req: ReposAppRequest, res: any, next) => { router.get( '/:campaignGroupId/unsubscribe', - asyncHandler(async (req: ReposAppRequest, res: any, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { return await modifySubscription(true, req, res, next); }) ); router.get( '/:campaignGroupId/subscribe', - asyncHandler(async (req: ReposAppRequest, res: any, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { return await modifySubscription(false, req, res, next); }) ); router.get( '/:campaignGroupId', - asyncHandler(async (req: ReposAppRequest, res: any, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const { campaignStateProvider } = getProviders(req); if (!campaignStateProvider) { return next(new Error('This app is not configured for campaign management')); @@ -53,7 +53,7 @@ router.get( return next(new Error('Corporate authentication and identity required')); } const currentState = await campaignStateProvider.getState(corporateId, campaignGroupId); - return res.json(currentState); + return res.json(currentState) as unknown as void; }) ); diff --git a/routes/settings/contributionData.ts b/routes/settings/contributionData.ts index 7e32f98f6..c68fc70b4 100644 --- a/routes/settings/contributionData.ts +++ b/routes/settings/contributionData.ts @@ -3,43 +3,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { ErrorHelper, getProviders } from '../../transitional'; -import { UserSettings } from '../../entities/userSettings'; -import { ReposAppRequest, UserAlertType } from '../../interfaces'; +import { ErrorHelper, getProviders } from '../../lib/transitional'; +import { UserSettings } from '../../business/entities/userSettings'; +import { UserAlertType } from '../../interfaces'; +import type { ReposAppRequestWithUserSettings } from '../../interfaces/middleware'; +import { getUserSettings } from '../../middleware/business/userSettings'; -export interface IRequestWithUserSettings extends ReposAppRequest { - userSettings?: UserSettings; -} - -async function getSettings(req: IRequestWithUserSettings, res, next) { - const corporateId = req.individualContext.corporateIdentity.id; - const { userSettingsProvider } = getProviders(req); - if (!req.userSettings) { - let settings: UserSettings = null; - try { - settings = await userSettingsProvider.getUserSettings(corporateId); - } catch (notFoundError) { - if (ErrorHelper.IsNotFound(notFoundError)) { - // ignore - } else { - throw notFoundError; - } - } - if (!settings) { - settings = new UserSettings(); - settings.corporateId = corporateId; - await userSettingsProvider.insertUserSettings(settings); - } - req.userSettings = settings; - } - return next(); -} - -function view(req: IRequestWithUserSettings, res) { +function view(req: ReposAppRequestWithUserSettings, res) { const userSettings = req.userSettings; req.individualContext.webContext.render({ view: 'settings/contributionData', @@ -50,13 +24,13 @@ function view(req: IRequestWithUserSettings, res) { }); } -router.use(asyncHandler(getSettings)); +router.use(asyncHandler(getUserSettings)); router.get('/', view); router.post( '/', - asyncHandler(async function (req: IRequestWithUserSettings, res, next) { + asyncHandler(async function (req: ReposAppRequestWithUserSettings, res: Response, next: NextFunction) { const isOptIn = !!(req.body.optIn === '1'); const currentSetting = req.userSettings.contributionShareOptIn; req.userSettings.contributionShareOptIn = isOptIn; diff --git a/routes/settings/index.ts b/routes/settings/index.ts index 37ea8f92b..8b25be30a 100644 --- a/routes/settings/index.ts +++ b/routes/settings/index.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); diff --git a/routes/settings/personalAccessTokens.ts b/routes/settings/personalAccessTokens.ts index 9aafe0077..303345a1a 100644 --- a/routes/settings/personalAccessTokens.ts +++ b/routes/settings/personalAccessTokens.ts @@ -3,14 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../../transitional'; -import { PersonalAccessToken } from '../../entities/token/token'; +import { getProviders } from '../../lib/transitional'; +import { PersonalAccessToken } from '../../business/entities/token/token'; import { ReposAppRequest } from '../../interfaces'; +type ResponseWithNewKey = Response & { + newKey: string; +}; + interface IPersonalAccessTokenForDisplay { active: boolean; expired: boolean; @@ -48,7 +52,7 @@ function translateTableToEntities( }); } -function getPersonalAccessTokens(req: ReposAppRequest, res, next) { +function getPersonalAccessTokens(req: ReposAppRequest, res: Response, next: NextFunction) { const providers = getProviders(req); const tokenProvider = providers.tokenProvider; const corporateId = req.individualContext.corporateIdentity.id; @@ -80,7 +84,7 @@ router.use(getPersonalAccessTokens); router.get('/', view); -function createToken(req: ReposAppRequest, res, next) { +function createToken(req: ReposAppRequest, res: ResponseWithNewKey, next: NextFunction) { const providers = getProviders(req); const tokenProvider = providers.tokenProvider; const insights = req.insights; @@ -136,7 +140,7 @@ router.post('/extension', createToken); router.post( '/delete', - asyncHandler(async (req: IRequestForSettingsPersonalAccessTokens, res, next) => { + asyncHandler(async (req: IRequestForSettingsPersonalAccessTokens, res: Response, next: NextFunction) => { const providers = getProviders(req); const tokenProvider = providers.tokenProvider; const revokeAll = req.body.revokeAll === '1'; diff --git a/routes/teams.ts b/routes/teams.ts index c1220135a..edf5c45ca 100644 --- a/routes/teams.ts +++ b/routes/teams.ts @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; const router: Router = Router(); import lowercaser from '../middleware/lowercaser'; @@ -11,7 +11,7 @@ import { ReposAppRequest } from '../interfaces'; import RouteTeamsPager from './teamsPager'; -router.use(function (req: ReposAppRequest, res, next) { +router.use(function (req: ReposAppRequest, res: Response, next: NextFunction) { req.individualContext.webContext.pushBreadcrumb('Teams'); req.reposContext = { section: 'teams', diff --git a/routes/teamsPager.ts b/routes/teamsPager.ts index 8dc93f1ab..d4225c2c6 100644 --- a/routes/teamsPager.ts +++ b/routes/teamsPager.ts @@ -7,7 +7,7 @@ import _ from 'lodash'; import asyncHandler from 'express-async-handler'; import { NextFunction, Response } from 'express'; -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; import { Operations } from '../business'; import { Team } from '../business'; import { UserContext } from '../business/user/aggregate'; diff --git a/routes/thanks.ts b/routes/thanks.ts index 04d7df55a..ff95bcfe6 100644 --- a/routes/thanks.ts +++ b/routes/thanks.ts @@ -5,7 +5,7 @@ import { ReposAppRequest } from '../interfaces'; import thisPackage from '../package.json'; -import { getProviders } from '../transitional'; +import { getProviders } from '../lib/transitional'; const express = require('express'); const router = express.Router(); diff --git a/routes/undo.ts b/routes/undo.ts index f0e61823e..a08e527ff 100644 --- a/routes/undo.ts +++ b/routes/undo.ts @@ -3,15 +3,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); import { Operations, Repository } from '../business'; -import { ErrorHelper, getProviders } from '../transitional'; -import { AuditLogRecord } from '../entities/auditLogRecord/auditLogRecord'; -import { daysInMilliseconds } from '../utils'; -import { AuditEvents } from '../entities/auditLogRecord'; +import { ErrorHelper, getProviders } from '../lib/transitional'; +import { AuditLogRecord } from '../business/entities/auditLogRecord/auditLogRecord'; +import { daysInMilliseconds } from '../lib/utils'; +import { AuditEvents } from '../business/entities/auditLogRecord'; import { IGitHubIdentity, IndividualContext } from '../business/user'; import { IMail } from '../lib/mailProvider'; import { GitHubRepositoryPermission, ReposAppRequest, UserAlertType } from '../interfaces'; @@ -291,7 +291,7 @@ async function undoTeamAdminRepoPermissionAsync( } router.use( - asyncHandler(async function (req: IHaveUndoCandidates, res, next) { + asyncHandler(async function (req: IHaveUndoCandidates, res: Response, next: NextFunction) { const { operations } = getProviders(req); if (!operations.allowUndoSystem) { res.status(404); @@ -322,7 +322,7 @@ router.use( router.post( '/', - asyncHandler(async (req: IHaveUndoCandidates, res, next) => { + asyncHandler(async (req: IHaveUndoCandidates, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const insights = operations.insights; const link = req.individualContext.link; @@ -394,7 +394,7 @@ router.post( router.get( '/', - asyncHandler(async (req: IHaveUndoCandidates, res, next) => { + asyncHandler(async (req: IHaveUndoCandidates, res: Response, next: NextFunction) => { const { operations } = getProviders(req); const insights = operations.insights; insights?.trackMetric({ name: 'UndoPageViews', value: 1 }); diff --git a/routes/unlink.ts b/routes/unlink.ts index af5a7e0a6..3e79266a6 100644 --- a/routes/unlink.ts +++ b/routes/unlink.ts @@ -3,18 +3,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -import { Router } from 'express'; +import { NextFunction, Response, Router } from 'express'; import asyncHandler from 'express-async-handler'; const router: Router = Router(); -import { getProviders } from '../transitional'; -import { wrapError } from '../utils'; +import { getProviders } from '../lib/transitional'; +import { wrapError } from '../lib/utils'; import { IndividualContext } from '../business/user'; import { jsonError } from '../middleware'; import { ReposAppRequest, OrganizationMembershipState, UnlinkPurpose } from '../interfaces'; router.use( - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const memberOfOrganizations = []; const { operations } = getProviders(req); const ghi = req.individualContext.getGitHubIdentity(); @@ -44,7 +44,7 @@ router.use( router.get( '/', - asyncHandler(async (req: ReposAppRequest, res, next) => { + asyncHandler(async (req: ReposAppRequest, res: Response, next: NextFunction) => { const link = req.individualContext.link; const id = req.individualContext.getGitHubIdentity().id; const { operations } = getProviders(req); @@ -110,7 +110,7 @@ export async function unlinkInteractive( router.post( '/', - asyncHandler(async function (req: ReposAppRequest, res, next) { + asyncHandler(async function (req: ReposAppRequest, res: Response, next: NextFunction) { const individualContext = req.individualContext; // TODO: validate return unlinkInteractive(false, individualContext, req, res, next); diff --git a/scripts/configuration.ts b/scripts/configuration.ts index 28f80acdc..8225c5164 100644 --- a/scripts/configuration.ts +++ b/scripts/configuration.ts @@ -3,24 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -async function go(providers: IProviders): Promise { - const { config } = providers; - for (const key of Object.getOwnPropertyNames(config)) { - console.log(`${key}\n`); - console.dir(config[key]); - console.log(); - } -} +import job from '../job'; -import app from '../app'; -import { IProviders, IReposJob } from '../interfaces'; - -app.runJob( - async function ({ providers }: IReposJob) { - await go(providers); - return {}; +job.run( + async (providers) => { + const { config } = providers; + for (const key of Object.getOwnPropertyNames(config)) { + console.log(`${key}\n`); + console.dir(config[key]); + console.log(); + } }, - { - enableAllGitHubApps: true, - } + { name: 'Script: View configuration' } ); diff --git a/scripts/localEnvironment.ts b/scripts/localEnvironment.ts index a3fad71cd..8611726c5 100644 --- a/scripts/localEnvironment.ts +++ b/scripts/localEnvironment.ts @@ -3,25 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -// The local environment script is designed to allow for local debugging, test and -// development scenarios. The go method is called with resolved configuration. +import job from '../job'; -async function go(providers: IProviders): Promise { - // --------------------------------------------------------------------------- -} +// This script allows for quick inner-loop development. -// ----------------------------------------------------------------------------- -// Local script initialization -// ----------------------------------------------------------------------------- -import app from '../app'; -import { IProviders, IReposJob } from '../interfaces'; - -app.runJob( - async function ({ providers }: IReposJob) { - await go(providers); - return {}; +job.run( + async (providers) => { + // }, - { - enableAllGitHubApps: true, - } + { name: 'Local Environment' } ); diff --git a/scripts/migrateLinks/task.ts b/scripts/migrateLinks.ts similarity index 84% rename from scripts/migrateLinks/task.ts rename to scripts/migrateLinks.ts index f7aaa3b02..316a702af 100644 --- a/scripts/migrateLinks/task.ts +++ b/scripts/migrateLinks.ts @@ -14,14 +14,17 @@ // LINK_MIGRATION_OVERWRITE values : 'overwrite', 'skip' import throat from 'throat'; -import { IReposJob, ICorporateLink } from '../../interfaces'; -import { createAndInitializeLinkProviderInstance, ILinkProvider } from '../../lib/linkProviders'; -import { ErrorHelper } from '../../transitional'; +import job from '../job'; +import { ICorporateLink, IProviders } from '../interfaces'; +import { createAndInitializeLinkProviderInstance } from '../lib/linkProviders'; +import { getThirdPartyLinkById } from '../lib/transitional'; const parallelWorkLimit = 5; -export default async function migration({ providers }: IReposJob): Promise { +job.run(migration, { name: 'Link migration' }); + +async function migration(providers: IProviders): Promise { // const sourceLinkProvider = providers.linkProvider; const config = providers.config; const sourceLinkProviderName = 'table'; @@ -57,7 +60,7 @@ export default async function migration({ providers }: IReposJob): Promise await Promise.all( allSourceLinks.map((sourceLink: ICorporateLink) => throttle(async () => { - const existingLink = await getThirdPartyLink(destinationLinkProvider, sourceLink.thirdPartyId); + const existingLink = await getThirdPartyLinkById(destinationLinkProvider, sourceLink.thirdPartyId); if (existingLink && overwriteDestinationLinks) { console.warn('Removing existing destination link...'); await destinationLinkProvider.deleteLink(existingLink); @@ -101,17 +104,6 @@ export default async function migration({ providers }: IReposJob): Promise console.log(); } -async function getThirdPartyLink(linkProvider: ILinkProvider, thirdPartyId: string): Promise { - try { - return await linkProvider.getByThirdPartyId(thirdPartyId); - } catch (error) { - if (ErrorHelper.IsNotFound(error)) { - return null; - } - throw error; - } -} - async function getUserIdByUpn(graphProvider, upn: string): Promise { return new Promise((resolve, reject) => { graphProvider.getUserById(upn, (err, info) => { diff --git a/scripts/postgres/setup.ts b/scripts/postgres/setup.ts index 7bcf5fe3f..7adb4968c 100644 --- a/scripts/postgres/setup.ts +++ b/scripts/postgres/setup.ts @@ -12,7 +12,7 @@ import path from 'path'; initialize(); async function setup() { - const sql = fs.readFileSync(path.join(__dirname, '../../../pg.sql'), 'utf8'); + const sql = fs.readFileSync(path.join(__dirname, '../../data/pg.sql'), 'utf8'); const server = await prompt('postgres server: '); const adminUsername = await prompt('admin user: '); diff --git a/jest.config.ts b/test/jest.config.ts similarity index 66% rename from jest.config.ts rename to test/jest.config.ts index d71b5f019..ec96f57aa 100644 --- a/jest.config.ts +++ b/test/jest.config.ts @@ -1,3 +1,8 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + // eslint-disable-next-line n/no-unpublished-import import type { Config } from 'jest'; diff --git a/tsconfig.json b/tsconfig.json index 7edc1ea63..b04ed2bd9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,12 @@ { "compilerOptions": { - "module": "commonjs", + "module": "NodeNext", "sourceMap": true, "outDir": "./dist", "incremental": true, "allowJs": true, - "moduleResolution": "node", + "declaration": true, + "moduleResolution": "nodenext", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, @@ -22,8 +23,8 @@ "./business/**/*", "./config/**/*", "./data/**/*", - "./entities/**/*", - "./features/**/*", + "business/entities/**/*", + "business/features/**/*", "./interfaces/**/*", "./jobs/**/*", "./lib/**/*", @@ -32,6 +33,6 @@ "./routes/**/*", "./scripts/**/*", "./test/**/*", - "./webhooks/**/*" + "business/webhooks/**/*" ] } diff --git a/views/contributions/eligible.pug b/views/contributions/eligible.pug index e1dd04859..3cad0a75f 100644 --- a/views/contributions/eligible.pug +++ b/views/contributions/eligible.pug @@ -6,10 +6,8 @@ extends ../layout block content - - var octicon = viewServices.octicon - .container - h5 CONFIDENTIAL - ADMINISTRATOR ACCESS ONLY + h5 ADMINISTRATOR ACCESS ONLY p Currently eligible corporate users to vote in the contribution system are listed below. p diff --git a/views/contributions/popular.pug b/views/contributions/popular.pug index 2ccd9f7c6..dacadaad8 100644 --- a/views/contributions/popular.pug +++ b/views/contributions/popular.pug @@ -6,8 +6,6 @@ extends ../layout block content - - var octicon = viewServices.octicon - .container p Popular repos people contribute to. diff --git a/views/contributions/voting/elections.pug b/views/contributions/voting/elections.pug index 0021a5886..5bff6d1fa 100644 --- a/views/contributions/voting/elections.pug +++ b/views/contributions/voting/elections.pug @@ -5,22 +5,32 @@ extends ../../layout -block content - - var fileSize = viewServices.fileSize - - var moment = viewServices.moment - - var octicon = viewServices.octicon - - //- var startMonthName = moment(start).format('MMMM') - //- var previousMonthName = moment(start).subtract(1, 'months').format('MMMM') +//- @cspell: ignore microsoftfossfund +block content .container - h2 Active Elections + h2 FOSS Fund Rounds + p. + The FOSS Fund is a way for Microsoft employees who contribute to open source + to support open source projects that they use and love. Public information + about this fund is available to be shared at #[a(href='https://aka.ms/microsoftfossfund') aka.ms/microsoftfossfund]. The + fund is distributed to projects based on the votes of Microsoft employees. if activeElections && activeElections.length + - var election1 = activeElections[0] + h3 Most recent funding round + h4: strong: a(href='/contributions/voting/' + election1.slug)= election1.title + p= election1.description + + h3 Past rounds each election in activeElections - //-pre= JSON.stringify(election, undefined, 2) - h2: a(href='/contributions/voting/' + election.slug)= election.title - p= election.description + if election.slug == election1.slug + //- nothing + else + //-pre= JSON.stringify(election, undefined, 2) + p + a(href='/contributions/voting/' + election.slug)= election.title + br + = election.description else - p No active voting opportunities. - + p No voting opportunities. diff --git a/views/contributions/voting/vote.pug b/views/contributions/voting/vote.pug index 1049fa3cc..546359c0d 100644 --- a/views/contributions/voting/vote.pug +++ b/views/contributions/voting/vote.pug @@ -24,9 +24,7 @@ mixin showNominee(election, nominee, iitemp, stripJsSingleQuote) p: small: em= nominee.justification block content - - var fileSize = viewServices.fileSize - var moment = viewServices.moment - - var octicon = viewServices.octicon - var stripJsSingleQuote = viewServices.stripJsSingleQuote //- var startMonthName = moment(start).format('MMMM') diff --git a/views/email/fossfund-vote.pug b/views/email/fossfund-vote.pug index 25b0f8987..94f43ceaf 100644 --- a/views/email/fossfund-vote.pug +++ b/views/email/fossfund-vote.pug @@ -48,16 +48,16 @@ block content p= election.description if userSettings && userSettings.contributionShareOptIn === true - //-h2 Launching soon, featuring you: the new opensource.microsoft.com + //-h2 Featuring you: the opensource.microsoft.com //-p Thanks for opting in to public data sharing. Your GitHub avatar and/or public contributions on GitHub may be featured. We will let you know when the new site launches. //-p: a(href='https://aka.ms/opensource/publicdatasharing') More info at aka.ms/opensource/publicdatasharing else if userSettings && userSettings.contributionShareOptIn === false - //-h2 The new opensource.microsoft.com site launches this month featuring many of your coworkers + //-h2 opensource.microsoft.com site features many of your coworkers //-p You have opted out of participating in the new site at this time. If you change your mind... //-p: a(href='https://aka.ms/opensource/publicdatasharing') More info and ability to opt-in at aka.ms/opensource/publicdatasharing else - h2 Want to be featured on the new opensource.microsoft.com site? - p Launched earlier this year, the new site features Microsoft employees who contribute to open source, whether part of their job, a hobby, or just something they do. + h2 Want to be featured on the opensource.microsoft.com site? + p The site features Microsoft employees who contribute to open source, whether part of their job, a hobby, or just something they do. p If you'd like to have your GitHub avatar appear on the homepage at times, and your contributions to other projects highlighted when they're made as part of the new "ecosystem" page, you can opt-in to sharing that already-public info. p: a(href='https://aka.ms/opensource/publicdatasharing') More info and ability to opt-in at aka.ms/opensource/publicdatasharing @@ -79,19 +79,20 @@ block content p We are trying to drive a change across Microsoft. We'd like to see more Microsofties contributing to open source communities, whether as part of your role, a Day of Learning project, updating project dependencies, hobbies, or pursuing off-hours projects and interests. h2 About the FOSS Fund - p Microsoft's FOSS Fund gives $10,000 to the most-voted-for open source software project. Projects are nominated and selected by those at Microsoft who contribute to communities that are not primarily Microsoft communities. + p Microsoft's FOSS Fund gives up to $10,000 to the most-voted-for open source software projects. Projects are nominated and selected by those at Microsoft who contribute to communities that are not primarily Microsoft communities. p Public information about the fund can be found at #[a(href='https://aka.ms/microsoftfossfund') https://aka.ms/microsoftfossfund], including previous fund winners. h3 Nominated projects p Projects must: ul - li Be used by Microsoft - li Have an OSI-approved license such as MIT, Apache 2.0, GPL, etc. + li Be used by Microsoft (used in Microsoft products and services) + li Have an #[a(href='https://opensource.org/licenses', target='_new') OSI-approved license] such as MIT, Apache 2.0, GPL, etc. li Must have a mechanism for receiving funds (the GitHub Sponsors team may be able to help) li Cannot be a Microsoft employee-led project + li Have a public-facing details of #[a(href='https://aka.ms/fossfundform/#funding', target='_new') who and how project sponsorship is distributed] h3 How to nominate a project for the next fund - p New FOSS Fund rounds are announced monthly via the #[a(href='https://idwebelements/GroupManagement.aspx?Group=osblast&Operation=join') osblast] discussion list. + p Nominate at any time using this #[a(href='https://aka.ms/fossfundform') form]. h3 Selection eligibility p Eligibility requirements: diff --git a/views/includes/corporateRepoMetadata.pug b/views/includes/corporateRepoMetadata.pug index 1ecb0cbf3..1b9db91d6 100644 --- a/views/includes/corporateRepoMetadata.pug +++ b/views/includes/corporateRepoMetadata.pug @@ -7,7 +7,6 @@ //- Optional inputs: createdUserLink //- Services -- var octicon = viewServices ? viewServices.octicon : null - var moment = viewServices ? viewServices.moment : null //- isBootstrap is currently being used to differentiate this include for whether it is diff --git a/views/message.pug b/views/message.pug index 10feac70c..d04cb6a70 100644 --- a/views/message.pug +++ b/views/message.pug @@ -6,6 +6,9 @@ extends layout block content + if clearLocalStorage + script. + localStorage.clear(); div.container#top(style='margin-top:60px') div.container#content div.row diff --git a/views/nav.pug b/views/nav.pug index 97ce212a6..0b13159d2 100644 --- a/views/nav.pug +++ b/views/nav.pug @@ -51,14 +51,14 @@ mixin userAzure div.navbar.navbar-default.second-row-nav div.container div.navbar-header - //-button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='.nav-collapse') - //-button.navbar-toggle(type='button', data-toggle='collapse', data-target='.nav-collapse') + button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='.nav-collapse') + button.navbar-toggle(type='button', data-toggle='collapse', data-target='.nav-collapse') span.sr-only Toggle navigation span.icon-bar span.icon-bar span.icon-bar - //- a.navbar-brand(href='./')= page.folderMetadata.title - //nav.collapse.navbar-collapse.nav-collapse(role='navigation') + // a.navbar-brand(href='./')= page.folderMetadata.title + nav.collapse.navbar-collapse.nav-collapse(role='navigation') nav(role='navigation') div.container(style='margin-top:24px;margin-bottom:12px') div.row(style=(user && !error && ossLink) ? 'margin-left:0' : 'margin-left:-30px') diff --git a/views/org/pending.pug b/views/org/pending.pug index 0e29de88a..348bbcaa9 100644 --- a/views/org/pending.pug +++ b/views/org/pending.pug @@ -78,20 +78,7 @@ block content div.row div.col-md-8.col-lg-8 h1 Want to join #{organization.name}? - if organization && organization.pilot_program && organization.pilot_program === 'pilot' - //- Pilot program - //- Due to SAML, auto-invite and accept does not work - p.lead 1ES Engineering Pilot - ul - li An invitation will be sent to your GitHub account. - li You accept the invitation in on GitHub.com. Due to SAML (single Microsoft sign-on), you may need to authenticate again with Microsoft AAD. - li You come back to this site and continue onboarding. - p   - form(method='post') - p - input.btn.btn-primary.btn-lg(type='submit', value='Join ' + organization.name) - - else if hasIncreasedScope && supportsExpressJoinExperience + if hasIncreasedScope && supportsExpressJoinExperience form(method='post') p(style='margin-top:24px') input.btn.btn-primary.btn-huge(type='submit', value='Join ' + organization.name) diff --git a/views/org/team/index.pug b/views/org/team/index.pug index f807d7042..503250909 100644 --- a/views/org/team/index.pug +++ b/views/org/team/index.pug @@ -87,13 +87,6 @@ mixin membersList(typeOfList, membersList, isAdmin, moreMembersToShow) p.lead.text-primary.text-center: small … and others block content - - //- Services - - var languageColor = viewServices.languageColor - - var octicon = viewServices.octicon - - var fileSize = viewServices.fileSize - - var moment = viewServices.moment - //- Variables - var maximumMembersToShow = (4 * 3) - 1 - var maximumRepositoriesToShow = 5 @@ -101,6 +94,7 @@ block content //- View services - var languageColor = viewServices.languageColor - var octicon = viewServices.octicon + - var moment = viewServices.moment //- Mode variables - var admin = teamPermissions.allowAdministration @@ -343,9 +337,12 @@ block content .repo(id=repo.name, style='padding-bottom:36px;display:block') h3 a(href='/' + localOrgName + '/repos/' + repo.name)= repo.name - if repo.private === true + if repo.visibility + |   + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} + if repo.has_pages |   - .label.label-warning.shrink66(title='This is a private repository and not open source.') Private + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages if repoPermissions && specificTeam = ' ' if repoPermissions.admin @@ -361,7 +358,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('primitive-dot', 10) + != octicon('dot-fill', 10) = ' ' + repo.language if repo.stargazers_count li diff --git a/views/organization/whois/result.pug b/views/organization/whois/result.pug index adde2067f..4a044bab3 100644 --- a/views/organization/whois/result.pug +++ b/views/organization/whois/result.pug @@ -173,6 +173,12 @@ block content p.lead DANGER ZONE - NO CONFIRMATION p input.btn.btn-danger(type='submit', value='Remove link', name='remove-link-only') + if query && query.collaboratorRepositories && query.collaboratorRepositories.length + p + input.btn.btn-danger(type='submit', value='Remove collaborator grants', name='remove-collaboration') + if query && query.collaboratorRepositories && query.collaboratorRepositories.length > 100 + p + input.btn.btn-danger(type='submit', value='Remove 100 collaborator grants', name='remove-collaboration-100') if query && query.collaboratorRepositories && query.collaboratorRepositories.length h2 Active individual Collaborator permissions on repos diff --git a/views/people/index.pug b/views/people/index.pug index 5266558b8..edaf41e3d 100644 --- a/views/people/index.pug +++ b/views/people/index.pug @@ -51,7 +51,7 @@ block content //-ul.nav.nav-pills li(class=(search.sort === 'Alphabet' ? 'active' : ''), title='Alphabetically sorted') a(href='?sort=Alphabet&tag=' + (tag ? tag : '') + (query.phrase ? '&q=' + query.phrase : '')) - != octicon('text-size', 20) + != octicon('typography', 20) | Name form.form-horizontal#entitySearch(style='margin-top:24px') diff --git a/views/repos/defaultBranch.pug b/views/repos/defaultBranch.pug deleted file mode 100644 index f05e585db..000000000 --- a/views/repos/defaultBranch.pug +++ /dev/null @@ -1,88 +0,0 @@ -//- -//- Copyright (c) Microsoft. -//- Licensed under the MIT license. See LICENSE file in the project root for full license information. -//- - -extends ../layout - -block content - - //- Services - - var languageColor = viewServices.languageColor - - var octicon = viewServices.octicon - - var fileSize = viewServices.fileSize - - //- Variables - - var githubUrl = 'https://github.com/' + repo.full_name - - var cloneUrl = repo.clone_url - - var sshUrl = repo.ssh_url - - var admin = repoPermissions && repoPermissions.allowAdministration - - .container - .row: .col-md-12 - if fromReposPage - .nav - ul.pager.zero-pad-bottom - li.previous - a(href='javascript:window.history.back()') - span(aria-hidden=true) ← - = ' Back' - - var hugeHeading = repo.name.length < 33 - h1(class={huge: hugeHeading}) - a(href='https://github.com/' + repo.full_name, target="_blank")= repo.name - if repo.private === true - |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) Private - h6= repo.full_name.replace('/' + repo.name, '') + ' organization' - if repo.description - p.lead=repo.description - - include ./pills - - if admin - if !organizationSupportsUpdatesApp - h4 Default branch rename #[span.label.label-muted PREVIEW] - ul.list-inline.list-horizontal-space - li - | Current default branch name - br - strong= repo.default_branch - p. - The #{organization.name} is not configured to allow renames at this time. - else - //- repo.default_branch !== 'main' - h4 Default branch rename #[span.label.label-muted PREVIEW] - ul.list-inline.list-horizontal-space - li - | Current default branch name - br - strong= repo.default_branch - p You have administrative rights to this repo and can choose to rename the default branch. - if repo.default_branch == 'main' - p: strong You're already using the default branch "main", no action required. - p. - Easily convert the default branch of this project. Note that there are - many potential side effects, including impacting deep URL links, continuous - integration and deployment systems, and likely this will require cleanup - work. - p. - This automated default branch rename capability: - ul - li Creates a new branch based off of the current default branch's latest commit - li Reassigns any protected branch settings to the new default branch from the former - li Updates any open pull requests against the current default branch for the new branch - li Updates the default branch to the new branch - li Deletes the current default branch - p The automated operation will halt if a major error is detected, but will not revert the changes completely. It will take 20-120 seconds to process. Please anticipate updating this repo to take some time, and resource for this change. This process may timeout if there are a large number of open pull requests. - - form(method='post', action=repository.baseUrl + 'defaultBranch') - p: strong New default branch name - input.form-control(name='targetBranchName', type='text', placeholder='The new default branch name to use', value='main') - br - input.btn.btn-sm( - type='submit', - name='rename-default-branch' - class='btn-danger', - value='Rename default branch', - onclick='return confirm(\'Are you sure that you want to rename the default branch? Additional work may be required to address any errors or configure systems such as webhooks, continuous integration, etc.\');' - title='Select this operation to begin the default branch rename process automatically') diff --git a/views/repos/delete.pug b/views/repos/delete.pug index f8886d855..57f420726 100644 --- a/views/repos/delete.pug +++ b/views/repos/delete.pug @@ -7,11 +7,6 @@ extends ../layout block content - //- Services - - var languageColor = viewServices.languageColor - - var octicon = viewServices.octicon - - var fileSize = viewServices.fileSize - //- View constants - var maxReaders = 10 diff --git a/views/repos/history.pug b/views/repos/history.pug index 2c36be2b5..d7100cbf6 100644 --- a/views/repos/history.pug +++ b/views/repos/history.pug @@ -8,9 +8,6 @@ extends ../layout block content //- Services - - var languageColor = viewServices.languageColor - - var octicon = viewServices.octicon - - var fileSize = viewServices.fileSize - var moment = viewServices.moment //- Variables diff --git a/views/repos/index.pug b/views/repos/index.pug index 8ffce2683..2c657276f 100644 --- a/views/repos/index.pug +++ b/views/repos/index.pug @@ -81,7 +81,7 @@ block content li(class=(search.sort === 'Alphabet' ? 'active' : ''), title='Sort by repo name') a(href='?sort=Alphabet&tag=' + (specificTeamId ? '&teamRepos=' + specificTeamId : '') + (tag ? tag : '') + (query.tt ? '&tt=' + query.tt : '') + (query.phrase ? '&q=' + query.phrase : '')) //- i.glyphicon.glyphicon-sort-by-alphabet - != octicon('text-size', 20) + != octicon('typography', 20) | Name //-i.glyphicon.glyphicon-triangle-bottom li(class=(search.sort === 'Updated' ? 'active' : '')) @@ -225,9 +225,12 @@ block content if showIds = repo.id + ' ' a(href='/' + localOrgName + '/repos/' + repo.name)= repo.name - if repo.private === true + if repo.visibility |   - .label.label-warning.shrink66(title='This is a private repository and not open source.') Private + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} + if repo.has_pages + |   + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages if repo.permissions && specificTeam = ' ' if repo.permissions.admin @@ -248,7 +251,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('primitive-dot', 10) + != octicon('dot-fill', 10) = ' ' + repo.language if repo.stargazers_count li diff --git a/views/repos/permissions.pug b/views/repos/permissions.pug index 1cbc9e9de..5168fc4b3 100644 --- a/views/repos/permissions.pug +++ b/views/repos/permissions.pug @@ -66,9 +66,7 @@ mixin teamsList(teams, hideJoinOption) block content //- Services - - var languageColor = viewServices.languageColor - var octicon = viewServices.octicon - - var fileSize = viewServices.fileSize //- View constants - var maxReaders = 10 diff --git a/views/repos/pills.pug b/views/repos/pills.pug index 7800be760..9f1e89b86 100644 --- a/views/repos/pills.pug +++ b/views/repos/pills.pug @@ -6,6 +6,5 @@ .row: .col-md-12(style='margin-bottom: 32px; margin-top: 16px') ul.nav.nav-tabs li(role='presentation', class={active: !reposSubView || reposSubView === 'default'}): a(href=repository.baseUrl) Overview - li(role='presentation', class={active: reposSubView === 'defaultBranch'}): a(href=repository.baseUrl + 'defaultBranch/') Default Branch Name li(role='presentation', class={active: reposSubView === 'permissions'}): a(href=repository.baseUrl + 'permissions/') Permissions li(role='presentation', class={active: reposSubView === 'history'}): a(href=repository.baseUrl + 'history/') History diff --git a/views/repos/repo.pug b/views/repos/repo.pug index da2e35ae1..fd3d575a7 100644 --- a/views/repos/repo.pug +++ b/views/repos/repo.pug @@ -13,27 +13,6 @@ mixin simplePersonView(account) div(style='display:block;vertical-align:middle') h4 a(href='/people?q=' + account.login)= shorthandName - //-ul.list-inline - if shorthandName && shorthandName !== account.login - li - span(title=account.login + ' is the GitHub username for ' + shorthandName)= account.login - if corporateIdentity - if link && !corporate - li.text-warning!= octicon('link', 16) - li - span(title=link.aadoid)= link.aadupn - else - li!= octicon('link', 16) - li - span(title=corporateIdentity + ' is the corporate identity for ' + shorthandName)= corporateIdentity - //- just corporate e-mails here, not user emails - if email - li - a(href='mailto:' + email, title='Send corporate email to ' + email) - != octicon('mail', 16) - if serviceAccount - li!= octicon('hubot', 16) - li Service account mixin teamsList(teams, hideJoinOption) if teams && teams.length > 0 @@ -96,9 +75,12 @@ block content - var hugeHeading = repo.name.length < 33 h1(class={huge: hugeHeading}) a(href='https://github.com/' + repo.full_name, target="_blank")= repo.name - if repo.private === true + if repo.visibility + |   + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) #{repo.visibility} + if repo.has_pages |   - .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) Private + .label.label-warning(class={shrink66: !hugeHeading, shrink50: hugeHeading}) pages h6= repo.full_name.replace('/' + repo.name, '') + ' organization' if repo.fork h6 @@ -123,7 +105,7 @@ block content if repo.language li span(style={color: languageColor(repo.language)}) - != octicon('primitive-dot', 10) + != octicon('dot-fill', 10) = ' ' + repo.language if repo.license && repo.license.featured && repo.license.name li @@ -185,9 +167,6 @@ block content | Default branch br strong= repo.default_branch - if repo.default_branch === 'master' && admin - span   - a.btn.btn-sm.btn-muted(href=repository.baseUrl + 'defaultBranch') Rename... if organizationSupportsUpdatesApp && repo.default_branch !== 'main' && admin .alert.alert-gray diff --git a/views/teams/index.pug b/views/teams/index.pug index 4f9b585a7..c1c3b23f5 100644 --- a/views/teams/index.pug +++ b/views/teams/index.pug @@ -9,7 +9,6 @@ block append js_doc_ready include ../js/search.js block content - - var languageColor = viewServices.languageColor - var octicon = viewServices.octicon .container From ff4576c796c434bf16bfa30a7fe5bc2aaecaea49 Mon Sep 17 00:00:00 2001 From: furniturewalatkNIH <137434977+furniturewalatkNIH@users.noreply.github.com> Date: Thu, 1 Aug 2024 11:28:49 -0500 Subject: [PATCH 182/209] Update nav.pug - Joels change done to fix the issue seen on merge --- views/nav.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/nav.pug b/views/nav.pug index 0b13159d2..7e7c068e2 100644 --- a/views/nav.pug +++ b/views/nav.pug @@ -57,7 +57,7 @@ div.navbar.navbar-default.second-row-nav span.icon-bar span.icon-bar span.icon-bar - // a.navbar-brand(href='./')= page.folderMetadata.title + a.navbar-brand(href='./')= page.folderMetadata.title nav.collapse.navbar-collapse.nav-collapse(role='navigation') nav(role='navigation') div.container(style='margin-top:24px;margin-bottom:12px') From 51e51c1fe8898af86b653965ff11871903366665 Mon Sep 17 00:00:00 2001 From: furniturewalatkNIH <137434977+furniturewalatkNIH@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:22:32 -0500 Subject: [PATCH 183/209] commenting out line 60 --- views/nav.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/nav.pug b/views/nav.pug index 7e7c068e2..67d2ef894 100644 --- a/views/nav.pug +++ b/views/nav.pug @@ -57,7 +57,7 @@ div.navbar.navbar-default.second-row-nav span.icon-bar span.icon-bar span.icon-bar - a.navbar-brand(href='./')= page.folderMetadata.title + // a.navbar-brand(href='./')= page.folderMetadata.title nav.collapse.navbar-collapse.nav-collapse(role='navigation') nav(role='navigation') div.container(style='margin-top:24px;margin-bottom:12px') From 01576ed11d1ce5c4878d0d327cb3a43ca89f8ca2 Mon Sep 17 00:00:00 2001 From: jrcoleman Date: Tue, 13 Aug 2024 13:41:59 -0400 Subject: [PATCH 184/209] Add repository_selection to org settings --- .github/scripts/Create-PSQLUpdate.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/scripts/Create-PSQLUpdate.ps1 b/.github/scripts/Create-PSQLUpdate.ps1 index 0893bb02f..6de95e1b8 100644 --- a/.github/scripts/Create-PSQLUpdate.ps1 +++ b/.github/scripts/Create-PSQLUpdate.ps1 @@ -50,7 +50,9 @@ foreach ($item in $data) { else { $processed_description = $orgData.description } - + if ($item.repository_selection -ne "all") { + Write-Output "Org $($item.account.login) does not have all repositories selected. This can cause issues with the portal." + } $insertData += [PSCustomObject]@{ type = @("public", "private", "internal") active = $true @@ -60,6 +62,7 @@ foreach ($item in $data) { @{ appId = $item.app_id installationId = $item.id + repositoryAccess = $item.repository_selection } ) organizationid = $item.account.id From 7a8b60917c32b7c83a97c8df1b3a50cfe864c24a Mon Sep 17 00:00:00 2001 From: jrcoleman Date: Tue, 13 Aug 2024 16:01:09 -0400 Subject: [PATCH 185/209] Fix app_output step --- .../staging_update_orgsettings_table.yaml | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/staging_update_orgsettings_table.yaml b/.github/workflows/staging_update_orgsettings_table.yaml index 31b520e29..1343833af 100644 --- a/.github/workflows/staging_update_orgsettings_table.yaml +++ b/.github/workflows/staging_update_orgsettings_table.yaml @@ -25,15 +25,23 @@ jobs: PEM: ${{ secrets.DEV_APP_PEM }} APPID: ${{ secrets.DEV_APP_ID }} - + # JC Note: This version of this step is not working changing to use curl like for production + # - name: run gh cli to get app install info + # run: | + # gh api --paginate \ + # -H "Accept: application/vnd.github+json" \ + # -H "Authorization: Bearer $(cat token)" \ + # -H "X-GitHub-Api-Version: 2022-11-28" \ + # app/installations | jq >> app_output.json - name: run gh cli to get app install info run: | - gh api --paginate \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer $(cat token)" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - app/installations | jq >> app_output.json - + curl \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $(cat token)" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/app/installations?per_page=100 | jq >> app_output.json + cat ./app_output.json + # needs a PAT that can read org and enterprise data - name: run powershell script to build sql run: | From 6aed215efdbb09fb11f3ee606329b7a9ee3ece79 Mon Sep 17 00:00:00 2001 From: jrcoleman Date: Thu, 15 Aug 2024 13:48:48 -0400 Subject: [PATCH 186/209] Error is missing all repo permissions. --- .github/scripts/Create-PSQLUpdate.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/scripts/Create-PSQLUpdate.ps1 b/.github/scripts/Create-PSQLUpdate.ps1 index 6de95e1b8..6b9a9e82e 100644 --- a/.github/scripts/Create-PSQLUpdate.ps1 +++ b/.github/scripts/Create-PSQLUpdate.ps1 @@ -52,6 +52,7 @@ foreach ($item in $data) { } if ($item.repository_selection -ne "all") { Write-Output "Org $($item.account.login) does not have all repositories selected. This can cause issues with the portal." + Throw "Org $($item.account.login) does not have all repositories selected. This can cause issues with the portal." } $insertData += [PSCustomObject]@{ type = @("public", "private", "internal") From 82ef32d7bc2e6b7f025ffc31f16f56eaf112a051 Mon Sep 17 00:00:00 2001 From: furniturewalatkNIH <137434977+furniturewalatkNIH@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:59:09 -0600 Subject: [PATCH 187/209] Update package.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manually adding in the below dependabot alerts: chore(deps): bump path-to-regexp and express by dependabot[bot] ยท Pull Request #640 ยท NIHGOV/github-portal chore(deps): bump body-parser from 1.20.2 to 1.20.3 by dependabot[bot] ยท Pull Request #638 ยท NIHGOV/github-portal chore(deps): bump axios from 1.6.5 to 1.7.4 by dependabot[bot] ยท Pull Request #609 ยท NIHGOV/github-portal --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 1b2d5c589..a86cd915a 100644 --- a/package.json +++ b/package.json @@ -80,9 +80,9 @@ "app-root-path": "3.1.0", "applicationinsights": "2.9.2", "async-prompt": "1.0.1", - "axios": "1.6.5", + "axios": "1.7.4", "basic-auth": "2.0.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "color-contrast-checker": "2.1.0", "compression": "1.7.4", "connect-redis": "7.1.0", @@ -90,7 +90,7 @@ "debug": "4.3.4", "deepmerge": "4.3.1", "dotenv": "16.3.1", - "express": "4.18.2", + "express": "4.21.0", "express-async-handler": "1.2.0", "express-session": "1.17.3", "express-sslify": "1.2.0", From 4782350ea1c0a048ebea3b23e7996a01a5db4e21 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Thu, 4 Jun 2026 05:08:45 +0000 Subject: [PATCH 188/209] feat: ACI container deployment workflows and infra reference configs Add GitHub Actions workflows to deploy/recreate ACI container groups for both staging and production environments, and infra reference YAMLs. Workflows: - staging_nihdevgithubportalfh.yml (firehose, daily 01:00 UTC + manual) - staging_nihdevgithubportalcb.yml (cache builder, every 6h + manual) - main_nihgithubportalfh.yml (prod firehose, manual) - main_nihgithubportalcb.yml (prod cache builder, manual) Fixes: - Correct job command paths (jobs/firehose.js, jobs/refreshQueryCache.js) - Correct env var assignment: GITHUB_APP_OPERATIONS_KEY carries the PEM - All credentials sourced from GitHub Secrets (no hardcoded values) Infra reference configs in infra/aci/ document the container structure. --- .cspell.json | 5 ++ .github/workflows/main_nihgithubportalcb.yml | 76 +++++++++++++++++++ .github/workflows/main_nihgithubportalfh.yml | 75 ++++++++++++++++++ .../staging_nihdevgithubportalcb.yml | 76 +++++++++++++++++++ .../staging_nihdevgithubportalfh.yml | 75 ++++++++++++++++++ infra/aci/prod-cachebuilder.yml | 70 +++++++++++++++++ infra/aci/prod-firehose.yml | 72 ++++++++++++++++++ infra/aci/staging-cachebuilder.yml | 70 +++++++++++++++++ infra/aci/staging-firehose.yml | 72 ++++++++++++++++++ 9 files changed, 591 insertions(+) create mode 100644 .github/workflows/main_nihgithubportalcb.yml create mode 100644 .github/workflows/main_nihgithubportalfh.yml create mode 100644 .github/workflows/staging_nihdevgithubportalcb.yml create mode 100644 .github/workflows/staging_nihdevgithubportalfh.yml create mode 100644 infra/aci/prod-cachebuilder.yml create mode 100644 infra/aci/prod-firehose.yml create mode 100644 infra/aci/staging-cachebuilder.yml create mode 100644 infra/aci/staging-firehose.yml diff --git a/.cspell.json b/.cspell.json index 83a11efe1..010f0d1d1 100644 --- a/.cspell.json +++ b/.cspell.json @@ -502,7 +502,12 @@ "newrepolockdown", "newrepolockremoved", "nihgithubportal", + "nihgithubportalcb", + "nihgithubportalfh", "nihdevgithubportal", + "nihdevgithubportalcb", + "nihdevgithubportalfh", + "centralus", "Newtonsoft", "NOASSERTION", "nodeapp", diff --git a/.github/workflows/main_nihgithubportalcb.yml b/.github/workflows/main_nihgithubportalcb.yml new file mode 100644 index 000000000..97992a58e --- /dev/null +++ b/.github/workflows/main_nihgithubportalcb.yml @@ -0,0 +1,76 @@ +name: NIH GHMP (Prod) - Deploy Cache Builder Container + +on: + schedule: + # Run every 6 hours to keep query cache fresh. + - cron: '0 */6 * * *' + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + creds: '{"clientId":"${{ secrets.PROD_AAD_CLIENT_ID }}","clientSecret":"${{ secrets.PROD_AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.PROD_AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.PROD_AAD_TENANT_ID }}"}' + + - name: Delete existing container group + run: | + az container delete \ + --resource-group "${{ secrets.PROD_RG }}" \ + --name nihgithubportalcb \ + --yes 2>/dev/null || true + + - name: Create cache builder container + env: + REGISTRY_SERVER: ${{ secrets.PROD_REGISTRY_SERVER }} + REGISTRY_USER: ${{ secrets.PROD_REGISTRY_USER }} + REGISTRY_PASS: ${{ secrets.PROD_REGISTRY_PASS }} + REDIS_TLS_HOST: ${{ secrets.PROD_REDIS_TLS_HOST }} + REDIS_KEY: ${{ secrets.PROD_REDIS_KEY }} + POSTGRES_HOST: ${{ secrets.PROD_POSTGRES_HOST }} + POSTGRES_DB: ${{ secrets.PROD_POSTGRES_DB }} + POSTGRES_USER: ${{ secrets.PROD_POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ secrets.PROD_POSTGRES_PASSWORD }} + APP_ID: ${{ secrets.PROD_GITHUB_APP_OPERATIONS_APP_ID }} + APP_KEY: ${{ secrets.PROD_GITHUB_APP_OPERATIONS_KEY }} + APP_SLUG: ${{ secrets.PROD_GITHUB_APP_OPERATIONS_SLUG }} + RG: ${{ secrets.PROD_RG }} + run: | + az container create \ + --resource-group "$RG" \ + --name nihgithubportalcb \ + --location centralus \ + --image "$REGISTRY_SERVER/portal:latest" \ + --registry-server "$REGISTRY_SERVER" \ + --registry-username "$REGISTRY_USER" \ + --registry-password "$REGISTRY_PASS" \ + --command-line "node /usr/src/repos/jobs/refreshQueryCache.js" \ + --restart-policy OnFailure \ + --os-type Linux \ + --cpu 1 \ + --memory 1.5 \ + --ip-address Public \ + --ports 443 \ + --environment-variables \ + REDIS_TLS_HOST="$REDIS_TLS_HOST" \ + REDIS_PORT=6380 \ + REPOS_POSTGRES_DATABASE="$POSTGRES_DB" \ + REPOS_POSTGRES_HOST="$POSTGRES_HOST" \ + REPOS_POSTGRES_USER="$POSTGRES_USER" \ + REPOS_POSTGRES_SSL=false \ + GITHUB_ORGANIZATIONS_SOURCE=postgres \ + GITHUB_APP_OPERATIONS_APP_ID="$APP_ID" \ + GITHUB_APP_OPERATIONS_SLUG="$APP_SLUG" \ + --secure-environment-variables \ + REDIS_KEY="$REDIS_KEY" \ + REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ + GITHUB_APP_OPERATIONS_KEY="$APP_KEY" \ + --tags \ + 'Creator=petersonjd@nih.gov' \ + Customer=NIH \ + Impact=Low \ + Project=GitHub \ + --no-wait diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml new file mode 100644 index 000000000..4445599c9 --- /dev/null +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -0,0 +1,75 @@ +name: NIH GHMP (Prod) - Deploy Firehose Container + +on: + schedule: + # Restart daily at 01:00 UTC โ€” firehose has a 48h kill bit; daily restart ensures continuity. + - cron: '0 1 * * *' + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + creds: '{"clientId":"${{ secrets.PROD_AAD_CLIENT_ID }}","clientSecret":"${{ secrets.PROD_AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.PROD_AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.PROD_AAD_TENANT_ID }}"}' + + - name: Delete existing container group + run: | + az container delete \ + --resource-group "${{ secrets.PROD_RG }}" \ + --name nihgithubportalfh \ + --yes 2>/dev/null || true + + - name: Create firehose container + env: + REGISTRY_SERVER: ${{ secrets.PROD_REGISTRY_SERVER }} + REGISTRY_USER: ${{ secrets.PROD_REGISTRY_USER }} + REGISTRY_PASS: ${{ secrets.PROD_REGISTRY_PASS }} + REDIS_TLS_HOST: ${{ secrets.PROD_REDIS_TLS_HOST }} + REDIS_KEY: ${{ secrets.PROD_REDIS_KEY }} + POSTGRES_HOST: ${{ secrets.PROD_POSTGRES_HOST }} + POSTGRES_DB: ${{ secrets.PROD_POSTGRES_DB }} + POSTGRES_USER: ${{ secrets.PROD_POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ secrets.PROD_POSTGRES_PASSWORD }} + SERVICEBUS_CONN: ${{ secrets.PROD_SERVICEBUS_CONNECTIONSTRING }} + RG: ${{ secrets.PROD_RG }} + run: | + az container create \ + --resource-group "$RG" \ + --name nihgithubportalfh \ + --location centralus \ + --image "$REGISTRY_SERVER/portal:latest" \ + --registry-server "$REGISTRY_SERVER" \ + --registry-username "$REGISTRY_USER" \ + --registry-password "$REGISTRY_PASS" \ + --command-line "node /usr/src/repos/jobs/firehose.js" \ + --restart-policy OnFailure \ + --os-type Linux \ + --cpu 1 \ + --memory 1.5 \ + --ip-address Public \ + --ports 443 \ + --environment-variables \ + REDIS_TLS_HOST="$REDIS_TLS_HOST" \ + REDIS_PORT=6380 \ + REPOS_POSTGRES_DATABASE="$POSTGRES_DB" \ + REPOS_POSTGRES_HOST="$POSTGRES_HOST" \ + REPOS_POSTGRES_USER="$POSTGRES_USER" \ + REPOS_POSTGRES_SSL=false \ + GITHUB_ORGANIZATIONS_FILE=../env-orgs.json \ + GITHUB_ORGANIZATIONS_SOURCE=postgres \ + GITHUB_WEBHOOKS_PROVIDER=servicebus \ + GITHUB_WEBHOOKS_SERVICEBUS_QUEUE=events \ + --secure-environment-variables \ + REDIS_KEY="$REDIS_KEY" \ + REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ + GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ + --tags \ + 'Creator=petersonjd@nih.gov' \ + Customer=NIH \ + Impact=Low \ + Project=GitHub \ + --no-wait diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml new file mode 100644 index 000000000..fd1389e8c --- /dev/null +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -0,0 +1,76 @@ +name: NIH GHMP (Dev) - Deploy Cache Builder Container + +on: + schedule: + # Run every 6 hours to keep query cache fresh. + - cron: '0 */6 * * *' + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + creds: '{"clientId":"${{ secrets.AAD_CLIENT_ID }}","clientSecret":"${{ secrets.AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AAD_TENANT_ID }}"}' + + - name: Delete existing container group + run: | + az container delete \ + --resource-group "${{ secrets.DEV_RG }}" \ + --name nihdevgithubportalcb \ + --yes 2>/dev/null || true + + - name: Create cache builder container + env: + REGISTRY_SERVER: ${{ secrets.DEV_REGISTRY_SERVER }} + REGISTRY_USER: ${{ secrets.DEV_REGISTRY_USER }} + REGISTRY_PASS: ${{ secrets.DEV_REGISTRY_PASS }} + REDIS_TLS_HOST: ${{ secrets.DEV_REDIS_TLS_HOST }} + REDIS_KEY: ${{ secrets.DEV_REDIS_KEY }} + POSTGRES_HOST: ${{ secrets.DEV_POSTGRES_HOST }} + POSTGRES_DB: ${{ secrets.DEV_POSTGRES_DB }} + POSTGRES_USER: ${{ secrets.DEV_POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ secrets.DEV_POSTGRES_PASSWORD }} + APP_ID: ${{ secrets.DEV_GITHUB_APP_OPERATIONS_APP_ID }} + APP_KEY: ${{ secrets.DEV_GITHUB_APP_OPERATIONS_KEY }} + APP_SLUG: ${{ secrets.DEV_GITHUB_APP_OPERATIONS_SLUG }} + RG: ${{ secrets.DEV_RG }} + run: | + az container create \ + --resource-group "$RG" \ + --name nihdevgithubportalcb \ + --location centralus \ + --image "$REGISTRY_SERVER/portal:latest" \ + --registry-server "$REGISTRY_SERVER" \ + --registry-username "$REGISTRY_USER" \ + --registry-password "$REGISTRY_PASS" \ + --command-line "node /usr/src/repos/jobs/refreshQueryCache.js" \ + --restart-policy OnFailure \ + --os-type Linux \ + --cpu 1 \ + --memory 1.5 \ + --ip-address Public \ + --ports 443 \ + --environment-variables \ + REDIS_TLS_HOST="$REDIS_TLS_HOST" \ + REDIS_PORT=6380 \ + REPOS_POSTGRES_DATABASE="$POSTGRES_DB" \ + REPOS_POSTGRES_HOST="$POSTGRES_HOST" \ + REPOS_POSTGRES_USER="$POSTGRES_USER" \ + REPOS_POSTGRES_SSL=false \ + GITHUB_ORGANIZATIONS_SOURCE=postgres \ + GITHUB_APP_OPERATIONS_APP_ID="$APP_ID" \ + GITHUB_APP_OPERATIONS_SLUG="$APP_SLUG" \ + --secure-environment-variables \ + REDIS_KEY="$REDIS_KEY" \ + REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ + GITHUB_APP_OPERATIONS_KEY="$APP_KEY" \ + --tags \ + 'Creator=petersonjd@nih.gov' \ + Customer=NIH \ + Impact=Low \ + Project=GitHub \ + --no-wait diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml new file mode 100644 index 000000000..909a167a0 --- /dev/null +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -0,0 +1,75 @@ +name: NIH GHMP (Dev) - Deploy Firehose Container + +on: + schedule: + # Restart daily at 01:00 UTC โ€” firehose has a 48h kill bit; daily restart ensures continuity. + - cron: '0 1 * * *' + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + creds: '{"clientId":"${{ secrets.AAD_CLIENT_ID }}","clientSecret":"${{ secrets.AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AAD_TENANT_ID }}"}' + + - name: Delete existing container group + run: | + az container delete \ + --resource-group "${{ secrets.DEV_RG }}" \ + --name nihdevgithubportalfh \ + --yes 2>/dev/null || true + + - name: Create firehose container + env: + REGISTRY_SERVER: ${{ secrets.DEV_REGISTRY_SERVER }} + REGISTRY_USER: ${{ secrets.DEV_REGISTRY_USER }} + REGISTRY_PASS: ${{ secrets.DEV_REGISTRY_PASS }} + REDIS_TLS_HOST: ${{ secrets.DEV_REDIS_TLS_HOST }} + REDIS_KEY: ${{ secrets.DEV_REDIS_KEY }} + POSTGRES_HOST: ${{ secrets.DEV_POSTGRES_HOST }} + POSTGRES_DB: ${{ secrets.DEV_POSTGRES_DB }} + POSTGRES_USER: ${{ secrets.DEV_POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ secrets.DEV_POSTGRES_PASSWORD }} + SERVICEBUS_CONN: ${{ secrets.DEV_SERVICEBUS_CONNECTIONSTRING }} + RG: ${{ secrets.DEV_RG }} + run: | + az container create \ + --resource-group "$RG" \ + --name nihdevgithubportalfh \ + --location centralus \ + --image "$REGISTRY_SERVER/portal:latest" \ + --registry-server "$REGISTRY_SERVER" \ + --registry-username "$REGISTRY_USER" \ + --registry-password "$REGISTRY_PASS" \ + --command-line "node /usr/src/repos/jobs/firehose.js" \ + --restart-policy OnFailure \ + --os-type Linux \ + --cpu 1 \ + --memory 1.5 \ + --ip-address Public \ + --ports 443 \ + --environment-variables \ + REDIS_TLS_HOST="$REDIS_TLS_HOST" \ + REDIS_PORT=6380 \ + REPOS_POSTGRES_DATABASE="$POSTGRES_DB" \ + REPOS_POSTGRES_HOST="$POSTGRES_HOST" \ + REPOS_POSTGRES_USER="$POSTGRES_USER" \ + REPOS_POSTGRES_SSL=false \ + GITHUB_ORGANIZATIONS_FILE=../env-orgs.json \ + GITHUB_ORGANIZATIONS_SOURCE=postgres \ + GITHUB_WEBHOOKS_PROVIDER=servicebus \ + GITHUB_WEBHOOKS_SERVICEBUS_QUEUE=events \ + --secure-environment-variables \ + REDIS_KEY="$REDIS_KEY" \ + REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ + GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ + --tags \ + 'Creator=petersonjd@nih.gov' \ + Customer=NIH \ + Impact=Low \ + Project=GitHub \ + --no-wait diff --git a/infra/aci/prod-cachebuilder.yml b/infra/aci/prod-cachebuilder.yml new file mode 100644 index 000000000..79741b93c --- /dev/null +++ b/infra/aci/prod-cachebuilder.yml @@ -0,0 +1,70 @@ +# Reference configuration for nihgithubportalcb (production cache builder) +# Deployed by .github/workflows/main_nihgithubportalcb.yml +# Do not deploy this file directly โ€” secrets must come from GitHub Secrets. +# +# GitHub Secrets required for deployment: +# PROD_REGISTRY_SERVER, PROD_REGISTRY_USER, PROD_REGISTRY_PASS +# PROD_REDIS_TLS_HOST, PROD_REDIS_KEY +# PROD_POSTGRES_HOST, PROD_POSTGRES_DB, PROD_POSTGRES_USER, PROD_POSTGRES_PASSWORD +# PROD_GITHUB_APP_OPERATIONS_APP_ID, PROD_GITHUB_APP_OPERATIONS_KEY, PROD_GITHUB_APP_OPERATIONS_SLUG +apiVersion: '2021-09-01' +location: centralus +name: nihgithubportalcb +properties: + containers: + - name: nihgithubportalcb + properties: + command: + - node + - /usr/src/repos/jobs/refreshQueryCache.js + environmentVariables: + - name: REDIS_TLS_HOST + value: + - name: REDIS_PORT + value: '6380' + - name: REPOS_POSTGRES_DATABASE + value: + - name: REPOS_POSTGRES_HOST + value: + - name: REPOS_POSTGRES_USER + value: + - name: REPOS_POSTGRES_SSL + value: 'false' + - name: GITHUB_ORGANIZATIONS_SOURCE + value: postgres + - name: GITHUB_APP_OPERATIONS_APP_ID + value: + - name: GITHUB_APP_OPERATIONS_SLUG + value: + - name: REDIS_KEY + secureValue: + - name: REPOS_POSTGRES_PASSWORD + secureValue: + - name: GITHUB_APP_OPERATIONS_KEY + secureValue: + image: /portal:latest + ports: + - port: 443 + protocol: TCP + resources: + requests: + cpu: 1.0 + memoryInGB: 1.5 + imageRegistryCredentials: + - server: + username: + password: + initContainers: [] + ipAddress: + ports: + - port: 443 + protocol: TCP + type: Public + osType: Linux + restartPolicy: OnFailure + sku: Standard +tags: + Creator: petersonjd@nih.gov + Customer: NIH + Impact: Low + Project: GitHub diff --git a/infra/aci/prod-firehose.yml b/infra/aci/prod-firehose.yml new file mode 100644 index 000000000..26e04e879 --- /dev/null +++ b/infra/aci/prod-firehose.yml @@ -0,0 +1,72 @@ +# Reference configuration for nihgithubportalfh (production firehose) +# Deployed by .github/workflows/main_nihgithubportalfh.yml +# Do not deploy this file directly โ€” secrets must come from GitHub Secrets. +# +# GitHub Secrets required for deployment: +# PROD_REGISTRY_SERVER, PROD_REGISTRY_USER, PROD_REGISTRY_PASS +# PROD_REDIS_TLS_HOST, PROD_REDIS_KEY +# PROD_POSTGRES_HOST, PROD_POSTGRES_DB, PROD_POSTGRES_USER, PROD_POSTGRES_PASSWORD +# PROD_SERVICEBUS_CONNECTIONSTRING +apiVersion: '2021-09-01' +location: centralus +name: nihgithubportalfh +properties: + containers: + - name: nihgithubportalfh + properties: + command: + - node + - /usr/src/repos/jobs/firehose.js + environmentVariables: + - name: REDIS_TLS_HOST + value: + - name: REDIS_PORT + value: '6380' + - name: REPOS_POSTGRES_DATABASE + value: + - name: REPOS_POSTGRES_HOST + value: + - name: REPOS_POSTGRES_USER + value: + - name: REPOS_POSTGRES_SSL + value: 'false' + - name: GITHUB_ORGANIZATIONS_FILE + value: ../env-orgs.json + - name: GITHUB_ORGANIZATIONS_SOURCE + value: postgres + - name: GITHUB_WEBHOOKS_PROVIDER + value: servicebus + - name: GITHUB_WEBHOOKS_SERVICEBUS_QUEUE + value: events + - name: REDIS_KEY + secureValue: + - name: REPOS_POSTGRES_PASSWORD + secureValue: + - name: GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING + secureValue: + image: /portal:latest + ports: + - port: 443 + protocol: TCP + resources: + requests: + cpu: 1.0 + memoryInGB: 1.5 + imageRegistryCredentials: + - server: + username: + password: + initContainers: [] + ipAddress: + ports: + - port: 443 + protocol: TCP + type: Public + osType: Linux + restartPolicy: OnFailure + sku: Standard +tags: + Creator: petersonjd@nih.gov + Customer: NIH + Impact: Low + Project: GitHub diff --git a/infra/aci/staging-cachebuilder.yml b/infra/aci/staging-cachebuilder.yml new file mode 100644 index 000000000..6c7d3c5da --- /dev/null +++ b/infra/aci/staging-cachebuilder.yml @@ -0,0 +1,70 @@ +# Reference configuration for nihdevgithubportalcb (staging cache builder) +# Deployed by .github/workflows/staging_nihdevgithubportalcb.yml +# Do not deploy this file directly โ€” secrets must come from GitHub Secrets. +# +# GitHub Secrets required for deployment: +# DEV_REGISTRY_PASS ACR password +# DEV_REDIS_KEY Redis access key +# DEV_POSTGRES_PASSWORD Postgres password +# DEV_GITHUB_APP_OPERATIONS_KEY GitHub App private key (PEM) +apiVersion: '2021-09-01' +location: centralus +name: nihdevgithubportalcb +properties: + containers: + - name: nihdevgithubportalcb + properties: + command: + - node + - /usr/src/repos/jobs/refreshQueryCache.js + environmentVariables: + - name: REDIS_TLS_HOST + value: + - name: REDIS_PORT + value: '6380' + - name: REPOS_POSTGRES_DATABASE + value: + - name: REPOS_POSTGRES_HOST + value: + - name: REPOS_POSTGRES_USER + value: + - name: REPOS_POSTGRES_SSL + value: 'false' + - name: GITHUB_ORGANIZATIONS_SOURCE + value: postgres + - name: GITHUB_APP_OPERATIONS_APP_ID + value: + - name: GITHUB_APP_OPERATIONS_SLUG + value: + - name: REDIS_KEY + secureValue: + - name: REPOS_POSTGRES_PASSWORD + secureValue: + - name: GITHUB_APP_OPERATIONS_KEY + secureValue: + image: /portal:latest + ports: + - port: 443 + protocol: TCP + resources: + requests: + cpu: 1.0 + memoryInGB: 1.5 + imageRegistryCredentials: + - server: + username: + password: + initContainers: [] + ipAddress: + ports: + - port: 443 + protocol: TCP + type: Public + osType: Linux + restartPolicy: OnFailure + sku: Standard +tags: + Creator: petersonjd@nih.gov + Customer: NIH + Impact: Low + Project: GitHub diff --git a/infra/aci/staging-firehose.yml b/infra/aci/staging-firehose.yml new file mode 100644 index 000000000..c6f3dc309 --- /dev/null +++ b/infra/aci/staging-firehose.yml @@ -0,0 +1,72 @@ +# Reference configuration for nihdevgithubportalfh (staging firehose) +# Deployed by .github/workflows/staging_nihdevgithubportalfh.yml +# Do not deploy this file directly โ€” secrets must come from GitHub Secrets. +# +# GitHub Secrets required for deployment: +# DEV_REGISTRY_PASS ACR password +# DEV_REDIS_KEY Redis access key +# DEV_POSTGRES_PASSWORD Postgres password +# DEV_SERVICEBUS_CONNECTIONSTRING Full Service Bus connection string +apiVersion: '2021-09-01' +location: centralus +name: nihdevgithubportalfh +properties: + containers: + - name: nihdevgithubportalfh + properties: + command: + - node + - /usr/src/repos/jobs/firehose.js + environmentVariables: + - name: REDIS_TLS_HOST + value: + - name: REDIS_PORT + value: '6380' + - name: REPOS_POSTGRES_DATABASE + value: + - name: REPOS_POSTGRES_HOST + value: + - name: REPOS_POSTGRES_USER + value: + - name: REPOS_POSTGRES_SSL + value: 'false' + - name: GITHUB_ORGANIZATIONS_FILE + value: ../env-orgs.json + - name: GITHUB_ORGANIZATIONS_SOURCE + value: postgres + - name: GITHUB_WEBHOOKS_PROVIDER + value: servicebus + - name: GITHUB_WEBHOOKS_SERVICEBUS_QUEUE + value: events + - name: REDIS_KEY + secureValue: + - name: REPOS_POSTGRES_PASSWORD + secureValue: + - name: GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING + secureValue: + image: /portal:latest + ports: + - port: 443 + protocol: TCP + resources: + requests: + cpu: 1.0 + memoryInGB: 1.5 + imageRegistryCredentials: + - server: + username: + password: + initContainers: [] + ipAddress: + ports: + - port: 443 + protocol: TCP + type: Public + osType: Linux + restartPolicy: OnFailure + sku: Standard +tags: + Creator: petersonjd@nih.gov + Customer: NIH + Impact: Low + Project: GitHub From 572800216621db656a3b26bb491420c660a9b8a4 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 3 Jun 2026 22:12:04 -0700 Subject: [PATCH 189/209] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/main_nihgithubportalcb.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main_nihgithubportalcb.yml b/.github/workflows/main_nihgithubportalcb.yml index 97992a58e..efbf921a7 100644 --- a/.github/workflows/main_nihgithubportalcb.yml +++ b/.github/workflows/main_nihgithubportalcb.yml @@ -6,6 +6,9 @@ on: - cron: '0 */6 * * *' workflow_dispatch: +permissions: + contents: read + jobs: deploy: runs-on: ubuntu-latest From e46b8f5abee492e4f911a31ce549103b6531251a Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 3 Jun 2026 22:12:12 -0700 Subject: [PATCH 190/209] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/main_nihgithubportalfh.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml index 4445599c9..5773838d0 100644 --- a/.github/workflows/main_nihgithubportalfh.yml +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -6,6 +6,9 @@ on: - cron: '0 1 * * *' workflow_dispatch: +permissions: + contents: read + jobs: deploy: runs-on: ubuntu-latest From d0eda35253aa893220dfcf35096c34e8c7c22a8a Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 3 Jun 2026 22:12:29 -0700 Subject: [PATCH 191/209] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/staging_nihdevgithubportalcb.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index fd1389e8c..7d82e1c1c 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -6,6 +6,8 @@ on: - cron: '0 */6 * * *' workflow_dispatch: +permissions: {} + jobs: deploy: runs-on: ubuntu-latest From 385d3ef548a421ae2b810a7bf5439240906cdc8a Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 3 Jun 2026 22:12:38 -0700 Subject: [PATCH 192/209] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/staging_nihdevgithubportalfh.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index 909a167a0..ff6c574d4 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -6,6 +6,9 @@ on: - cron: '0 1 * * *' workflow_dispatch: +permissions: + contents: read + jobs: deploy: runs-on: ubuntu-latest From fb4b9de48259670dff876f60a20dad3f8fd7a9d2 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Fri, 5 Jun 2026 22:20:36 +0000 Subject: [PATCH 193/209] fix: switch ACI workflows to OIDC federated auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace service principal client secret with OIDC federated credential (client-id + tenant-id + subscription-id). Evergreen โ€” no secret expiry. --- .github/workflows/main_nihgithubportalcb.yml | 5 ++++- .github/workflows/main_nihgithubportalfh.yml | 5 ++++- .github/workflows/staging_nihdevgithubportalcb.yml | 8 ++++++-- .github/workflows/staging_nihdevgithubportalfh.yml | 5 ++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main_nihgithubportalcb.yml b/.github/workflows/main_nihgithubportalcb.yml index efbf921a7..ce8247a62 100644 --- a/.github/workflows/main_nihgithubportalcb.yml +++ b/.github/workflows/main_nihgithubportalcb.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: permissions: + id-token: write contents: read jobs: @@ -17,7 +18,9 @@ jobs: - name: Azure Login uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: - creds: '{"clientId":"${{ secrets.PROD_AAD_CLIENT_ID }}","clientSecret":"${{ secrets.PROD_AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.PROD_AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.PROD_AAD_TENANT_ID }}"}' + client-id: ${{ secrets.PROD_AAD_CLIENT_ID }} + tenant-id: ${{ secrets.PROD_AAD_TENANT_ID }} + subscription-id: ${{ secrets.PROD_AAD_SUBSCRIPTION_ID }} - name: Delete existing container group run: | diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml index 5773838d0..9ca8d7d63 100644 --- a/.github/workflows/main_nihgithubportalfh.yml +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: permissions: + id-token: write contents: read jobs: @@ -17,7 +18,9 @@ jobs: - name: Azure Login uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: - creds: '{"clientId":"${{ secrets.PROD_AAD_CLIENT_ID }}","clientSecret":"${{ secrets.PROD_AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.PROD_AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.PROD_AAD_TENANT_ID }}"}' + client-id: ${{ secrets.PROD_AAD_CLIENT_ID }} + tenant-id: ${{ secrets.PROD_AAD_TENANT_ID }} + subscription-id: ${{ secrets.PROD_AAD_SUBSCRIPTION_ID }} - name: Delete existing container group run: | diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index 7d82e1c1c..380b82e2e 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -6,7 +6,9 @@ on: - cron: '0 */6 * * *' workflow_dispatch: -permissions: {} +permissions: + id-token: write + contents: read jobs: deploy: @@ -16,7 +18,9 @@ jobs: - name: Azure Login uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: - creds: '{"clientId":"${{ secrets.AAD_CLIENT_ID }}","clientSecret":"${{ secrets.AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AAD_TENANT_ID }}"}' + client-id: ${{ secrets.AAD_CLIENT_ID }} + tenant-id: ${{ secrets.AAD_TENANT_ID }} + subscription-id: ${{ secrets.AAD_SUBSCRIPTION_ID }} - name: Delete existing container group run: | diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index ff6c574d4..8e24cf919 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: permissions: + id-token: write contents: read jobs: @@ -17,7 +18,9 @@ jobs: - name: Azure Login uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: - creds: '{"clientId":"${{ secrets.AAD_CLIENT_ID }}","clientSecret":"${{ secrets.AAD_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AAD_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AAD_TENANT_ID }}"}' + client-id: ${{ secrets.AAD_CLIENT_ID }} + tenant-id: ${{ secrets.AAD_TENANT_ID }} + subscription-id: ${{ secrets.AAD_SUBSCRIPTION_ID }} - name: Delete existing container group run: | From 8f7c679f22075c3b03131d8900bda6f65ee7b8ca Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sat, 6 Jun 2026 00:30:07 +0000 Subject: [PATCH 194/209] fix: correct az container create flags --- .github/workflows/main_nihgithubportalcb.yml | 8 ++------ .github/workflows/main_nihgithubportalfh.yml | 8 ++------ .github/workflows/staging_nihdevgithubportalcb.yml | 8 ++------ .github/workflows/staging_nihdevgithubportalfh.yml | 8 ++------ 4 files changed, 8 insertions(+), 24 deletions(-) diff --git a/.github/workflows/main_nihgithubportalcb.yml b/.github/workflows/main_nihgithubportalcb.yml index ce8247a62..c0c892257 100644 --- a/.github/workflows/main_nihgithubportalcb.yml +++ b/.github/workflows/main_nihgithubportalcb.yml @@ -50,7 +50,7 @@ jobs: --name nihgithubportalcb \ --location centralus \ --image "$REGISTRY_SERVER/portal:latest" \ - --registry-server "$REGISTRY_SERVER" \ + --registry-login-server "$REGISTRY_SERVER" \ --registry-username "$REGISTRY_USER" \ --registry-password "$REGISTRY_PASS" \ --command-line "node /usr/src/repos/jobs/refreshQueryCache.js" \ @@ -74,9 +74,5 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_APP_OPERATIONS_KEY="$APP_KEY" \ - --tags \ - 'Creator=petersonjd@nih.gov' \ - Customer=NIH \ - Impact=Low \ - Project=GitHub \ + --tags 'Creator=petersonjd@nih.gov' Customer=NIH Impact=Low Project=GitHub \ --no-wait diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml index 9ca8d7d63..8b0e757b3 100644 --- a/.github/workflows/main_nihgithubportalfh.yml +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -48,7 +48,7 @@ jobs: --name nihgithubportalfh \ --location centralus \ --image "$REGISTRY_SERVER/portal:latest" \ - --registry-server "$REGISTRY_SERVER" \ + --registry-login-server "$REGISTRY_SERVER" \ --registry-username "$REGISTRY_USER" \ --registry-password "$REGISTRY_PASS" \ --command-line "node /usr/src/repos/jobs/firehose.js" \ @@ -73,9 +73,5 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ - --tags \ - 'Creator=petersonjd@nih.gov' \ - Customer=NIH \ - Impact=Low \ - Project=GitHub \ + --tags 'Creator=petersonjd@nih.gov' Customer=NIH Impact=Low Project=GitHub \ --no-wait diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index 380b82e2e..c2fdc11b3 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -50,7 +50,7 @@ jobs: --name nihdevgithubportalcb \ --location centralus \ --image "$REGISTRY_SERVER/portal:latest" \ - --registry-server "$REGISTRY_SERVER" \ + --registry-login-server "$REGISTRY_SERVER" \ --registry-username "$REGISTRY_USER" \ --registry-password "$REGISTRY_PASS" \ --command-line "node /usr/src/repos/jobs/refreshQueryCache.js" \ @@ -74,9 +74,5 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_APP_OPERATIONS_KEY="$APP_KEY" \ - --tags \ - 'Creator=petersonjd@nih.gov' \ - Customer=NIH \ - Impact=Low \ - Project=GitHub \ + --tags 'Creator=petersonjd@nih.gov' Customer=NIH Impact=Low Project=GitHub \ --no-wait diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index 8e24cf919..c234f5dc2 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -48,7 +48,7 @@ jobs: --name nihdevgithubportalfh \ --location centralus \ --image "$REGISTRY_SERVER/portal:latest" \ - --registry-server "$REGISTRY_SERVER" \ + --registry-login-server "$REGISTRY_SERVER" \ --registry-username "$REGISTRY_USER" \ --registry-password "$REGISTRY_PASS" \ --command-line "node /usr/src/repos/jobs/firehose.js" \ @@ -73,9 +73,5 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ - --tags \ - 'Creator=petersonjd@nih.gov' \ - Customer=NIH \ - Impact=Low \ - Project=GitHub \ + --tags 'Creator=petersonjd@nih.gov' Customer=NIH Impact=Low Project=GitHub \ --no-wait From 035d5a159235ee5e58eb6ecf10bdcf161e9f8b88 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sat, 6 Jun 2026 00:35:35 +0000 Subject: [PATCH 195/209] fix: remove --tags from az container create (unsupported flag) --- .github/workflows/main_nihgithubportalcb.yml | 1 - .github/workflows/main_nihgithubportalfh.yml | 1 - .github/workflows/staging_nihdevgithubportalcb.yml | 1 - .github/workflows/staging_nihdevgithubportalfh.yml | 1 - 4 files changed, 4 deletions(-) diff --git a/.github/workflows/main_nihgithubportalcb.yml b/.github/workflows/main_nihgithubportalcb.yml index c0c892257..5fe19ed73 100644 --- a/.github/workflows/main_nihgithubportalcb.yml +++ b/.github/workflows/main_nihgithubportalcb.yml @@ -74,5 +74,4 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_APP_OPERATIONS_KEY="$APP_KEY" \ - --tags 'Creator=petersonjd@nih.gov' Customer=NIH Impact=Low Project=GitHub \ --no-wait diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml index 8b0e757b3..427f5a5c0 100644 --- a/.github/workflows/main_nihgithubportalfh.yml +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -73,5 +73,4 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ - --tags 'Creator=petersonjd@nih.gov' Customer=NIH Impact=Low Project=GitHub \ --no-wait diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index c2fdc11b3..b1a941ba9 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -74,5 +74,4 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_APP_OPERATIONS_KEY="$APP_KEY" \ - --tags 'Creator=petersonjd@nih.gov' Customer=NIH Impact=Low Project=GitHub \ --no-wait diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index c234f5dc2..084bfc50f 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -73,5 +73,4 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ - --tags 'Creator=petersonjd@nih.gov' Customer=NIH Impact=Low Project=GitHub \ --no-wait From dcf874f099173826c0c2d0357a718bb4e62bce9a Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sat, 6 Jun 2026 00:43:32 +0000 Subject: [PATCH 196/209] fix: restore --tags, move before --environment-variables to avoid CLI parse issue --- .github/workflows/main_nihgithubportalcb.yml | 1 + .github/workflows/main_nihgithubportalfh.yml | 1 + .github/workflows/staging_nihdevgithubportalcb.yml | 1 + .github/workflows/staging_nihdevgithubportalfh.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/.github/workflows/main_nihgithubportalcb.yml b/.github/workflows/main_nihgithubportalcb.yml index 5fe19ed73..09e248974 100644 --- a/.github/workflows/main_nihgithubportalcb.yml +++ b/.github/workflows/main_nihgithubportalcb.yml @@ -60,6 +60,7 @@ jobs: --memory 1.5 \ --ip-address Public \ --ports 443 \ + --tags Creator=petersonjd@nih.gov Customer=NIH Impact=Low Project=GitHub \ --environment-variables \ REDIS_TLS_HOST="$REDIS_TLS_HOST" \ REDIS_PORT=6380 \ diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml index 427f5a5c0..3e15a6863 100644 --- a/.github/workflows/main_nihgithubportalfh.yml +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -58,6 +58,7 @@ jobs: --memory 1.5 \ --ip-address Public \ --ports 443 \ + --tags Creator=petersonjd@nih.gov Customer=NIH Impact=Low Project=GitHub \ --environment-variables \ REDIS_TLS_HOST="$REDIS_TLS_HOST" \ REDIS_PORT=6380 \ diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index b1a941ba9..a72d6eade 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -60,6 +60,7 @@ jobs: --memory 1.5 \ --ip-address Public \ --ports 443 \ + --tags Creator=petersonjd@nih.gov Customer=NIH Impact=Low Project=GitHub \ --environment-variables \ REDIS_TLS_HOST="$REDIS_TLS_HOST" \ REDIS_PORT=6380 \ diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index 084bfc50f..517098297 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -58,6 +58,7 @@ jobs: --memory 1.5 \ --ip-address Public \ --ports 443 \ + --tags Creator=petersonjd@nih.gov Customer=NIH Impact=Low Project=GitHub \ --environment-variables \ REDIS_TLS_HOST="$REDIS_TLS_HOST" \ REDIS_PORT=6380 \ From d98a1ec97f9b6c8d06c47c98344b9fed430caf99 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sat, 6 Jun 2026 00:52:44 +0000 Subject: [PATCH 197/209] fix: remove --tags, not supported by az container create --- .github/workflows/main_nihgithubportalcb.yml | 1 - .github/workflows/main_nihgithubportalfh.yml | 1 - .github/workflows/staging_nihdevgithubportalcb.yml | 1 - .github/workflows/staging_nihdevgithubportalfh.yml | 1 - 4 files changed, 4 deletions(-) diff --git a/.github/workflows/main_nihgithubportalcb.yml b/.github/workflows/main_nihgithubportalcb.yml index 09e248974..5fe19ed73 100644 --- a/.github/workflows/main_nihgithubportalcb.yml +++ b/.github/workflows/main_nihgithubportalcb.yml @@ -60,7 +60,6 @@ jobs: --memory 1.5 \ --ip-address Public \ --ports 443 \ - --tags Creator=petersonjd@nih.gov Customer=NIH Impact=Low Project=GitHub \ --environment-variables \ REDIS_TLS_HOST="$REDIS_TLS_HOST" \ REDIS_PORT=6380 \ diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml index 3e15a6863..427f5a5c0 100644 --- a/.github/workflows/main_nihgithubportalfh.yml +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -58,7 +58,6 @@ jobs: --memory 1.5 \ --ip-address Public \ --ports 443 \ - --tags Creator=petersonjd@nih.gov Customer=NIH Impact=Low Project=GitHub \ --environment-variables \ REDIS_TLS_HOST="$REDIS_TLS_HOST" \ REDIS_PORT=6380 \ diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index a72d6eade..b1a941ba9 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -60,7 +60,6 @@ jobs: --memory 1.5 \ --ip-address Public \ --ports 443 \ - --tags Creator=petersonjd@nih.gov Customer=NIH Impact=Low Project=GitHub \ --environment-variables \ REDIS_TLS_HOST="$REDIS_TLS_HOST" \ REDIS_PORT=6380 \ diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index 517098297..084bfc50f 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -58,7 +58,6 @@ jobs: --memory 1.5 \ --ip-address Public \ --ports 443 \ - --tags Creator=petersonjd@nih.gov Customer=NIH Impact=Low Project=GitHub \ --environment-variables \ REDIS_TLS_HOST="$REDIS_TLS_HOST" \ REDIS_PORT=6380 \ From f5cb0b72ad42341d709cae3ad1f89bdc7e5fc5e1 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sat, 6 Jun 2026 02:49:15 +0000 Subject: [PATCH 198/209] feat: Terraform workflow and dev infra for log analytics workspace --- .cspell.json | 360 +++++++++++++------- .github/workflows/staging_terraform_dev.yml | 81 +++++ infra/terraform/dev/main.tf | 7 + infra/terraform/dev/outputs.tf | 10 + infra/terraform/dev/providers.tf | 22 ++ infra/terraform/dev/variables.tf | 22 ++ 6 files changed, 370 insertions(+), 132 deletions(-) create mode 100644 .github/workflows/staging_terraform_dev.yml create mode 100644 infra/terraform/dev/main.tf create mode 100644 infra/terraform/dev/outputs.tf create mode 100644 infra/terraform/dev/providers.tf create mode 100644 infra/terraform/dev/variables.tf diff --git a/.cspell.json b/.cspell.json index 010f0d1d1..68e1dce17 100644 --- a/.cspell.json +++ b/.cspell.json @@ -2,13 +2,23 @@ "version": "0.2", "dictionaries": ["typescript", "softwareTerms"], "ignorePaths": [ - ".git/", ".environment/**", + ".config/1espt/**", + ".config/guardian/**", + ".deploy/geneva/**", + ".deploy/sitecontainers/**", + ".npmrc*", + ".cspell.json", + ".git/", + "*pipeline*.yaml", "**/jitStaticConfiguration.json", "**/*Accounts.json", + "**/frontend/**", "**/sentiment/**", "**/thirdparty/**", "**/vendor/**", + "**/vendor.nocommit/**", + "docs/security/**", "launch.json", "config/github.gitignore.json", "default-assets-package/resources/repos-css/oss.css", @@ -20,6 +30,7 @@ "**/*.ignore_data.ts", "package*.json", ".devcontainer/nih/**", + "**/*.*ignore", "**/assets/*.xlsx", "**/known.csv" ], @@ -28,6 +39,132 @@ "words": [ "1es", "1escopilot", + "APPDIR", + "APPINSIGHTS", + "APPNAME", + "AUDITLOG", + "AZURESERVICEBUS", + "Autobuild", + "BAPI", + "BUILDID", + "CACF", + "CBFFB", + "CDOC", + "CELA", + "CLIENTID", + "CLIENTSECRET", + "CNTK", + "CODEOWNERS", + "CONNECTIONSTRING", + "CORPORATEID", + "CORPORATEIDS", + "CUSTOMSERVICE", + "Caser", + "CloudMine", + "Contoso", + "Copybara", + "DATETIME", + "DSRE", + "Decisionmaker", + "Decisionmakers", + "Dogfooding", + "ENOENT", + "Ecosyste", + "FEBDA", + "FIRSTRUNFILE", + "FOSS", + "FOSSFUND", + "FRONTDOOR", + "GHAE", + "GHEC", + "GHID", + "GHMP", + "GHPI", + "GITHUBID", + "GITHUBINSIDEMICROSOFT", + "HSTS", + "Hsts", + "IAAD", + "JWTs", + "KEYVAULT", + "KHTML", + "KUSTO", + "Kusto", + "LOCALEXTENSIONKEY", + "LOGLEVEL", + "Lockdown", + "MCAPS", + "MEMBERTOMAINTAINER", + "MSEULA", + "MSFTEULA", + "MSFTIES", + "MSRC", + "Maintainerships", + "Maluuba", + "Markdownlint", + "Metadatas", + "Microsofties", + "Millis", + "Mitigations", + "NIHGOV", + "NOASSERTION", + "Navs", + "Newtonsoft", + "Nunit", + "OIDC", + "OPENSOURCE", + "OPENSSF", + "OSPO", + "OSPO's", + "OSSF", + "OSSMSFT", + "Oids", + "Openssf", + "PGSQL", + "PREHEADER", + "PUBLISHERNAME", + "PUBLISHPROFILE", + "Palamida", + "Passcode", + "Plex", + "Provs", + "Puid", + "QUEUENAME", + "RANDO", + "REPLYTO", + "RESOURCEGROUP", + "RESOURCEGROUPNAME", + "RUNNERDATA", + "Rehydrator", + "SCIM", + "SELFSERVICE", + "SENDERPROFILE", + "SERVICEBUS", + "SSIRP", + "Satya", + "Sida", + "Sudoer", + "Thaliproject", + "Toolset", + "Tpng", + "Treateds", + "Tsvg", + "USERSETTINGS", + "Unaccepts", + "Unauthoritative", + "Uncommited", + "Unconfigured", + "Unlocker", + "Unlockers", + "Unmark", + "Uplevel", + "Upns", + "Wcag", + "Whois", + "XSTORE", + "Xcache", + "aadalias", + "aademail", "aadgraph", "aadid", "aadname", @@ -47,16 +184,14 @@ "actionsworkflowcount", "actorid", "adal", - "additionals", "addgroup", + "additionals", "adduser", "adminids", "aeahoy", "aedata", "aemetadata", - "aemsftmetadata", "aeoperations", - "aerepositorymetadata", "aesurvey", "aeutil", "agreementversion", @@ -65,34 +200,33 @@ "alreadyrestored", "aosp", "apikey", - "APPDIR", "appinsights", - "APPINSIGHTS", - "APPNAME", "approvalnotes", "approvedbycorporateid", "approvedtime", + "appsettings", + "aquasecurity", "archivedat", "aspnet", "auditlog", - "AUDITLOG", "auditlogrecord", "autoarchive", "autobuild", - "Autobuild", + "autofetch", "azdo", "azure", "azuread", "azureappservice", + "azurecli", "azurecr", "azurefrontdoor", + "azurelinux", "azurelogo", "azurequeue", "azurequeues", "azurewebsites", - "AZURESERVICEBUS", "backoff", - "BAPI", + "bcdr", "blockui", "bootswatch", "bootup", @@ -100,23 +234,21 @@ "breakingchangereviewrequired", "browserconfig", "builddir", - "BUILDID", "buildrootdir", "buildscript", "buildscriptdir", + "bunx", "byid", "byidpriv", "byidvis", "byuser", - "CACF", - "Caser", - "CBFFB", - "CDOC", - "CELA", + "centralus", "champscount", "champstatus", "checkmarks", + "chokepoint", "chromedriver", + "citcs", "citus", "citusdata", "classificationdelegated", @@ -128,17 +260,13 @@ "classpath", "cleanupblobs", "cleanupinvites", - "cleanupkeys", "cleanuptokens", - "CLIENTID", - "CLIENTSECRET", + "clickjacking", "closedtime", "cloudmine", - "CloudMine", "clsdir", "clust", "cnames", - "CNTK", "codeofconductcoursecompleted", "codeofconductmentor", "codepath", @@ -154,9 +282,7 @@ "comms", "companyinternalpackagename", "connectiondata", - "CONNECTIONSTRING", "contoso", - "Contoso", "contosodev", "contosoenterprise", "contributesettings", @@ -168,24 +294,22 @@ "copilotagreement", "copilotprod", "copilotrequest", - "Copybara", "corpnet", - "corporatealias", "corporatecount", "corporatedev", "corporateid", - "CORPORATEID", - "CORPORATEIDS", "corporatemail", "corporatename", "corporateprod", "corporateusername", + "countif", "countuse", "createdat", "creategithubaccount", "creds", "credscan", - "CUSTOMSERVICE", + "croncheckdate", + "cwes", "dailyblob", "dangerouslysetinnerhtml", "datalake", @@ -193,13 +317,13 @@ "datamonthiso", "datasharing", "datatable", - "DATETIME", + "datetimes", + "davidanson", "dbaeumer", "dcount", + "dcountif", "deadcode", "decisionmaker", - "Decisionmaker", - "Decisionmakers", "deepmerge", "defaultbranch", "deferreason", @@ -218,21 +342,23 @@ "devstaging", "directoryname", "directowners", + "directownerscount", + "disableid", "disablewave", "distributeonly", "distro", + "distroless", "divisionid", "dnfmit", "docfx", "docsandtemplates", "dogfooders", - "Dogfooding", "dotnetexempt", "dpkg", "dropup", - "DSRE", + "durableownershiptracking", "eastus", - "Ecosyste", + "easypath", "edgecase", "electionid", "eligibilityend", @@ -268,9 +394,11 @@ "entityid", "entitytype", "entra", + "esbenp", "esbody", "esemail", "eshead", + "esme", "etag", "eventid", "eventrecord", @@ -279,45 +407,37 @@ "existingrepoid", "existingreponame", "fakeaccesstoken", - "FEBDA", "feedscan", "fieldname", "fifteenpercent", "fillcolor", "firstconfigured", - "FIRSTRUNFILE", "flipgrid", "fontawesome", "fontname", + "footgun", "forceopen", "forkscount", "fortawesome", - "FOSS", - "FOSSFUND", "fossfundabout", "fossfundsharing", - "FRONTDOOR", "frontload", "fullname", - "GHAE", "ghas", "ghavatar", "ghcrawler", "ghec", - "GHEC", "ghecemu", "ghecemustatus", "ghecemuusername", "gheclogin", "ghid", - "GHID", - "GHMP", "ghname", "ghossapis", "ghowners", - "GHPI", "ghpimigrationphase", "ghrp", + "ghsa", "gimsvc", "githubae", "githubaeis", @@ -328,15 +448,16 @@ "githubemployeelink", "githubemu", "githubid", - "GITHUBID", - "GITHUBINSIDEMICROSOFT", "githublogin", "githuborg", + "githubprod", "githubteams", "gittemp", "glyphicon", "godo", "goodfirstissue", + "goprivate", + "goproxy", "grantedtime", "graphviz", "hackathon", @@ -347,22 +468,24 @@ "haspages", "hasprojects", "haswiki", + "healthz", "hierarchynames", "hierarchytext", "highcharts", + "hitdttm", "hsts", - "Hsts", - "HSTS", + "httplogging", "hubber", "hubbers", "hubot", - "IAAD", "ictext", "identicons", "idtoken", + "ifexists", "iitemp", "inclusivity", "indiv", + "ingestor", "initdb", "initialrepositoryhomepage", "innersource", @@ -372,6 +495,7 @@ "insideadmin", "insideread", "insidewrite", + "installationid", "intelli", "internalcontent", "internalissuescreated", @@ -379,7 +503,6 @@ "internalpullrequestsmerged", "internalpullrequestsopened", "ipcpath", - "ipscan", "ischamp", "isempty", "isnotempty", @@ -394,6 +517,7 @@ "istest", "jabberpl", "jeffwilcox", + "jetbrains", "jitgrants", "joblog", "jobname", @@ -402,19 +526,18 @@ "jsoncreated", "jwilcox", "jwks", - "JWTs", "keybytes", "keyout", "keyvault", - "KEYVAULT", - "KHTML", "kubeconfig", + "kubectl", + "kubelogin", "kusto", - "KUSTO", "labeljust", "labelloc", "languagesspoken", "latrop", + "leftanti", "leftouter", "legalcontact", "legalentities", @@ -424,15 +547,12 @@ "linkmanager", "livestream", "localextensionkey", - "LOCALEXTENSIONKEY", - "Lockdown", "lockdowncontext", "lockdownfinalized", "lockdownguid", "lockdownid", "lockdownstarted", "lockedrepodeleted", - "LOGLEVEL", "logname", "longkeyhash", "longterm", @@ -443,57 +563,55 @@ "mailwithsemicolon", "maint", "maintainercorporateids", + "maintainerdisable", "maintainerless", "maintainerlocks", "maintainersecuritygroup", - "Maintainerships", "maintainerupdated", "maintainerupdatedby", "maintainerupdatedbytext", "maints", "maluuba", - "Maluuba", "managerid", "managerunlink", - "Markdownlint", - "MCAPS", - "MEMBERTOMAINTAINER", + "maxif", + "maxpingfailures", "memex", "mergedpullscount", "metadatas", - "Metadatas", "mgmt", "microsoftarchive", + "microsoftcollaboration", "microsoftcopilot", "microsoftdevopsdojo", "microsoftdocs", "microsoftgithubtraining", "microsoftgraph", - "Microsofties", "microsoftmetadata", + "microsoftopensource", "migrationdate", "migrationstatus", "milestoned", - "Millis", + "minif", "mitigations", - "Mitigations", "mitls", "monthlycontributionactivity", + "mrmlnc", + "msal", "msapplication", "msecnd", - "MSEULA", - "MSFTEULA", - "MSFTIES", + "mseng", "msftmetadata", "msrc", - "MSRC", "mucp", "multiplegithubaccounts", + "multitenant", "myadmin", "myinfo", "myread", "mywrite", - "Navs", + "nameid", + "ndarray", "networkcount", "nevermind", "newaction", @@ -501,15 +619,16 @@ "newrepo", "newrepolockdown", "newrepolockremoved", - "nihgithubportal", - "nihgithubportalcb", - "nihgithubportalfh", "nihdevgithubportal", "nihdevgithubportalcb", + "nihdevgithubportaldb", "nihdevgithubportalfh", - "centralus", - "Newtonsoft", - "NOASSERTION", + "nihdevgithubportaltf", + "nihgithubportal", + "nihgithubportalcb", + "nihgithubportalfh", + "noauth", + "nocommit", "nodeapp", "nodenext", "noemail", @@ -518,37 +637,37 @@ "nominationcomment", "nominationid", "noninteractive", + "nosniff", "notifiedissueid", "npminitignore", "npminstallignore", "npmjs", "npmrc", "nums", - "Nunit", "octicon", + "octokitty", "odata", "offboard", "offboarded", "offboarding", "officedev", "oidc", - "OIDC", "oids", - "Oids", "okrs", "olprod", + "omggif", "onbehalfof", "onboarded", "onboarder", "onboardingchannel", "onedrive", "onees", + "onmicrosoft", "onyxgithub", "onyxgithubbot", "opencontributions", "openissuescount", "opensource", - "OPENSOURCE", "opensourcecontributions", "opensourcedirectowners", "opensourcedocs", @@ -561,8 +680,6 @@ "opensourcesite", "opensourceweb", "openssf", - "Openssf", - "OPENSSF", "openssfscorecard", "operationsnotes", "optin", @@ -597,32 +714,27 @@ "oseaew", "osmp", "ospo", - "OSPO", - "OSPO's", "ospoaks", "ospoaksjobs", "ospoj", "ospomail", "ossdev", - "OSSF", "ossftoolversion", "ossline", "ossmgmtportaldev", "ossmgmtportalprod", - "OSSMSFT", "osssite", "osstool", "outsideadmin", "outsideread", "outsidewrite", + "overlordtracking", "ownerjit", "pageview", - "Palamida", "parentid", "parentname", "parentorganizationid", "parentorganizationname", - "Passcode", "patachable", "pcontent", "permlevel", @@ -630,11 +742,9 @@ "petyan", "pglink", "pgpool", - "PGSQL", "pkey", "pkgs", "pkgtext", - "Plex", "plsql", "pmownerid", "popd", @@ -648,20 +758,17 @@ "pptext", "praction", "preheader", - "PREHEADER", "primaryorg", "privatelocked", "privatepublic", "prodstaging", "projecttype", - "Provs", + "proxied", "psql", "publicdatasharing", "publicprivate", "publishedaction", - "PUBLISHERNAME", - "PUBLISHPROFILE", - "Puid", + "pugbeautify", "pullmerges", "pullrequestreview", "pullrequests", @@ -675,21 +782,20 @@ "pypi", "qcuser", "querycache", - "QUEUENAME", "rainycloud", - "RANDO", "rankdir", "ratelimit", "rcce", + "readyz", "rebaseable", "rehydrator", - "Rehydrator", "reimplementation", "reldir", "removeothergithubaccount", - "REPLYTO", "repocount", "repodisablebranchprotections", + "repodisabled", + "repodisabledate", "repodisableoutsidecollaborators", "repoid", "repoidifyouhaveit", @@ -721,15 +827,14 @@ "resave", "resaved", "resaving", - "RESOURCEGROUP", - "RESOURCEGROUPNAME", "respos", "restapi", "revokedbycorporateid", "rootdir", "rubygem", "rubygems", - "RUNNERDATA", + "ruleset", + "rulesets", "runtimes", "samplescollaboratorusername", "samplescontact", @@ -737,9 +842,8 @@ "samplespayloadcollectionprod", "sampleswebhookurl", "samplevault", - "Satya", "scansummary", - "SCIM", + "scipy", "scorecardreprocessrequest", "secretbox", "secretless", @@ -748,13 +852,10 @@ "securityevents", "securitygroupalias", "selfid", - "SELFSERVICE", - "SENDERPROFILE", "senttoapprovers", "serviceaccount", "serviceaccountmail", "servicebus", - "SERVICEBUS", "servicegroupid", "servicegroupname", "serviceid", @@ -762,6 +863,7 @@ "servicenames", "serviceshortname", "servicetree", + "servicetreecount", "servicetreedelegated", "servicetreeexempt", "servicetreeexemptdetails", @@ -776,25 +878,32 @@ "setupbycorporateusername", "setupdate", "sghi", + "sgmembercount", + "shadowit", "shortcutting", "shouldrestore", "showids", "shuf", - "Sida", "signin", "signoff", "signout", "signup", + "sitecontainer", + "sitecontainers", + "skus", + "smartcard", + "smashgg", "socialimages", "socialmediaimages", + "softdelete", "sortedkeys", "speakingavailability", "specialteams", - "SSIRP", "sslify", "standardsredirect", "stargazerscount", "startclean", + "startgg", "startofday", "startright", "startswith", @@ -803,7 +912,6 @@ "stid", "studyconsented", "subscriberscount", - "Sudoer", "sudoteamjit", "syncclassification", "syncservicetree", @@ -817,9 +925,9 @@ "teammembercache", "teamname", "teamslug", + "tenantid", "testmail", "testplan", - "Thaliproject", "thirdparty", "thirdpartyavatar", "thirdpartycount", @@ -836,30 +944,24 @@ "timezoneoffset", "tlink", "tolower", - "Toolset", "toscalar", + "tostring", "totalcount", "touchedtime", "toupper", - "Tpng", "treatedconsent", "treateddirectmanager", - "Treateds", "tsbuild", - "Tsvg", + "tfstate", "twentypercent", "typeahead", "typeaheadjs", "uitable", "uitablefilter", - "Unaccepts", "unactivated", "unadopted", "unarchived", - "Unauthoritative", - "Uncommited", "unconfigured", - "Unconfigured", "unconfirmedorganizationname", "undefinedtagthing", "unignored", @@ -868,13 +970,11 @@ "unlinkexitsurvey", "unlockable", "unlockedbyid", - "Unlocker", - "Unlockers", "unlockfinalized", "unlockstarted", "unmap", "unmark", - "Unmark", + "unnest", "unsign", "unzipper", "updatedat", @@ -882,42 +982,38 @@ "updatedbyid", "updatedbyusername", "updateddate", - "Uplevel", - "Upns", "upserting", "usercorporateid", "usercorporateusername", "userid", "userlogin", "usersettings", - "USERSETTINGS", "usertype", "userusername", + "userwarned", "viewname", "visitgithubae", + "vite", "volumefile", "voteattest", "vsts", "vststeam", "waitingforcustomer", - "waitlist", + "warndate", "watcherscount", - "Wcag", "webapps", "webcontext", "webfonts", "webhoooks", "welcomeemailsent", "whois", - "Whois", "withmaintainers", "withservicetree", "withsource", "wixtoolset", + "wwwroot", "xamarinhq", - "Xcache", "xlink", - "XSTORE", "xtable", "yamls", "yml" diff --git a/.github/workflows/staging_terraform_dev.yml b/.github/workflows/staging_terraform_dev.yml new file mode 100644 index 000000000..8067d61e0 --- /dev/null +++ b/.github/workflows/staging_terraform_dev.yml @@ -0,0 +1,81 @@ +name: NIH GHMP (Dev) - Terraform + +on: + push: + branches: + - staging + paths: + - 'infra/terraform/dev/**' + workflow_dispatch: + inputs: + action: + description: 'Terraform action to run' + required: true + default: 'plan' + type: choice + options: + - plan + - apply + +permissions: + id-token: write + contents: read + +jobs: + terraform: + runs-on: ubuntu-latest + + env: + ARM_CLIENT_ID: ${{ secrets.AAD_CLIENT_ID }} + ARM_TENANT_ID: ${{ secrets.AAD_TENANT_ID }} + ARM_SUBSCRIPTION_ID: ${{ secrets.AAD_SUBSCRIPTION_ID }} + ARM_USE_OIDC: 'true' + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + client-id: ${{ secrets.AAD_CLIENT_ID }} + tenant-id: ${{ secrets.AAD_TENANT_ID }} + subscription-id: ${{ secrets.AAD_SUBSCRIPTION_ID }} + + - name: Setup Terraform + uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3 + + - name: Terraform Init + working-directory: infra/terraform/dev + run: | + terraform init \ + -backend-config="resource_group_name=${{ secrets.DEV_RG }}" \ + -backend-config="storage_account_name=${{ secrets.DEV_TF_STORAGE_ACCOUNT }}" \ + -backend-config="container_name=${{ secrets.DEV_TF_STORAGE_CONTAINER }}" \ + -backend-config="key=dev/terraform.tfstate" + + - name: Terraform Plan + working-directory: infra/terraform/dev + run: | + terraform plan \ + -var="resource_group_name=${{ secrets.DEV_RG }}" + + - name: Terraform Apply + if: ${{ github.event_name == 'push' || github.event.inputs.action == 'apply' }} + working-directory: infra/terraform/dev + run: | + terraform apply -auto-approve \ + -var="resource_group_name=${{ secrets.DEV_RG }}" + + - name: Export outputs to GitHub Secrets + if: ${{ github.event_name == 'push' || github.event.inputs.action == 'apply' }} + working-directory: infra/terraform/dev + env: + # Fine-grained PAT with: Contents=read, Secrets=read/write, scoped to this repo. + # Store as GitHub Secret: GH_SECRETS_PAT + GH_TOKEN: ${{ secrets.GH_SECRETS_PAT }} + run: | + WORKSPACE_ID=$(terraform output -raw workspace_id) + PRIMARY_KEY=$(terraform output -raw primary_shared_key) + gh secret set DEV_LOG_ANALYTICS_WORKSPACE_ID --body "$WORKSPACE_ID" + gh secret set DEV_LOG_ANALYTICS_WORKSPACE_KEY --body "$PRIMARY_KEY" diff --git a/infra/terraform/dev/main.tf b/infra/terraform/dev/main.tf new file mode 100644 index 000000000..9d5df08b2 --- /dev/null +++ b/infra/terraform/dev/main.tf @@ -0,0 +1,7 @@ +resource "azurerm_log_analytics_workspace" "main" { + name = var.log_analytics_workspace_name + location = var.location + resource_group_name = var.resource_group_name + sku = "PerGB2018" + retention_in_days = var.log_retention_days +} diff --git a/infra/terraform/dev/outputs.tf b/infra/terraform/dev/outputs.tf new file mode 100644 index 000000000..473ccf270 --- /dev/null +++ b/infra/terraform/dev/outputs.tf @@ -0,0 +1,10 @@ +output "workspace_id" { + description = "Workspace ID โ€” store as GitHub Secret DEV_LOG_ANALYTICS_WORKSPACE_ID" + value = azurerm_log_analytics_workspace.main.workspace_id +} + +output "primary_shared_key" { + description = "Primary key โ€” store as GitHub Secret DEV_LOG_ANALYTICS_WORKSPACE_KEY" + value = azurerm_log_analytics_workspace.main.primary_shared_key + sensitive = true +} diff --git a/infra/terraform/dev/providers.tf b/infra/terraform/dev/providers.tf new file mode 100644 index 000000000..104cec937 --- /dev/null +++ b/infra/terraform/dev/providers.tf @@ -0,0 +1,22 @@ +terraform { + required_version = ">= 1.5" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.110" + } + } + + # Backend config is supplied at init time via -backend-config flags. + # Required keys: storage_account_name, container_name, resource_group_name, key + backend "azurerm" {} +} + +provider "azurerm" { + features {} + + # Authenticates via OIDC federated identity (no client secret). + # ARM_CLIENT_ID, ARM_TENANT_ID, ARM_SUBSCRIPTION_ID are set from env by the workflow. + use_oidc = true +} diff --git a/infra/terraform/dev/variables.tf b/infra/terraform/dev/variables.tf new file mode 100644 index 000000000..d85944f10 --- /dev/null +++ b/infra/terraform/dev/variables.tf @@ -0,0 +1,22 @@ +variable "resource_group_name" { + description = "Name of the dev Azure resource group" + type = string +} + +variable "location" { + description = "Azure region for all resources" + type = string + default = "centralus" +} + +variable "log_analytics_workspace_name" { + description = "Name for the Log Analytics workspace" + type = string + default = "nihdevgithubportal-logs" +} + +variable "log_retention_days" { + description = "Number of days to retain logs" + type = number + default = 30 +} From 2427c1bfab1cc82706b7f3be9dc0fb1c6719746f Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sun, 7 Jun 2026 02:36:36 +0000 Subject: [PATCH 199/209] ci: migrate all workflows to OIDC; add prod ACR build; auto-deploy ACIs on image push MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - staging_create_acr_image.yml: replace docker/login-action (user/pass) with azure/login OIDC + az acr login; add permissions block - main_create_acr_image.yml: new workflow mirroring staging for mainโ†’prod ACR - staging/main ACI workflows: remove schedule triggers; add workflow_run trigger so ACI redeploys on new image push; add success guard; replace DEV/PROD_REGISTRY_USER/PASS secrets with az acr credential show at runtime - staging_nihdevgithubportal.yml + main_nihgithubportal.yml: replace publish-profile secrets with azure/login OIDC in deploy job - PLAN.md: add GitHub Actions Secret Reduction section; record decisions Secrets that can now be deleted: DEV_REGISTRY_USER, DEV_REGISTRY_PASS, PROD_REGISTRY_USER, PROD_REGISTRY_PASS, AZUREAPPSERVICE_PUBLISHPROFILE_34824FEBDA0F4C8CACF5CB97111CBFFB, AZUREAPPSERVICE_PUBLISHPROFILE_990190F22A5149AC859307273BAE196C --- .github/workflows/main_create_acr_image.yml | 41 ++ .github/workflows/main_nihgithubportal.yml | 221 ++++--- .github/workflows/main_nihgithubportalcb.yml | 13 +- .github/workflows/main_nihgithubportalfh.yml | 13 +- .../workflows/staging_create_acr_image.yml | 40 +- .../workflows/staging_nihdevgithubportal.yml | 221 ++++--- .../staging_nihdevgithubportalcb.yml | 13 +- .../staging_nihdevgithubportalfh.yml | 13 +- PLAN.md | 589 ++++++++++++++++++ 9 files changed, 985 insertions(+), 179 deletions(-) create mode 100644 .github/workflows/main_create_acr_image.yml create mode 100644 PLAN.md diff --git a/.github/workflows/main_create_acr_image.yml b/.github/workflows/main_create_acr_image.yml new file mode 100644 index 000000000..01f0fbaf5 --- /dev/null +++ b/.github/workflows/main_create_acr_image.yml @@ -0,0 +1,41 @@ +name: NIH GHMP Container (Prod) - Build & Register + +on: + workflow_dispatch: + push: + branches: + - main + paths: + - 'Dockerfile' + - 'jobs/**' + - 'business/**' + - 'lib/**' + - 'config/**' + - 'interfaces/**' + - 'package.json' + - 'bun.lock' + - 'tsconfig.json' + +permissions: + id-token: write + contents: read + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + client-id: ${{ secrets.PROD_AAD_CLIENT_ID }} + tenant-id: ${{ secrets.PROD_AAD_TENANT_ID }} + subscription-id: ${{ secrets.PROD_AAD_SUBSCRIPTION_ID }} + - name: Login to ACR + env: + REGISTRY_SERVER: ${{ secrets.PROD_REGISTRY_SERVER }} + run: az acr login --name "${REGISTRY_SERVER%%.*}" + - run: | + docker build . -t ${{ secrets.PROD_REGISTRY_SERVER }}/portal + docker push ${{ secrets.PROD_REGISTRY_SERVER }}/portal diff --git a/.github/workflows/main_nihgithubportal.yml b/.github/workflows/main_nihgithubportal.yml index 60f5d13d1..faf27ed99 100644 --- a/.github/workflows/main_nihgithubportal.yml +++ b/.github/workflows/main_nihgithubportal.yml @@ -1,75 +1,146 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: NIH GHMP (Prod) - Build & Deploy - -on: - push: - branches: - - main - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Set up Node.js version - uses: actions/setup-node@v3 - with: - node-version: '16.x' - - - name: npm install, build, and test - run: | - npm install - npm run build --if-present - cd ./default-assets-package - npm install - npm run build - cd .. - npm run test --if-present - - - name: zip application folders - run: | - echo $PWD - ls -lah - cd .. - echo $PWD - ls -lah - tar -czf output.tar.gz ./github-portal - ls -lah - - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v3 - with: - name: node-app - path: /home/runner/work/github-portal/output.tar.gz - - deploy: - runs-on: ubuntu-latest - needs: build - environment: - name: 'Production' - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - - steps: - - name: Download artifact from build job - uses: actions/download-artifact@v3 - with: - name: node-app - - - name: Unpack tar - run: | - tar -xf output.tar.gz - ls -lah - - - name: 'Deploy to Azure Web App' - id: deploy-to-webapp - uses: azure/webapps-deploy@v2 - with: - app-name: 'nihgithubportal' - slot-name: 'Production' - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_990190F22A5149AC859307273BAE196C }} - package: . +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: NIH GHMP (Prod) - Build & Deploy + +on: + push: + branches: + - main + paths-ignore: + - '**.md' + - 'docs/**' + - 'test/**' + - '.cspell.json' + - '.config/**' + - '.vscode/**' + - '.github/ISSUE_TEMPLATE/**' + - '.github/prompts/**' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up Node.js version + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: '24.x' + + - name: Set up Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: latest + + - name: Cache bun dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install all dependencies + run: bun install --frozen-lockfile --ignore-scripts + + - name: Build + run: bun run build + + - name: Build default-assets-package + run: cd ./default-assets-package && bun install --frozen-lockfile --ignore-scripts && bun run build + + # Tests are already run by the "Lint & Test" CI workflow on every push. + # Skipping here to avoid the duplicate ~2 min cost on every deploy. + + - name: Prune dev dependencies + # Re-use the already-populated bun cache; this is a metadata-only + # operation after the cache is warm โ€” much faster than a cold install. + run: rm -rf node_modules && bun install --frozen-lockfile --ignore-scripts --production + + - name: Strip dev artifacts from node_modules + # .map and .d.ts files are only needed for compilation/debugging. + # Removing them cuts node_modules from ~508 MB to ~300 MB. + run: | + find node_modules -name '*.map' -delete + find node_modules -name '*.d.ts' -delete + + - name: Stamp build number into package.json + # continuousDeployment.js reads GITHUB_RUN_NUMBER at startup to build the + # version string (major.minor.runNumber), but that env var is only present + # during the workflow run โ€” not on the deployed App Service. Baking it into + # package.json (matching the same placeholder as container.yml) makes the + # displayed version reflect the actual GitHub Actions run number. + run: | + sed -i "s/__Build_BuildNumber__/${{ github.run_number }}/" package.json + sed -i "s/__Build_BranchName__/${{ github.ref_name }}/" package.json + sed -i "s/__Build_SourceVersion__/${{ github.sha }}/" package.json + + - name: Package application for deployment + # Deployed with WEBSITE_RUN_FROM_PACKAGE=1: the zip is mounted + # READ-ONLY and IMMUTABLE at /home/site/wwwroot on each cold start. + # There is no persistent filesystem to accumulate stale files from + # prior deployments โ€” every release is an atomic, complete state. + # This eliminates the entire class of "Kudu additive deploy leaves + # stale nested node_modules behind" bugs that plagued earlier + # deploys (e.g. the @azure/core-tracing createTracingClient crash). + # + # No node_modules.tar.gz needed โ€” Oryx is bypassed entirely. + # Required Azure App Service settings (configure once in portal): + # WEBSITE_RUN_FROM_PACKAGE=1 + # SCM_DO_BUILD_DURING_DEPLOYMENT=false + # ENABLE_ORYX_BUILD=false + # Startup Command: node /home/site/wwwroot/github-portal/dist/bin/www + run: | + mkdir -p /tmp/pkg/github-portal + + rsync -a --exclude='.git' --exclude='.github' \ + --exclude='test' --exclude='docs' \ + --exclude='default-assets-package/node_modules' \ + --exclude='default-assets-package/src' \ + . /tmp/pkg/github-portal/ + find /tmp/pkg/github-portal -name '*.test.ts' -delete + find /tmp/pkg/github-portal -name '*.spec.ts' -delete + + cd /tmp/pkg && zip -qr /tmp/node-app.zip . + ls -lah /tmp/node-app.zip + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: node-app + path: /tmp/node-app.zip + compression-level: 0 + + deploy: + runs-on: ubuntu-latest + needs: build + permissions: + id-token: write + contents: read + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: node-app + + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + client-id: ${{ secrets.PROD_AAD_CLIENT_ID }} + tenant-id: ${{ secrets.PROD_AAD_TENANT_ID }} + subscription-id: ${{ secrets.PROD_AAD_SUBSCRIPTION_ID }} + + - name: 'Deploy to Azure Web App' + id: deploy-to-webapp + uses: azure/webapps-deploy@02a81bead70021f5284939794bcec79c271ab383 # v3.0.8 + with: + app-name: 'nihgithubportal' + slot-name: 'Production' + package: node-app.zip diff --git a/.github/workflows/main_nihgithubportalcb.yml b/.github/workflows/main_nihgithubportalcb.yml index 5fe19ed73..1ad3355b2 100644 --- a/.github/workflows/main_nihgithubportalcb.yml +++ b/.github/workflows/main_nihgithubportalcb.yml @@ -1,10 +1,11 @@ name: NIH GHMP (Prod) - Deploy Cache Builder Container on: - schedule: - # Run every 6 hours to keep query cache fresh. - - cron: '0 */6 * * *' workflow_dispatch: + workflow_run: + workflows: ['NIH GHMP Container (Prod) - Build & Register'] + types: [completed] + branches: [main] permissions: id-token: write @@ -12,6 +13,7 @@ permissions: jobs: deploy: + if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest steps: @@ -32,8 +34,6 @@ jobs: - name: Create cache builder container env: REGISTRY_SERVER: ${{ secrets.PROD_REGISTRY_SERVER }} - REGISTRY_USER: ${{ secrets.PROD_REGISTRY_USER }} - REGISTRY_PASS: ${{ secrets.PROD_REGISTRY_PASS }} REDIS_TLS_HOST: ${{ secrets.PROD_REDIS_TLS_HOST }} REDIS_KEY: ${{ secrets.PROD_REDIS_KEY }} POSTGRES_HOST: ${{ secrets.PROD_POSTGRES_HOST }} @@ -45,6 +45,9 @@ jobs: APP_SLUG: ${{ secrets.PROD_GITHUB_APP_OPERATIONS_SLUG }} RG: ${{ secrets.PROD_RG }} run: | + ACR_NAME="${REGISTRY_SERVER%%.*}" + REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) + REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) az container create \ --resource-group "$RG" \ --name nihgithubportalcb \ diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml index 427f5a5c0..c237b5643 100644 --- a/.github/workflows/main_nihgithubportalfh.yml +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -1,10 +1,11 @@ name: NIH GHMP (Prod) - Deploy Firehose Container on: - schedule: - # Restart daily at 01:00 UTC โ€” firehose has a 48h kill bit; daily restart ensures continuity. - - cron: '0 1 * * *' workflow_dispatch: + workflow_run: + workflows: ['NIH GHMP Container (Prod) - Build & Register'] + types: [completed] + branches: [main] permissions: id-token: write @@ -12,6 +13,7 @@ permissions: jobs: deploy: + if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest steps: @@ -32,8 +34,6 @@ jobs: - name: Create firehose container env: REGISTRY_SERVER: ${{ secrets.PROD_REGISTRY_SERVER }} - REGISTRY_USER: ${{ secrets.PROD_REGISTRY_USER }} - REGISTRY_PASS: ${{ secrets.PROD_REGISTRY_PASS }} REDIS_TLS_HOST: ${{ secrets.PROD_REDIS_TLS_HOST }} REDIS_KEY: ${{ secrets.PROD_REDIS_KEY }} POSTGRES_HOST: ${{ secrets.PROD_POSTGRES_HOST }} @@ -43,6 +43,9 @@ jobs: SERVICEBUS_CONN: ${{ secrets.PROD_SERVICEBUS_CONNECTIONSTRING }} RG: ${{ secrets.PROD_RG }} run: | + ACR_NAME="${REGISTRY_SERVER%%.*}" + REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) + REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) az container create \ --resource-group "$RG" \ --name nihgithubportalfh \ diff --git a/.github/workflows/staging_create_acr_image.yml b/.github/workflows/staging_create_acr_image.yml index cc3c64005..94f9ba03b 100644 --- a/.github/workflows/staging_create_acr_image.yml +++ b/.github/workflows/staging_create_acr_image.yml @@ -2,18 +2,40 @@ name: NIH GHMP Container (Dev) - Build & Register on: workflow_dispatch: + push: + branches: + - staging + paths: + - 'Dockerfile' + - 'jobs/**' + - 'business/**' + - 'lib/**' + - 'config/**' + - 'interfaces/**' + - 'package.json' + - 'bun.lock' + - 'tsconfig.json' + +permissions: + id-token: write + contents: read jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: azure/docker-login@v1 - with: - login-server: ${{ secrets.DEV_REGISTRY_SERVER }} - username: ${{ secrets.DEV_REGISTRY_USER }} - password: ${{ secrets.DEV_REGISTRY_PASS }} - - run: | - docker build . -t ${{ secrets.DEV_REGISTRY_SERVER }}/portal - docker push ${{ secrets.DEV_REGISTRY_SERVER }}/portal + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + client-id: ${{ secrets.AAD_CLIENT_ID }} + tenant-id: ${{ secrets.AAD_TENANT_ID }} + subscription-id: ${{ secrets.AAD_SUBSCRIPTION_ID }} + - name: Login to ACR + env: + REGISTRY_SERVER: ${{ secrets.DEV_REGISTRY_SERVER }} + run: az acr login --name "${REGISTRY_SERVER%%.*}" + - run: | + docker build . -t ${{ secrets.DEV_REGISTRY_SERVER }}/portal + docker push ${{ secrets.DEV_REGISTRY_SERVER }}/portal diff --git a/.github/workflows/staging_nihdevgithubportal.yml b/.github/workflows/staging_nihdevgithubportal.yml index 67408efbf..9b020a1f3 100644 --- a/.github/workflows/staging_nihdevgithubportal.yml +++ b/.github/workflows/staging_nihdevgithubportal.yml @@ -1,75 +1,146 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: NIH GHMP (Dev) - Build & Deploy - -on: - push: - branches: - - staging - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up Node.js version - uses: actions/setup-node@v4 - with: - node-version: "20.x" - - - name: npm install, build, and test - run: | - npm install - npm run build --if-present - cd ./default-assets-package - npm install - npm run build - cd .. - npm run test --if-present - - - name: zip application folders - run: | - echo $PWD - ls -lah - cd .. - echo $PWD - ls -lah - tar -czf output.tar.gz ./github-portal - ls -lah - - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v4 - with: - name: node-app - path: /home/runner/work/github-portal/output.tar.gz - - deploy: - runs-on: ubuntu-latest - needs: build - environment: - name: "Production" - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - - steps: - - name: Download artifact from build job - uses: actions/download-artifact@v4 - with: - name: node-app - - - name: Unpack tar - run: | - tar -xf output.tar.gz - ls -lah - - - name: "Deploy to Azure Web App" - id: deploy-to-webapp - uses: azure/webapps-deploy@v3 - with: - app-name: "nihdevgithubportal" - slot-name: "Production" - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_34824FEBDA0F4C8CACF5CB97111CBFFB }} - package: . +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: NIH GHMP (Dev) - Build & Deploy + +on: + push: + branches: + - staging + paths-ignore: + - '**.md' + - 'docs/**' + - 'test/**' + - '.cspell.json' + - '.config/**' + - '.vscode/**' + - '.github/ISSUE_TEMPLATE/**' + - '.github/prompts/**' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up Node.js version + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: '24.x' + + - name: Set up Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: latest + + - name: Cache bun dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install all dependencies + run: bun install --frozen-lockfile --ignore-scripts + + - name: Build + run: bun run build + + - name: Build default-assets-package + run: cd ./default-assets-package && bun install --frozen-lockfile --ignore-scripts && bun run build + + # Tests are already run by the "Lint & Test" CI workflow on every push. + # Skipping here to avoid the duplicate ~2 min cost on every deploy. + + - name: Prune dev dependencies + # Re-use the already-populated bun cache; this is a metadata-only + # operation after the cache is warm โ€” much faster than a cold install. + run: rm -rf node_modules && bun install --frozen-lockfile --ignore-scripts --production + + - name: Strip dev artifacts from node_modules + # .map and .d.ts files are only needed for compilation/debugging. + # Removing them cuts node_modules from ~508 MB to ~300 MB. + run: | + find node_modules -name '*.map' -delete + find node_modules -name '*.d.ts' -delete + + - name: Stamp build number into package.json + # continuousDeployment.js reads GITHUB_RUN_NUMBER at startup to build the + # version string (major.minor.runNumber), but that env var is only present + # during the workflow run โ€” not on the deployed App Service. Baking it into + # package.json (matching the same placeholder as container.yml) makes the + # displayed version reflect the actual GitHub Actions run number. + run: | + sed -i "s/__Build_BuildNumber__/${{ github.run_number }}/" package.json + sed -i "s/__Build_BranchName__/${{ github.ref_name }}/" package.json + sed -i "s/__Build_SourceVersion__/${{ github.sha }}/" package.json + + - name: Package application for deployment + # Deployed with WEBSITE_RUN_FROM_PACKAGE=1: the zip is mounted + # READ-ONLY and IMMUTABLE at /home/site/wwwroot on each cold start. + # There is no persistent filesystem to accumulate stale files from + # prior deployments โ€” every release is an atomic, complete state. + # This eliminates the entire class of "Kudu additive deploy leaves + # stale nested node_modules behind" bugs that plagued earlier + # deploys (e.g. the @azure/core-tracing createTracingClient crash). + # + # No node_modules.tar.gz needed โ€” Oryx is bypassed entirely. + # Required Azure App Service settings (configure once in portal): + # WEBSITE_RUN_FROM_PACKAGE=1 + # SCM_DO_BUILD_DURING_DEPLOYMENT=false + # ENABLE_ORYX_BUILD=false + # Startup Command: node /home/site/wwwroot/github-portal/dist/bin/www + run: | + mkdir -p /tmp/pkg/github-portal + + rsync -a --exclude='.git' --exclude='.github' \ + --exclude='test' --exclude='docs' \ + --exclude='default-assets-package/node_modules' \ + --exclude='default-assets-package/src' \ + . /tmp/pkg/github-portal/ + find /tmp/pkg/github-portal -name '*.test.ts' -delete + find /tmp/pkg/github-portal -name '*.spec.ts' -delete + + cd /tmp/pkg && zip -qr /tmp/node-app.zip . + ls -lah /tmp/node-app.zip + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: node-app + path: /tmp/node-app.zip + compression-level: 0 + + deploy: + runs-on: ubuntu-latest + needs: build + permissions: + id-token: write + contents: read + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: node-app + + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + client-id: ${{ secrets.AAD_CLIENT_ID }} + tenant-id: ${{ secrets.AAD_TENANT_ID }} + subscription-id: ${{ secrets.AAD_SUBSCRIPTION_ID }} + + - name: 'Deploy to Azure Web App' + id: deploy-to-webapp + uses: azure/webapps-deploy@02a81bead70021f5284939794bcec79c271ab383 # v3.0.8 + with: + app-name: 'nihdevgithubportal' + slot-name: 'Production' + package: node-app.zip diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index b1a941ba9..47523097b 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -1,10 +1,11 @@ name: NIH GHMP (Dev) - Deploy Cache Builder Container on: - schedule: - # Run every 6 hours to keep query cache fresh. - - cron: '0 */6 * * *' workflow_dispatch: + workflow_run: + workflows: ['NIH GHMP Container (Dev) - Build & Register'] + types: [completed] + branches: [staging] permissions: id-token: write @@ -12,6 +13,7 @@ permissions: jobs: deploy: + if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest steps: @@ -32,8 +34,6 @@ jobs: - name: Create cache builder container env: REGISTRY_SERVER: ${{ secrets.DEV_REGISTRY_SERVER }} - REGISTRY_USER: ${{ secrets.DEV_REGISTRY_USER }} - REGISTRY_PASS: ${{ secrets.DEV_REGISTRY_PASS }} REDIS_TLS_HOST: ${{ secrets.DEV_REDIS_TLS_HOST }} REDIS_KEY: ${{ secrets.DEV_REDIS_KEY }} POSTGRES_HOST: ${{ secrets.DEV_POSTGRES_HOST }} @@ -45,6 +45,9 @@ jobs: APP_SLUG: ${{ secrets.DEV_GITHUB_APP_OPERATIONS_SLUG }} RG: ${{ secrets.DEV_RG }} run: | + ACR_NAME="${REGISTRY_SERVER%%.*}" + REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) + REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) az container create \ --resource-group "$RG" \ --name nihdevgithubportalcb \ diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index 084bfc50f..e79280606 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -1,10 +1,11 @@ name: NIH GHMP (Dev) - Deploy Firehose Container on: - schedule: - # Restart daily at 01:00 UTC โ€” firehose has a 48h kill bit; daily restart ensures continuity. - - cron: '0 1 * * *' workflow_dispatch: + workflow_run: + workflows: ['NIH GHMP Container (Dev) - Build & Register'] + types: [completed] + branches: [staging] permissions: id-token: write @@ -12,6 +13,7 @@ permissions: jobs: deploy: + if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest steps: @@ -32,8 +34,6 @@ jobs: - name: Create firehose container env: REGISTRY_SERVER: ${{ secrets.DEV_REGISTRY_SERVER }} - REGISTRY_USER: ${{ secrets.DEV_REGISTRY_USER }} - REGISTRY_PASS: ${{ secrets.DEV_REGISTRY_PASS }} REDIS_TLS_HOST: ${{ secrets.DEV_REDIS_TLS_HOST }} REDIS_KEY: ${{ secrets.DEV_REDIS_KEY }} POSTGRES_HOST: ${{ secrets.DEV_POSTGRES_HOST }} @@ -43,6 +43,9 @@ jobs: SERVICEBUS_CONN: ${{ secrets.DEV_SERVICEBUS_CONNECTIONSTRING }} RG: ${{ secrets.DEV_RG }} run: | + ACR_NAME="${REGISTRY_SERVER%%.*}" + REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) + REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) az container create \ --resource-group "$RG" \ --name nihdevgithubportalfh \ diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 000000000..355499303 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,589 @@ +# Security Improvement Plan + +Priority-ordered list of security improvements identified across this repository. + +--- + +## GitHub Actions Secret Reduction (June 2026) + +Audit of all workflow secrets against Entra ID Workload Federation (OIDC) coverage. +The repo's service principal has Contributor on both subscriptions, so stored credentials +can be replaced with dynamic Azure API calls made within the already-authenticated session. + +### โœ… Purge immediately โ€” workflows already updated + +Delete these secrets from both repos (NIHGOV/github-portal + staging env): + +| Secret | Was used in | Replacement | +| -------------------- | ------------------------------ | ----------------------------------------- | +| `DEV_REGISTRY_USER` | Build + all 2 dev ACI deploys | `az acr credential show` after OIDC login | +| `DEV_REGISTRY_PASS` | Build + all 2 dev ACI deploys | same | +| `PROD_REGISTRY_USER` | Build + all 2 prod ACI deploys | `az acr credential show` after OIDC login | +| `PROD_REGISTRY_PASS` | Build + all 2 prod ACI deploys | same | + +Prerequisite: ACR admin user must be enabled on both registries (needed by `az acr credential show`). +Alternative if admin is disabled: assign a user-assigned managed identity with AcrPull to ACI groups instead. + +### โœ… Replace with OIDC โ€” done (issue #1122) + +| Secret | Workflow | Replacement | +| ----------------------------------------------------------------- | -------------------------------- | ---------------------------------------------------- | +| `AZUREAPPSERVICE_PUBLISHPROFILE_34824FEBDA0F4C8CACF5CB97111CBFFB` | `staging_nihdevgithubportal.yml` | Add `azure/login` OIDC step; drop `publish-profile:` | +| `AZUREAPPSERVICE_PUBLISHPROFILE_990190F22A5149AC859307273BAE196C` | `main_nihgithubportal.yml` | Same | + +### Keeping as secrets (decision: June 2026) + +`AAD_CLIENT_ID`, `AAD_TENANT_ID`, `AAD_SUBSCRIPTION_ID`, `PROD_AAD_CLIENT_ID`, +`PROD_AAD_TENANT_ID`, `PROD_AAD_SUBSCRIPTION_ID` โ€” remain as encrypted secrets. +Although these are GUIDs rather than credentials, the team prefers to keep them +in the secrets store to avoid any risk of accidental exposure. + +--- + +## Terraform Infrastructure (June 2026) + +`infra/terraform/dev/` manages Azure resources in `GitHub_OpenSource_Portal_Dev`. +Long-term goal: represent the entire `GitHub_OpenSource_Portal_Dev` (and eventually +`GitHub_OpenSource_Portal`) resource group in Terraform. + +### Bootstrap (one-time, manual) + +Before the workflow can run, a storage account for Terraform state must exist: + +1. ~~Create a storage account in `GitHub_OpenSource_Portal_Dev` (e.g. `nihdevgithubportaltf`)~~ โœ… Done +2. Create a blob container in it (e.g. `tfstate`) โ€” or confirm it exists +3. Grant service principal **Storage Blob Data Contributor** on `nihdevgithubportaltf` +4. Add GitHub Secrets: + - `DEV_TF_STORAGE_ACCOUNT` โ†’ `nihdevgithubportaltf` + - `DEV_TF_STORAGE_CONTAINER` โ†’ container name (e.g. `tfstate`) + - `GH_SECRETS_PAT` โ†’ fine-grained PAT with **Secrets: read/write** and **Contents: read** on this repo (used to auto-export Terraform outputs back as GitHub Secrets) + +### Resources managed + +- [ ] `azurerm_log_analytics_workspace` โ€” `nihdevgithubportal-logs` +- [ ] After first apply: workflow automatically sets these GitHub Secrets: + - `DEV_LOG_ANALYTICS_WORKSPACE_ID` + - `DEV_LOG_ANALYTICS_WORKSPACE_KEY` + - Then wire into ACI workflows: add `--log-analytics-workspace` + `--log-analytics-workspace-key` to `az container create` + +### Future: full resource group coverage (tracked in GitHub Issues) + +- [ ] Redis Cache (`nihdevgithubportal`) โ€” see issue +- [ ] PostgreSQL Flexible Server (`nihdevgithubportaldb`) โ€” see issue +- [ ] Service Bus namespace โ€” see issue +- [ ] Container Registry โ€” see issue +- [ ] App Service (`nihdevgithubportal`) โ€” see issue +- [ ] ACI container groups (firehose, cache builder) โ€” see issue +- [ ] Repeat entire stack for `GitHub_OpenSource_Portal` (prod) โ€” see issue + +--- + +## ACI Container Deployment (June 2026) + +Replaced hardcoded-secret YAML files with GitHub Actions workflows and `infra/aci/` reference configs. + +### Staging + +- [x] Add GitHub Secret `DEV_REDIS_TLS_HOST` +- [x] Add GitHub Secret `DEV_REDIS_KEY` +- [x] Add GitHub Secret `DEV_POSTGRES_HOST` +- [x] Add GitHub Secret `DEV_POSTGRES_DB` +- [x] Add GitHub Secret `DEV_POSTGRES_USER` +- [x] Add GitHub Secret `DEV_POSTGRES_PASSWORD` +- [x] Add GitHub Secret `DEV_SERVICEBUS_CONNECTIONSTRING` +- [x] Add GitHub Secret `DEV_GITHUB_APP_OPERATIONS_APP_ID` +- [x] Add GitHub Secret `DEV_GITHUB_APP_OPERATIONS_KEY` +- [x] Add GitHub Secret `DEV_GITHUB_APP_OPERATIONS_SLUG` +- [ ] Run `staging_nihdevgithubportalfh.yml` manually โ€” verify firehose container starts and logs appear +- [ ] Run `staging_nihdevgithubportalcb.yml` manually โ€” verify cache builder runs and `portaldescription` is written to DB for ARPA-H +- [ ] Restart `nihdevgithubportal` App Service โ€” confirm ARPA-H org description shows on homepage + +### Production + +- [ ] Add GitHub Secret `PROD_RG` โ†’ `GitHub_OpenSource_Portal` +- [ ] Add GitHub Secrets `PROD_AAD_CLIENT_ID`, `PROD_AAD_CLIENT_SECRET`, `PROD_AAD_SUBSCRIPTION_ID`, `PROD_AAD_TENANT_ID` (may match existing `AAD_*` values) +- [ ] Add GitHub Secret `PROD_REDIS_TLS_HOST` +- [ ] Add GitHub Secret `PROD_REDIS_KEY` +- [ ] Add GitHub Secret `PROD_POSTGRES_HOST` +- [ ] Add GitHub Secret `PROD_POSTGRES_DB` +- [ ] Add GitHub Secret `PROD_POSTGRES_USER` +- [ ] Add GitHub Secret `PROD_POSTGRES_PASSWORD` +- [ ] Add GitHub Secret `PROD_SERVICEBUS_CONNECTIONSTRING` +- [ ] Add GitHub Secret `PROD_GITHUB_APP_OPERATIONS_APP_ID` +- [ ] Add GitHub Secret `PROD_GITHUB_APP_OPERATIONS_KEY` +- [ ] Add GitHub Secret `PROD_GITHUB_APP_OPERATIONS_SLUG` +- [ ] Run `main_nihgithubportalfh.yml` manually โ€” verify firehose starts +- [ ] Run `main_nihgithubportalcb.yml` manually โ€” verify cache builder runs + +--- + +## Completed (June 2026 โ€” GitHub Copilot agentic session) + +### โœ… Fixed admin apps page showing wrong GitHub App slug and broken "Install in new org" link (June 2026) + +`/administration/apps` displayed the slug from `GITHUB_APP_OPERATIONS_SLUG` as both the "GitHub App" and "Purpose" columns, and used that slug to build the "Install in new org" link. Two issues combined to cause the broken link and misleading display: + +1. **Wrong env var value**: `GITHUB_APP_OPERATIONS_SLUG` was set to `nihdevgithubportal-app-ops` (the old/renamed app name) instead of the current slug `dev-nih-github-management-portal`. Fix: update the App Service setting to match the actual slug shown at `github.com/organizations/NIHGOV/settings/apps/โ€ฆ`. + +2. **Code bug**: `initializeAppById` in `business/operations/core.ts` called `tokenManager.getSlugById()` for _both_ the `slug` and `friendlyName` parameters, so the "Purpose" column showed the raw slug instead of the human-readable description (e.g. "GitHub Operations") from the app's JSON config. + +Code fix: + +- `lib/github/tokenManager.ts` โ€” added `_appFriendlyNames` map; populated it alongside `_appSlugs` in `initializeApp`; added `getFriendlyNameById()` accessor +- `business/operations/core.ts` โ€” `initializeAppById` now calls `getFriendlyNameById()` for the friendlyName, falling back to the slug only when no description is configured +- `AGENTS.md` โ€” documented `GITHUB_APP_OPERATIONS_SLUG` in the required App Service settings table + +**โš ๏ธ Required before merging to main:** Verify `GITHUB_APP_OPERATIONS_SLUG` is set correctly on both App Services (`nihdevgithubportal` and `nihgithubportal`). The value must exactly match the slug shown at `github.com/organizations/NIHGOV/settings/apps/โ€ฆ` (e.g. `dev-nih-github-management-portal` on staging). An incorrect slug causes broken "Install in new org" links and silently misidentifies bot commits in `getApplicationsAsLogins()`. + +## Completed (May 2026 โ€” GitHub Copilot agentic session) + +### โœ… Fixed version always showing 8.5.0 instead of 8.5.\ (May 2026) + +`continuousDeployment.js` constructs the displayed version as `major.minor.GITHUB_RUN_NUMBER`, but `GITHUB_RUN_NUMBER` is only set during a GitHub Actions run โ€” not on the deployed App Service. The packaging step never stamped the placeholder in `package.json`, so `stripPlaceholders()` deleted it and the code fell back to the literal `pkg.version` string `8.5.0`. + +- `.github/workflows/staging_nihdevgithubportal.yml` โ€” added a "Stamp build number" step before packaging that runs `sed` to replace `__Build_BuildNumber__`, `__Build_BranchName__`, and `__Build_SourceVersion__` with `github.run_number`, `github.ref_name`, and `github.sha` respectively (same approach already used by `container.yml`) +- `.github/workflows/main_nihgithubportal.yml` โ€” same stamp step added + +### โœ… Migrated production workflow to `WEBSITE_RUN_FROM_PACKAGE=1` (May 2026) + +`main_nihgithubportal.yml` still used the legacy Kudu additive `tar.gz` deploy, which accumulates stale nested `node_modules` across deploys and causes `createTracingClient` ESM export crashes. Updated to match `staging_nihdevgithubportal.yml`: + +- Removed `tar -czf output.tar.gz` + "Unpack tar" steps; replaced with `rsync` + `zip` into `/tmp/node-app.zip` with `github-portal/` as the root entry +- Added bun dependency cache step +- Added `Strip dev artifacts` step (`find node_modules -name '*.map' -delete` + `*.d.ts`) +- Added `Stamp build number` step (fixes version display, same as staging) +- Passes `package: node-app.zip` directly to `azure/webapps-deploy` (no re-zip) +- Added bun-version: latest + comments mirroring staging + +**Still required (one-time manual action in Azure portal):** Apply the `WEBSITE_RUN_FROM_PACKAGE=1` App Service settings to `nihgithubportal` before the first deploy from `main` โ€” see ยง0 below. + +### โœ… Synced upstream microsoft/opensource-management-portal โ†’ NIHGOV:staging (PR #1099) + +Merged `microsoft/opensource-management-portal:main` into `NIHGOV/github-portal:staging` on branch `sync-upstream-main-20260527`. Resolved 7 merge conflicts, preserving NIH-specific code: + +- `config/features.json` + `config/features.types.ts` โ€” retained `allowUsersToViewLockedOrgDetails` (NIH) alongside new upstream `allowSessionFeatureFlags` +- `views/layout.pug` โ€” retained NIH's Google Analytics iframe inside upstream's new `data-csrf-token` body attribute +- `package.json` โ€” retained NIH deps (`js-yaml`, `json-2-csv`); adopted upstream `jose` upgrade +- `routes/org/index.ts` โ€” adopted upstream `stringParam()` (not NIH-specific) +- `.vscode/settings.json` โ€” deleted (honored NIH staging commit) +- `package-lock.json` โ€” replaced with `bun.lock` (see migration below) + +### โœ… Migrated from npm to bun (PR #1099) + +- All `package.json` scripts: `npm`/`npx` โ†’ `bun`/`bunx` +- Generated `bun.lock` (SHA-512 pinned, replaces `package-lock.json`) +- Generated `default-assets-package/bun.lock` +- `Dockerfile` + `Dockerfile.open`: `npm install` โ†’ `bun install --frozen-lockfile --ignore-scripts`; ENTRYPOINT updated +- `.devcontainer/devcontainer.json`: rewrote to use `mcr.microsoft.com/devcontainers/javascript-node:24`, added `oven-sh/setup-bun` and `github-cli` features, `postCreateCommand: bun install --frozen-lockfile` + +### โœ… Fixed 4 GHAS security alerts (PR #1099) + +- `api/index.ts` โ€” removed `isClientRoute()` bypasses from pre-auth and post-auth rate limiters; all routes now go through rate limiting +- `middleware/rateLimit.ts` โ€” replaced `crypto.createHmac('sha256', 'rate-limit-cache-key')` with `crypto.createHash('sha256')` (was flagged as insufficient password hash) +- `api/client/context/diagnostics.ts` โ€” wrapped handler in `getRateLimitMiddleware` to fix missing rate limit alert + +### โœ… Fixed Redis v5 breaking API changes (PR #1100) + +- `middleware/initialize.ts` โ€” removed `await redisClient.auth({password: ...})` (removed in v5); moved `password` to top-level `createClient()` option +- `middleware/session.ts` โ€” removed `await redisLegacy.auth({password: ...})`; properly awaited `redisLegacy.connect()` + +### โœ… Fixed CI/CD workflows: Node 24 + bun (PR #1101) + +- `staging_nihdevgithubportal.yml` โ€” Node 20 โ†’ 24 (match App Service runtime); `npm install` โ†’ `bun install --frozen-lockfile --ignore-scripts`; added devDep pruning before packaging; split into explicit build/test/prune steps +- `main_nihgithubportal.yml` โ€” Node 16 โ†’ 24; same npm โ†’ bun migration; bumped `actions/checkout`, `upload/download-artifact`, `webapps-deploy` to latest +- `ci.yml` โ€” added `oven-sh/setup-bun@v2`; replaced all `npm` with `bun` equivalents; Node โ†’ 24 + +Root cause: `npm install` was running with no `package-lock.json` (deleted in bun migration), so npm did unconstrained fresh resolution ignoring `bun.lock`, resulting in wrong transitive versions being deployed (caused `@azure/core-tracing`/`createTracingClient` export error on startup). + +### โœ… SHA-pinned all GitHub Actions + upgraded to latest versions + +All `uses:` references across all 10 workflow files pinned to exact commit SHAs to prevent supply-chain attacks via tag mutation: + +| Action | Old | New | +| --------------------------- | ----------- | --------------------- | +| `actions/checkout` | v2/v3/v4/v6 | `de0fac2e` (v6.0.2) | +| `actions/setup-node` | v3/v4 | `48b55a01` (v6.4.0) | +| `actions/upload-artifact` | v3/v4 | `043fb46d` (v7.0.1) | +| `actions/download-artifact` | v3/v4 | `3e5f45b2` (v8.0.1) | +| `actions/stale` | v9 | `eb5cf3af` (v10.3.0) | +| `oven-sh/setup-bun` | v2 | `0c5077e5` (v2.2.0) | +| `azure/webapps-deploy` | v2/v3 | `02a81bea` (v3) | +| `azure/login` | v1.4.6/v2 | `532459ea` (v3.0.0) | +| `Azure/cli` | v1 | `9eb25b83` (v3.0.0) | +| `azure/docker-login` | v1 | `15c4aadf` (v2) | +| `github/codeql-action` | v3 | `03e4368a` (v3.36.0) | +| `ruby/setup-ruby` | v1.127.0 | `ee211353` (v1.127.0) | +| `azure/postgresql` | v1 | `59401b78` (v1.2.0) | + +### โœ… Updated GitHub Actions: Node 20 โ†’ 24, fresher pins (June 2026) + +Follow-up pass on all 10 workflow files to eliminate Node 20 runtime warnings and bring outdated pins to current: + +| Action | Old | New | Reason | +| -------------------------- | ----------------------------- | ---------------------------------- | ------------------------------------ | +| `azure/docker-login` | `15c4aadf` (v2, Node 20) | replaced โ€” see below | Still uses Node 20; no v3 planned | +| `docker/login-action` | _(not used)_ | `650006c6` (v4.2.0, Node 24) | First-party Docker action; Node 24 | +| `ruby/setup-ruby` | `ee211353` (v1.127.0) | `afeafc3d` (v1.310.0) | 183 patch releases behind | +| `github/codeql-action` | comment said `v3` | comment updated to `v3.36.0` | SHA was correct; comment imprecise | +| `azure/webapps-deploy` | comment said `v3` | comment updated to `v3.0.8` | SHA was correct; comment imprecise | +| `azure/postgresql` | comment said `v1` | comment updated to `v1.2.0` | SHA was correct; comment imprecise | +| `docker/build-push-action` | `@v3` (no SHA, commented out) | `f9f3042f` (v7.2.0, commented out) | SHA-pinned for when it is re-enabled | + +`azure/docker-login@v2` was the sole source of Node 20 deprecation warnings โ€” its `action.yml` specifies `using: node20`. All other actions confirmed on Node 24. Replaced with `docker/login-action@v4.2.0` which is the official Docker-maintained equivalent; only interface change is `login-server:` โ†’ `registry:`. + +### โœ… Upgraded `applicationinsights` 2.9.8 โ†’ 3.15.0 (OpenTelemetry) + +Fixes `DEP0005` (`Buffer()`) and `DEP0169` (`url.parse()`) deprecation warnings on Node.js 24. Breaking API changes addressed: + +- `lib/mail/render.ts` + `render.test.ts` โ€” replaced `import type NodeClient from 'applicationinsights/out/Library/NodeClient.js'` (internal v2 path, broken in v3) with `import type { TelemetryClient } from 'applicationinsights'` +- `middleware/appInsights.ts` โ€” removed `wrapWithCorrelationContext` / `getCorrelationContext` / `startOperation` (v2 correlation model removed; v3 propagates context automatically via OpenTelemetry async hooks); removed deprecated `instrumentationKey` reference + +### โœ… Suppressed OTel/require-in-the-middle verbose log flood (May 2026) + +`applicationinsights` v3 is built on OpenTelemetry and logs every `require()` intercept to stderr at VERBOSE level, flooding Azure's ERROR log stream. + +- `middleware/appInsights.ts` โ€” added `diag.setLogger({โ€ฆ}, DiagLogLevel.NONE)` from `@opentelemetry/api` before SDK setup to silence all OTel diagnostic output +- `package.json` โ€” added `@opentelemetry/api` as a direct dependency (was transitive-only; lint rule requires explicit declaration) + +**Note:** The `DEBUG` Azure App Service env var (if set to `*` or a broad pattern) separately causes `debug`-module output from `router`, `body-parser`, `express-session`, etc. to appear as ERROR-level logs. Remove the `DEBUG` app setting in the portal to silence that flood. + +### โœ… Guarded per-request JSON.parse failures with logging + safe fallback (May 2026) + +The app was crashing on every authenticated page with `SyntaxError: Unexpected token '', "โฌU+FFFDโญ"โ€ฆ` but the error was going to stdout (INFO), invisible in Azure's ERROR log stream. + +- `middleware/business/authentication.ts` โ€” wrapped `JSON.parse(oauthToken)` in try/catch; logs to `console.error` with correlation ID and token prefix; falls back to `signoutThenSignIn()` to clear corrupted session +- `middleware/errorHandler.ts` โ€” changed primary error log from `console.log` โ†’ `console.error` so all error messages appear in Azure's ERROR stream; wrapped `JSON.parse(err.data)` in try/catch to prevent the error handler itself from crashing mid-response + +### โœ… Fixed CI test runner (vitest vs bun native runner) (May 2026) + +All 3 CI test failures were caused by `ci.yml` running `bun test` (Bun's native Jest-compatible runner) while the test files explicitly `import { describe, expect, test } from 'vitest'` and the project is configured with `vitest.config.ts`. The two runners handle `.not.toThrow()` and Chai-style assertions differently. + +- `.github/workflows/ci.yml` โ€” changed `bun test` โ†’ `bun run test` (runs `vitest run` per `package.json` scripts) +- `AGENTS.md` โ€” updated documented test command to match + +### โœ… Fixed Redis v5 `withCommandOptions` typeMapping for compressed cache (May 2026) + +Every request hitting a cached GitHub API result (org members, repos, teams) was throwing `SyntaxError: Unexpected token '', "โฌU+FFFDโญ"` traced to `RedisHelper.getObjectCompressed`. + +**Root cause:** `_redisForBuffers` was created with `{ [RESP_TYPES.BLOB_STRING]: Buffer }` but redis v5 requires the type override under a `typeMapping` key. Without it the client decoded gzip-compressed binary as UTF-8 (producing U+FFFD replacement chars), which then failed `JSON.parse` after the corrupt string bypassed gunzip via the `Z_DATA_ERROR` fallback path. + +- `lib/caching/redis.ts` โ€” changed `withCommandOptions({ [RESP_TYPES.BLOB_STRING]: Buffer })` โ†’ `withCommandOptions({ typeMapping: { [RESP_TYPES.BLOB_STRING]: Buffer } })` + +### โœ… Fixed missing and crashing octicon + hardened helper (May 2026) + +`@primer/octicons` v19 removed `primitive-dot` (renamed to `dot-fill`). The octicon helper threw an uncaught `Error` on any unknown icon name, crashing the entire Pug render and returning a 500. + +- `views/repos/index.pug`, `views/repos/repo.pug`, `views/org/team/index.pug` โ€” `primitive-dot` โ†’ `dot-fill` +- `lib/pugViewServices.ts` โ€” changed throw โ†’ `console.warn` + `return ''` so an unknown icon name renders as empty rather than crashing the page + +### โœ… Suppressed mouse-click focus ring (Edge Chromium accessibility change) (May 2026) + +Edge 102+ strengthened the default `:focus` ring to a thick double-ring (blue + white offset) for WCAG 2.1 AA compliance. Bootstrap 3 triggers `:focus` on mouse clicks (not just keyboard), making every anchor click show the heavy ring. + +- `default-assets-package/resources/repos-css/oss.css` โ€” added `a:focus:not(:focus-visible) { outline: none; }` to suppress the ring for pointer clicks while preserving it for keyboard navigation + +--- + +## High Priority + +### 0. **Before merging `staging` to `main`: apply `WEBSITE_RUN_FROM_PACKAGE=1` to `nihgithubportal` App Service** + +The production **workflow** (`main_nihgithubportal.yml`) has been updated to use zip packaging + run-from-package (see Completed section above). But the **Azure App Service itself** still needs its settings updated โ€” otherwise the first deploy from `main` will crash because the App Service still expects the old Kudu additive model. + +**If the app crash-loops with:** + +```text +SyntaxError: The requested module '@azure/core-tracing' does not provide an export named 'createTracingClient' +``` + +the App Service settings below were not yet applied. Apply them and redeploy. + +#### Required one-time settings (Azure portal โ†’ `nihgithubportal` โ†’ Configuration) + +| Name | Value | +| ---------------------------------- | ---------------------------------------------------- | +| `WEBSITE_RUN_FROM_PACKAGE` | `1` | +| `SCM_DO_BUILD_DURING_DEPLOYMENT` | `false` | +| `ENABLE_ORYX_BUILD` | `false` | +| Startup Command (General settings) | `node /home/site/wwwroot/github-portal/dist/bin/www` | + +Or via Azure CLI: + +```bash +az webapp config appsettings set --name nihgithubportal --resource-group \ + --settings WEBSITE_RUN_FROM_PACKAGE=1 SCM_DO_BUILD_DURING_DEPLOYMENT=false ENABLE_ORYX_BUILD=false +az webapp config set --name nihgithubportal --resource-group \ + --startup-file "node /home/site/wwwroot/github-portal/dist/bin/www" +``` + +#### Caveat โ€” read-only `wwwroot` + +With `WEBSITE_RUN_FROM_PACKAGE=1`, the app **cannot write to `/home/site/wwwroot`**. Anything writable must live under `/home/` (the persistent share, separate from `wwwroot`). Audit any code that writes to its own directory (logs, uploads, caches) before flipping the switch in production. + +See `AGENTS.md` for the debugging checklist if the production app crash-loops with this error after the stagingโ†’main merge. + +#### Also add the renamed Entra env vars to both App Services + +The upstream sync (commit `55c10cfe`) completely restructured `config/activeDirectory.json`, renaming all app registration env vars from `AAD_*` to `ENTRA_*`. Both App Services need these new names **alongside** the old ones (do not rename โ€” other config paths still reference `AAD_ISSUER`, `AAD_BLOCK_GUESTS`, etc.): + +| Add this new setting | Copy value from | +| ------------------------ | ------------------- | +| `ENTRA_ID_CLIENT_ID` | `AAD_CLIENT_ID` | +| `ENTRA_ID_CLIENT_SECRET` | `AAD_CLIENT_SECRET` | +| `ENTRA_ID_TENANT_ID` | `AAD_TENANT_ID` | + +Without these, the app throws `No Entra application configuration found` on startup. + +#### Additional required App Service settings (discovered during staging debug) + +The following settings are also required or the app crashes/misbehaves at runtime: + +| Setting | Value | Why | +| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | +| `AUTHENTICATION_SCHEME` | `entra-id` | Default `aad` throws on startup since upstream sync | +| `ApplicationInsightsAgent_EXTENSION_VERSION` | `disabled` | Codeless agent floods logs and slows cold starts | +| `FRONTEND_MODE` | `skip` | No `frontend/` directory in repo; default `serve` crashes during route setup | +| `REDIS_KEY` \_ | _(Azure Ca_he for Redis primary access key)_ | Without it, all Redis commands fail with `NOAUTH Authentication required` | +| `ENTRA_ID_AUTHENTICATION_TYPE` | `secret` | Default `managed-identity` silently skips passport strategy registration โ†’ "Unknown authentication strategy entra-id" | +| `ENTRA_ID_AUTHENTICATION_CLIENT_ID` | = `AAD_CLIENT_ID` | Used by passport strategy (separate from `ENTRA_ID_CLIENT_ID`) | +| `ENTRA_ID_AUTHENTICATION_CLIENT_SECRET` | = `AAD_CLIENT_SECRET` | | +| `ENTRA_ID_AUTHENTICATION_TENANT_ID` | = `AAD_TENANT_ID` | | +| `ENTRA_ID_REDIRECT_URL` | `https://dev.portal.github.nih.gov/auth/entra-id/callback` (staging) / `https://portal.github.nih.gov/auth/entra-id/callback` (prod) | Must also be registered as a redirect URI in Entra app registration | +| `ENTRA_ID_MULTI_TENANT` | `1` | Set on NIH App Service; enables multitenant MSAL authority so non-NIH Entra users (e.g. ARPA-H) can sign in | +| `ENTRA_ID_ALLOWED_TENANT_IDS` | `{NIH-tenant-id};{ARPA-H-tenant-id}` | Set on NIH App Service; NIH tenant ID = value of `ENTRA_ID_AUTHENTICATION_TENANT_ID`; semicolon-separated | + +See `AGENTS.md` for the full required-settings table and a known-errors quick-reference. + +--- + +### ARPA-H User Migration Procedure + +When a user migrates from an NIH identity (`user@nih.gov`) to an ARPA-H identity (`user@arpa-h.gov`), their `links` row must be updated manually in both databases (`nihdevgithubportal` and `nihgithubportal`). + +#### Step 1 โ€” Get the ARPA-H home-tenant OID + +```bash +az login --tenant +az ad user show --id user@arpa-h.gov --query id -o tsv +``` + +This must be the **ARPA-H home-tenant OID** โ€” not the NIH guest OID. The portal uses `oid` from the MSAL token (issued by the home tenant) as the corporate ID. + +#### Step 2 โ€” Update the links row + +```sql +UPDATE links +SET corporateid = '', + corporateusername = 'user@arpa-h.gov', + corporatemail = 'user@arpa-h.gov', + corporatename = 'Display Name (ARPA-H)' +WHERE thirdpartytype = 'github' + AND lower(thirdpartyusername) = ''; +``` + +Confirm `UPDATE 1` before proceeding. Run this on both the staging and production databases. + +#### Step 3 โ€” Verify the ARPA-H tenant is allowed + +Confirm the ARPA-H tenant ID is present in `ENTRA_ID_ALLOWED_TENANT_IDS` on both App Services (semicolon-separated). Without it, the sign-in is rejected before the link lookup runs. + +#### Step 4 โ€” Have the user sign in + +The user signs in with their ARPA-H identity. No further action is needed โ€” the 30-second Redis links cache expires quickly, and `AddLinkToRequest` queries Postgres directly by `corporateid`. + +#### Ongoing: display name staleness + +The `refreshUsernames` job keeps NIH users' `corporatename` in sync automatically by calling `graphProvider.getUserById(corporateId)`. For ARPA-H users, the NIH tenant's Graph client cannot resolve the ARPA-H OID, so the job silently skips them. If an ARPA-H user changes their display name (e.g. due to a title/org change within ARPA-H), it must be updated manually: + +```sql +UPDATE links +SET corporatename = 'New Display Name' +WHERE thirdpartytype = 'github' + AND lower(thirdpartyusername) = ''; +``` + +--- + +### 1. Add `helmet` middleware (CSP, X-Frame-Options, nosniff, Referrer-Policy) + +**Files:** `middleware/index.ts`, `package.json` + +The middleware stack currently only sets HSTS and disables `X-Powered-By`. No `Content-Security-Policy`, `X-Frame-Options`, `X-Content-Type-Options`, or `Referrer-Policy` headers are sent. These are the primary browser-side defenses against XSS and clickjacking. + +- [ ] `npm install helmet` +- [ ] Register `app.use(helmet({ ... }))` early in `middleware/index.ts`, before routing +- [ ] Define a CSP policy appropriate to the app's asset sources (GitHub, Azure CDN, etc.) โ€” start in report-only mode (`helmet.contentSecurityPolicy({ reportOnly: true })`) to avoid breaking changes, then harden + +--- + +### 2. Add `permissions:` blocks to all workflows + +**Files:** `.github/workflows/ci.yml`, `.github/workflows/codeql-analysis.yml`, and any workflow lacking an explicit `permissions:` declaration + +Without an explicit `permissions:` block, workflows inherit the repository default (often `write-all` for private repos). A compromised step could push code, publish packages, or modify secrets. + +- [ ] Add minimal-privilege `permissions:` at the top level of each workflow: + + ```yaml + permissions: + contents: read + ``` + +- [ ] For workflows that need additional access (e.g., CodeQL needs `security-events: write`), scope those grants per-job rather than globally + +--- + +## Medium Priority + +### 4. Set `sameSite` on the session cookie + +**File:** `middleware/session.ts` + +There is a 6-year-old `// TODO: 2020: consider SameSite` comment. The session cookie is currently created without an explicit `sameSite` attribute. Setting it explicitly documents intent and provides defense-in-depth against CSRF for the OAuth redirect flows. + +- [ ] Add `sameSite: 'lax'` to the `settings.cookie` object in `middleware/session.ts` +- [ ] Verify that `sameSite: 'lax'` is compatible with the Entra ID and GitHub OAuth callback flows (both use `GET` redirects, so `lax` should work) + +--- + +### 5. Add `bun audit` step to CI + +**File:** `.github/workflows/ci.yml` + +Dependabot PRs can take days; a failing audit step catches known vulnerabilities on every push independently of Dependabot. + +- [ ] Add to `ci.yml` after the install step: + + ```yaml + - name: Audit dependencies + run: bun audit --audit-level=high + ``` + +--- + +### 6. Add container image vulnerability scanning + +**Files:** `.github/workflows/ci.yml` or a new `security-scan.yml` + +The Docker build in CI creates an image but never scans it. Both the Azure Linux base layer (OS packages) and the npm layer can contain CVEs that only appear post-build. + +- [ ] Add a [Trivy](https://github.com/aquasecurity/trivy-action) step after `docker build`: + + ```yaml + - name: Scan container image + uses: aquasecurity/trivy-action@ + with: + image-ref: 'portal:latest' + format: 'table' + exit-code: '1' + severity: 'HIGH,CRITICAL' + ``` + +- [ ] Alternatively integrate [Grype](https://github.com/anchore/scan-action) for SBOM-aware scanning + +--- + +### 7. Add Dependabot coverage for `frontend/` + +**File:** `.github/dependabot.yml` + +Dependabot covers `/` and `/default-assets-package` for npm, but the `frontend/` directory has its own `package.json` (referenced in `Dockerfile` as `WORKDIR /build/frontend`) and is not covered. + +- [ ] Add a third npm entry to `dependabot.yml`: + + ```yaml + - package-ecosystem: npm + directory: /frontend + target-branch: staging + schedule: + interval: daily + open-pull-requests-limit: 10 + commit-message: + prefix: 'npm - frontend' + ``` + +--- + +### 8. Verify package integrity in CI (`bun audit`) + +**File:** `.github/workflows/ci.yml` + +Bun's lockfile uses SHA-512 integrity hashes for every package. Adding `bun audit` in CI catches advisories on every push independently of Dependabot. + +- [ ] Add to `ci.yml` after install: + + ```yaml + - name: Verify package integrity + run: bun audit + ``` + +--- + +## Lower Priority + +### 9. Migrate `staging_create_acr_image.yml` off static registry credentials + +**File:** `.github/workflows/staging_create_acr_image.yml` + +The staging image push workflow uses `secrets.DEV_REGISTRY_USER` and `secrets.DEV_REGISTRY_PASS` (long-lived static credentials), while `container.yml` correctly uses OIDC (`azure/login` with `client-id`/`tenant-id`/`subscription-id`). Static credentials are a higher-value target and cannot be automatically rotated. + +- [ ] Configure a workload identity federated credential for the staging environment in Azure +- [ ] Replace the Docker login step with `azure/login@v2` using OIDC, then `az acr login` +- [ ] Remove `DEV_REGISTRY_USER` and `DEV_REGISTRY_PASS` secrets once migrated + +--- + +### 10. Audit and contain unescaped Pug template expressions + +**Files:** `views/error.pug`, `views/contributions/index.pug` + +`views/error.pug` uses `!= detailed` (unescaped HTML), which is intentional per an inline comment โ€” but it creates a footgun if any future code path sets `err.detailed` from external (GitHub API, user) data. The `!=` in `views/contributions/index.pug` is for trusted Octicon SVG strings. + +- [ ] Audit all `!=` / `!{` occurrences in `views/` and document in a comment next to each why raw HTML is safe at that point +- [ ] Where possible, replace with escaped `=` expressions and pass pre-built HTML through a controlled helper rather than open-ended error properties + +--- + +### 11. Escaping database name in `scripts/postgres/setup.ts` + +**File:** `scripts/postgres/setup.ts` + +Line 34 interpolates `${db}` directly into a `CREATE DATABASE` query string without using `pg-escape`, while line 43 correctly uses `escape(...)` for user creation. Both should use parameterized or escaped values. + +- [ ] Replace `\`create database ${db}\``with`escape('create database %I', db)`using the already-imported`pg-escape` package + +--- + +### 12. Evaluate private npm registry proxy (Azure Artifacts / Artifactory) + +Routing all npm installs through an internal registry mirror that scans packages before they are available to developers and CI provides a chokepoint for supply chain attacks independent of public registry health. + +- [ ] Evaluate Azure Artifacts Upstream Sources or GitHub Packages as a proxy +- [ ] If adopted, restrict `.npmrc` in the Dockerfile and devcontainer to the internal registry and remove direct registry access + +--- + +### 13. Evaluate Socket.dev or Snyk for proactive dependency analysis + +Dependabot and `npm audit` are reactive (known CVEs). [Socket.dev](https://socket.dev) and Snyk both analyze package behavior (network access, filesystem access, install scripts, typosquatting) before a CVE is published. + +- [ ] Install the Socket GitHub App on the repository +- [ ] Configure it to block PRs that introduce packages with flagged behaviors + +--- + +## Already in Place (No Action Required) + +- `bun install --frozen-lockfile --ignore-scripts` in `Dockerfile` and all CI workflows โ€” prevents malicious install scripts and ensures reproducible installs +- `bun.lock` with SHA-512 integrity hashes for all packages (replaces `package-lock.json`) โ€” deterministic installs +- All GitHub Actions SHA-pinned to exact commit hashes across all 10 workflow files +- `app.disable('x-powered-by')` in `middleware/index.ts` +- HSTS with preload and `includeSubDomains` via `middleware/hsts.ts` +- `eslint-plugin-security` integrated in `eslint.config.mjs` +- OIDC-based Azure auth in `container.yml` (no static Azure credentials) +- Dependabot covering npm (`/`, `/default-assets-package`), GitHub Actions, and Docker +- CodeQL scanning on push and weekly (`codeql-analysis.yml`) +- API token validation via Entra in `middleware/api/authentication/` +- Session production guards (rejects `memory`/`file` providers in production) +- Rate limiting on all API routes (GHAS alerts resolved May 2026) +- Redis v5 auth handled correctly via `createClient({ password })` (fixed May 2026) From 384a0fee301c4e813b472fafb3410d65e8e9d7d8 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Sun, 7 Jun 2026 02:39:09 +0000 Subject: [PATCH 200/209] ci: delete unused container.yml workflow Was generating Problems tab noise; all its steps were commented out or guarded to microsoft/opensource-management-portal only. Replaced by staging_create_acr_image.yml and main_create_acr_image.yml. --- .github/workflows/container.yml | 126 -------------------------------- 1 file changed, 126 deletions(-) delete mode 100644 .github/workflows/container.yml diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml deleted file mode 100644 index c1dd30444..000000000 --- a/.github/workflows/container.yml +++ /dev/null @@ -1,126 +0,0 @@ -name: Unused Docker Image - Build - -on: - push: - branches: [main] - -permissions: - id-token: write - contents: read - -jobs: - lint-and-test: - name: "Lint 'n test ๐Ÿงบ" - runs-on: ubuntu-latest - steps: - - name: Checkout ๐Ÿ›’ - uses: actions/checkout@v4 - - - name: Packages ๐Ÿ“ฆ - run: | - npm ci - - - name: Lint ๐Ÿ‘” - run: | - npm run lint - - - name: Test ๐Ÿƒโ€โ™‚๏ธ - run: | - npm run test - # npm run-script build - # npm run-script test:ci - - build: - name: 'Container delivery ๐Ÿš›' - runs-on: ubuntu-latest - environment: - name: development - steps: - - uses: actions/checkout@v4 - #- uses: docker/build-push-action@v3 - - - name: Azure OpenID Connect โœจ - if: github.repository == 'microsoft/opensource-management-portal' # official repo only - uses: azure/login@v1 - with: - client-id: ${{ secrets.CLIENT_ID }} - tenant-id: ${{ secrets.TENANT_ID }} - subscription-id: ${{ secrets.SUBSCRIPTION_ID }} - - - name: Connect to Azure Container Registry ๐Ÿ”– - if: github.repository == 'microsoft/opensource-management-portal' # official repo only - run: | - az acr login -n opensource - - - name: Stamp build information ๐Ÿ’Œ - run: | - sed -i "s/__Build_BuildNumber__/${{ github.run_number }}/" package.json - sed -i "s/__Build_SourceVersion__/${{ github.sha }}/" package.json - echo package.json-stamped version: - cat package.json - - - name: Use opensource deployment values ๐Ÿ“‘ - if: github.repository == 'microsoft/opensource-management-portal' # official repo only - run: | - node .ossdev/build/packageBurn.js - node .ossdev/build/dockerfileForEnvironment.js - - - name: Container build โ›ด๏ธ - run: | - docker build \ - -t ${{ github.event.repository.name }}:${{ github.run_number }} \ - -t opensource.azurecr.io/${{ github.event.repository.name }}:${{ github.run_number }} \ - -t opensource.azurecr.io/${{ github.event.repository.name }}:latest \ - . - - - name: Push to ACR ๐Ÿ“Œ - if: github.repository == 'microsoft/opensource-management-portal' # official repo only - run: | - docker image push opensource.azurecr.io/${{ github.event.repository.name }}:${{ github.run_number }} - docker image push opensource.azurecr.io/${{ github.event.repository.name }}:latest - - development-stage: - name: Stage to development ๐Ÿ—๏ธ - if: github.repository == 'microsoft/opensource-management-portal' # official repo only - runs-on: ubuntu-latest - needs: [build, lint-and-test] - environment: - name: development - url: https://portal-staging.ospo.dev - steps: - - name: Azure OpenID Connect โœจ - uses: azure/login@v1 - with: - client-id: ${{ secrets.CLIENT_ID }} - tenant-id: ${{ secrets.TENANT_ID }} - subscription-id: ${{ secrets.SUBSCRIPTION_ID }} - - name: Prepare staging slots ๐ŸŽฐ - run: | - az webapp config container set \ - --docker-custom-image-name opensource.azurecr.io/${{ github.event.repository.name }}:${{ github.run_number }} \ - --docker-registry-server-url https://opensource.azurecr.io \ - --name portalwestus3 \ - --resource-group portal \ - --slot staging - - development: - name: Swap to live ๐Ÿ—๏ธ - if: github.repository == 'microsoft/opensource-management-portal' # official repo only - runs-on: ubuntu-latest - needs: [development-stage] - environment: - name: development - url: https://portal.ospo.dev - steps: - - name: Azure OpenID Connect โœจ - uses: azure/login@v1 - with: - client-id: ${{ secrets.CLIENT_ID }} - tenant-id: ${{ secrets.TENANT_ID }} - subscription-id: ${{ secrets.SUBSCRIPTION_ID }} - - name: Swap staging to live ๐Ÿ’ƒ - run: | - az webapp deployment slot swap \ - --name portalwestus3 \ - --resource-group portal \ - --slot staging From 88d22e05ec44b5d3fd71d576c4acfa91fc8f03f0 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:39:28 +0000 Subject: [PATCH 201/209] ci: replace GH_SECRETS_PAT with az monitor lookup for Log Analytics creds ACI deploy workflows now query Log Analytics workspace ID and key directly from Azure at deploy time via the existing OIDC session. No PAT required. --- .github/workflows/staging_nihdevgithubportalcb.yml | 9 +++++++++ .github/workflows/staging_nihdevgithubportalfh.yml | 9 +++++++++ .github/workflows/staging_terraform_dev.yml | 14 ++------------ PLAN.md | 9 +++------ infra/terraform/dev/outputs.tf | 4 ++-- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index 47523097b..85f413835 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -48,6 +48,14 @@ jobs: ACR_NAME="${REGISTRY_SERVER%%.*}" REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) + LA_WORKSPACE_ID=$(az monitor log-analytics workspace show \ + --resource-group "$RG" \ + --workspace-name nihdevgithubportal-logs \ + --query customerId --output tsv 2>/dev/null || echo "") + LA_WORKSPACE_KEY=$(az monitor log-analytics workspace get-shared-keys \ + --resource-group "$RG" \ + --workspace-name nihdevgithubportal-logs \ + --query primarySharedKey --output tsv 2>/dev/null || echo "") az container create \ --resource-group "$RG" \ --name nihdevgithubportalcb \ @@ -77,4 +85,5 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_APP_OPERATIONS_KEY="$APP_KEY" \ + $( [ -n "$LA_WORKSPACE_ID" ] && echo "--log-analytics-workspace \"$LA_WORKSPACE_ID\" --log-analytics-workspace-key \"$LA_WORKSPACE_KEY\"" ) \ --no-wait diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index e79280606..44fad0218 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -46,6 +46,14 @@ jobs: ACR_NAME="${REGISTRY_SERVER%%.*}" REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) + LA_WORKSPACE_ID=$(az monitor log-analytics workspace show \ + --resource-group "$RG" \ + --workspace-name nihdevgithubportal-logs \ + --query customerId --output tsv 2>/dev/null || echo "") + LA_WORKSPACE_KEY=$(az monitor log-analytics workspace get-shared-keys \ + --resource-group "$RG" \ + --workspace-name nihdevgithubportal-logs \ + --query primarySharedKey --output tsv 2>/dev/null || echo "") az container create \ --resource-group "$RG" \ --name nihdevgithubportalfh \ @@ -76,4 +84,5 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ + $( [ -n "$LA_WORKSPACE_ID" ] && echo "--log-analytics-workspace \"$LA_WORKSPACE_ID\" --log-analytics-workspace-key \"$LA_WORKSPACE_KEY\"" ) \ --no-wait diff --git a/.github/workflows/staging_terraform_dev.yml b/.github/workflows/staging_terraform_dev.yml index 8067d61e0..1a911ba91 100644 --- a/.github/workflows/staging_terraform_dev.yml +++ b/.github/workflows/staging_terraform_dev.yml @@ -67,15 +67,5 @@ jobs: terraform apply -auto-approve \ -var="resource_group_name=${{ secrets.DEV_RG }}" - - name: Export outputs to GitHub Secrets - if: ${{ github.event_name == 'push' || github.event.inputs.action == 'apply' }} - working-directory: infra/terraform/dev - env: - # Fine-grained PAT with: Contents=read, Secrets=read/write, scoped to this repo. - # Store as GitHub Secret: GH_SECRETS_PAT - GH_TOKEN: ${{ secrets.GH_SECRETS_PAT }} - run: | - WORKSPACE_ID=$(terraform output -raw workspace_id) - PRIMARY_KEY=$(terraform output -raw primary_shared_key) - gh secret set DEV_LOG_ANALYTICS_WORKSPACE_ID --body "$WORKSPACE_ID" - gh secret set DEV_LOG_ANALYTICS_WORKSPACE_KEY --body "$PRIMARY_KEY" + # Log Analytics workspace ID and key are NOT stored as secrets. + # ACI deploy workflows look them up at deploy time via az monitor. diff --git a/PLAN.md b/PLAN.md index 355499303..d2e8449d1 100644 --- a/PLAN.md +++ b/PLAN.md @@ -52,19 +52,16 @@ Before the workflow can run, a storage account for Terraform state must exist: 1. ~~Create a storage account in `GitHub_OpenSource_Portal_Dev` (e.g. `nihdevgithubportaltf`)~~ โœ… Done 2. Create a blob container in it (e.g. `tfstate`) โ€” or confirm it exists -3. Grant service principal **Storage Blob Data Contributor** on `nihdevgithubportaltf` +3. ~~Grant service principal **Storage Blob Data Contributor** on `nihdevgithubportaltf`~~ โœ… Done 4. Add GitHub Secrets: - `DEV_TF_STORAGE_ACCOUNT` โ†’ `nihdevgithubportaltf` - `DEV_TF_STORAGE_CONTAINER` โ†’ container name (e.g. `tfstate`) - - `GH_SECRETS_PAT` โ†’ fine-grained PAT with **Secrets: read/write** and **Contents: read** on this repo (used to auto-export Terraform outputs back as GitHub Secrets) + - ~~`GH_SECRETS_PAT`~~ โ€” not needed; ACI workflows look up Log Analytics from Azure at deploy time via `az monitor` ### Resources managed - [ ] `azurerm_log_analytics_workspace` โ€” `nihdevgithubportal-logs` -- [ ] After first apply: workflow automatically sets these GitHub Secrets: - - `DEV_LOG_ANALYTICS_WORKSPACE_ID` - - `DEV_LOG_ANALYTICS_WORKSPACE_KEY` - - Then wire into ACI workflows: add `--log-analytics-workspace` + `--log-analytics-workspace-key` to `az container create` +- [x] Log Analytics ID/key wired into ACI deploys: looked up at runtime via `az monitor log-analytics workspace show/get-shared-keys` โ€” no secrets required ### Future: full resource group coverage (tracked in GitHub Issues) diff --git a/infra/terraform/dev/outputs.tf b/infra/terraform/dev/outputs.tf index 473ccf270..bfa5ea352 100644 --- a/infra/terraform/dev/outputs.tf +++ b/infra/terraform/dev/outputs.tf @@ -1,10 +1,10 @@ output "workspace_id" { - description = "Workspace ID โ€” store as GitHub Secret DEV_LOG_ANALYTICS_WORKSPACE_ID" + description = "Log Analytics workspace ID (customer ID). Looked up at deploy time via az monitor โ€” not stored as a secret." value = azurerm_log_analytics_workspace.main.workspace_id } output "primary_shared_key" { - description = "Primary key โ€” store as GitHub Secret DEV_LOG_ANALYTICS_WORKSPACE_KEY" + description = "Log Analytics primary shared key. Looked up at deploy time via az monitor โ€” not stored as a secret." value = azurerm_log_analytics_workspace.main.primary_shared_key sensitive = true } From 818cc39bbf126f73636ffb0f91df52ca3f30fef2 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:43:01 +0000 Subject: [PATCH 202/209] ci: auto-bootstrap Terraform backend storage on first run --- .github/workflows/staging_terraform_dev.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/staging_terraform_dev.yml b/.github/workflows/staging_terraform_dev.yml index 1a911ba91..fdd916caf 100644 --- a/.github/workflows/staging_terraform_dev.yml +++ b/.github/workflows/staging_terraform_dev.yml @@ -42,6 +42,25 @@ jobs: tenant-id: ${{ secrets.AAD_TENANT_ID }} subscription-id: ${{ secrets.AAD_SUBSCRIPTION_ID }} + - name: Bootstrap Terraform backend storage + env: + TF_SA: ${{ secrets.DEV_TF_STORAGE_ACCOUNT }} + TF_CONTAINER: ${{ secrets.DEV_TF_STORAGE_CONTAINER }} + RG: ${{ secrets.DEV_RG }} + run: | + az storage account create \ + --name "$TF_SA" \ + --resource-group "$RG" \ + --sku Standard_LRS \ + --allow-blob-public-access false \ + --min-tls-version TLS1_2 \ + 2>/dev/null || echo "Storage account already exists" + az storage container create \ + --name "$TF_CONTAINER" \ + --account-name "$TF_SA" \ + --auth-mode login \ + 2>/dev/null || echo "Container already exists" + - name: Setup Terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3 From e758c7bd8ed63ba635a165c41ed7c57fc69564db Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:51:25 +0000 Subject: [PATCH 203/209] ci: use Entra ID auth for Terraform azurerm backend --- .github/workflows/staging_terraform_dev.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/staging_terraform_dev.yml b/.github/workflows/staging_terraform_dev.yml index fdd916caf..255f68fc6 100644 --- a/.github/workflows/staging_terraform_dev.yml +++ b/.github/workflows/staging_terraform_dev.yml @@ -71,7 +71,8 @@ jobs: -backend-config="resource_group_name=${{ secrets.DEV_RG }}" \ -backend-config="storage_account_name=${{ secrets.DEV_TF_STORAGE_ACCOUNT }}" \ -backend-config="container_name=${{ secrets.DEV_TF_STORAGE_CONTAINER }}" \ - -backend-config="key=dev/terraform.tfstate" + -backend-config="key=dev/terraform.tfstate" \ + -backend-config="use_azuread_auth=true" - name: Terraform Plan working-directory: infra/terraform/dev From 5d84aea8bda7c1e0bc1b069eee03396cf0bdbfd1 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:00:07 +0000 Subject: [PATCH 204/209] ci: pass OIDC token endpoint vars to Terraform azurerm backend --- .github/workflows/staging_terraform_dev.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/staging_terraform_dev.yml b/.github/workflows/staging_terraform_dev.yml index 255f68fc6..b717f299b 100644 --- a/.github/workflows/staging_terraform_dev.yml +++ b/.github/workflows/staging_terraform_dev.yml @@ -30,6 +30,8 @@ jobs: ARM_TENANT_ID: ${{ secrets.AAD_TENANT_ID }} ARM_SUBSCRIPTION_ID: ${{ secrets.AAD_SUBSCRIPTION_ID }} ARM_USE_OIDC: 'true' + ARM_OIDC_REQUEST_URL: ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL }} + ARM_OIDC_REQUEST_TOKEN: ${{ env.ACTIONS_ID_TOKEN_REQUEST_TOKEN }} steps: - name: Checkout From 66e61c96cf76b7e6f2690c0389b1bb7c62769688 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:06:06 +0000 Subject: [PATCH 205/209] ci: fix workflow parse error from invalid env context reference --- .github/workflows/staging_terraform_dev.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/staging_terraform_dev.yml b/.github/workflows/staging_terraform_dev.yml index b717f299b..6c111493c 100644 --- a/.github/workflows/staging_terraform_dev.yml +++ b/.github/workflows/staging_terraform_dev.yml @@ -30,8 +30,9 @@ jobs: ARM_TENANT_ID: ${{ secrets.AAD_TENANT_ID }} ARM_SUBSCRIPTION_ID: ${{ secrets.AAD_SUBSCRIPTION_ID }} ARM_USE_OIDC: 'true' - ARM_OIDC_REQUEST_URL: ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL }} - ARM_OIDC_REQUEST_TOKEN: ${{ env.ACTIONS_ID_TOKEN_REQUEST_TOKEN }} + # ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN are + # injected automatically by the runner when id-token: write is set. + # Terraform's azurerm provider reads them directly โ€” no mapping needed. steps: - name: Checkout From 206a8a074f7cefd39b391ffac0ae3ba5a186ae57 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:20:15 +0000 Subject: [PATCH 206/209] ci: fix Log Analytics arg injection in ACI deploy workflows --- .github/workflows/staging_nihdevgithubportalcb.yml | 12 ++++++++---- .github/workflows/staging_nihdevgithubportalfh.yml | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/staging_nihdevgithubportalcb.yml b/.github/workflows/staging_nihdevgithubportalcb.yml index 85f413835..ae75ab4df 100644 --- a/.github/workflows/staging_nihdevgithubportalcb.yml +++ b/.github/workflows/staging_nihdevgithubportalcb.yml @@ -45,9 +45,6 @@ jobs: APP_SLUG: ${{ secrets.DEV_GITHUB_APP_OPERATIONS_SLUG }} RG: ${{ secrets.DEV_RG }} run: | - ACR_NAME="${REGISTRY_SERVER%%.*}" - REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) - REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) LA_WORKSPACE_ID=$(az monitor log-analytics workspace show \ --resource-group "$RG" \ --workspace-name nihdevgithubportal-logs \ @@ -56,6 +53,13 @@ jobs: --resource-group "$RG" \ --workspace-name nihdevgithubportal-logs \ --query primarySharedKey --output tsv 2>/dev/null || echo "") + LA_ARGS=() + if [ -n "$LA_WORKSPACE_ID" ]; then + LA_ARGS=(--log-analytics-workspace "$LA_WORKSPACE_ID" --log-analytics-workspace-key "$LA_WORKSPACE_KEY") + fi + ACR_NAME="${REGISTRY_SERVER%%.*}" + REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) + REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) az container create \ --resource-group "$RG" \ --name nihdevgithubportalcb \ @@ -85,5 +89,5 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_APP_OPERATIONS_KEY="$APP_KEY" \ - $( [ -n "$LA_WORKSPACE_ID" ] && echo "--log-analytics-workspace \"$LA_WORKSPACE_ID\" --log-analytics-workspace-key \"$LA_WORKSPACE_KEY\"" ) \ + "${LA_ARGS[@]}" \ --no-wait diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index 44fad0218..752934bdf 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -43,9 +43,6 @@ jobs: SERVICEBUS_CONN: ${{ secrets.DEV_SERVICEBUS_CONNECTIONSTRING }} RG: ${{ secrets.DEV_RG }} run: | - ACR_NAME="${REGISTRY_SERVER%%.*}" - REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) - REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) LA_WORKSPACE_ID=$(az monitor log-analytics workspace show \ --resource-group "$RG" \ --workspace-name nihdevgithubportal-logs \ @@ -54,6 +51,13 @@ jobs: --resource-group "$RG" \ --workspace-name nihdevgithubportal-logs \ --query primarySharedKey --output tsv 2>/dev/null || echo "") + LA_ARGS=() + if [ -n "$LA_WORKSPACE_ID" ]; then + LA_ARGS=(--log-analytics-workspace "$LA_WORKSPACE_ID" --log-analytics-workspace-key "$LA_WORKSPACE_KEY") + fi + ACR_NAME="${REGISTRY_SERVER%%.*}" + REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) + REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) az container create \ --resource-group "$RG" \ --name nihdevgithubportalfh \ @@ -84,5 +88,5 @@ jobs: REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ - $( [ -n "$LA_WORKSPACE_ID" ] && echo "--log-analytics-workspace \"$LA_WORKSPACE_ID\" --log-analytics-workspace-key \"$LA_WORKSPACE_KEY\"" ) \ + "${LA_ARGS[@]}" \ --no-wait From edba54dd9659e756ba89b639bf899c6acd4298f7 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 10 Jun 2026 02:19:37 +0000 Subject: [PATCH 207/209] feat: managed identity for Service Bus; prod Terraform; eliminate SERVICEBUS_CONNECTIONSTRING - servicebus.ts: accept fullyQualifiedNamespace (managed identity) or connectionString - config/github.webhooks.json: map GITHUB_WEBHOOKS_SERVICEBUS_ENDPOINT to fullyQualifiedNamespace - config/github.webhooks.types.ts: make connectionString optional, add fullyQualifiedNamespace - firehose workflows: assign managed identity to ACI, use GITHUB_WEBHOOKS_SERVICEBUS_ENDPOINT instead of GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING; lookup identity at deploy time - staging_terraform_dev.yml: pass DEV_SERVICEBUS_NAMESPACE var - infra/terraform/dev: add user-assigned identity + Service Bus Data Receiver role assignment - infra/terraform/prod/: new prod Terraform (mirrors dev) - .github/workflows/main_terraform_prod.yml: new prod Terraform workflow --- .eslintrc.js | 50 -------- .github/workflows/main_nihgithubportalfh.yml | 22 +++- .github/workflows/main_terraform_prod.yml | 93 +++++++++++++++ .../staging_nihdevgithubportalfh.yml | 9 +- .github/workflows/staging_terraform_dev.yml | 6 +- config/github.webhooks.json | 1 + config/github.webhooks.types.ts | 3 +- eslint.config.mjs | 109 ++++++++++++++++++ infra/terraform/dev/main.tf | 17 +++ infra/terraform/dev/outputs.tf | 15 +++ infra/terraform/dev/variables.tf | 5 + infra/terraform/prod/main.tf | 24 ++++ infra/terraform/prod/outputs.tf | 25 ++++ infra/terraform/prod/providers.tf | 22 ++++ infra/terraform/prod/variables.tf | 27 +++++ lib/queues/servicebus.ts | 14 ++- 16 files changed, 379 insertions(+), 63 deletions(-) delete mode 100644 .eslintrc.js create mode 100644 .github/workflows/main_terraform_prod.yml create mode 100644 eslint.config.mjs create mode 100644 infra/terraform/prod/main.tf create mode 100644 infra/terraform/prod/outputs.tf create mode 100644 infra/terraform/prod/providers.tf create mode 100644 infra/terraform/prod/variables.tf diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 3c5d9899b..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = { - root: true, - extends: ['eslint:recommended', 'plugin:prettier/recommended'], - overrides: [ - { - files: ['**/*.js'], - env: { - es6: true, - node: true, - }, - }, - { - files: ['**/*.ts'], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - extends: ['plugin:@typescript-eslint/recommended', 'plugin:n/recommended'], - rules: { - '@typescript-eslint/ban-ts-comment': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-empty-interface': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-this-alias': 'off', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/no-var-requires': 'off', - 'n/no-missing-import': 'off', - 'n/no-process-exit': 'off', - 'n/shebang': 'off', - 'no-case-declarations': 'off', - 'no-empty': 'off', - 'no-ex-assign': 'off', - 'no-inner-declarations': 'off', - 'no-useless-catch': 'off', - 'prefer-const': [ - 'error', - { - destructuring: 'all', - }, - ], - 'prefer-rest-params': 'off', - 'prefer-spread': 'off', - }, - }, - ], - ignorePatterns: [ - 'default-assets-package/thirdparty/**/*.js', - 'dist/**/*.js', - 'dist/**/*.d.ts', - '**/vendor/**', - ], -}; diff --git a/.github/workflows/main_nihgithubportalfh.yml b/.github/workflows/main_nihgithubportalfh.yml index c237b5643..50649da14 100644 --- a/.github/workflows/main_nihgithubportalfh.yml +++ b/.github/workflows/main_nihgithubportalfh.yml @@ -40,12 +40,27 @@ jobs: POSTGRES_DB: ${{ secrets.PROD_POSTGRES_DB }} POSTGRES_USER: ${{ secrets.PROD_POSTGRES_USER }} POSTGRES_PASSWORD: ${{ secrets.PROD_POSTGRES_PASSWORD }} - SERVICEBUS_CONN: ${{ secrets.PROD_SERVICEBUS_CONNECTIONSTRING }} + SB_NAMESPACE: ${{ secrets.PROD_SERVICEBUS_NAMESPACE }} RG: ${{ secrets.PROD_RG }} run: | + LA_WORKSPACE_ID=$(az monitor log-analytics workspace show \ + --resource-group "$RG" \ + --workspace-name nihgithubportal-logs \ + --query customerId --output tsv 2>/dev/null || echo "") + LA_WORKSPACE_KEY=$(az monitor log-analytics workspace get-shared-keys \ + --resource-group "$RG" \ + --workspace-name nihgithubportal-logs \ + --query primarySharedKey --output tsv 2>/dev/null || echo "") + LA_ARGS=() + if [ -n "$LA_WORKSPACE_ID" ]; then + LA_ARGS=(--log-analytics-workspace "$LA_WORKSPACE_ID" --log-analytics-workspace-key "$LA_WORKSPACE_KEY") + fi ACR_NAME="${REGISTRY_SERVER%%.*}" REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) + IDENTITY_ID=$(az identity show --resource-group "$RG" --name nihgithubportal-firehose --query id --output tsv) + IDENTITY_CLIENT_ID=$(az identity show --resource-group "$RG" --name nihgithubportal-firehose --query clientId --output tsv) + SB_ENDPOINT="${SB_NAMESPACE}.servicebus.windows.net" az container create \ --resource-group "$RG" \ --name nihgithubportalfh \ @@ -54,6 +69,7 @@ jobs: --registry-login-server "$REGISTRY_SERVER" \ --registry-username "$REGISTRY_USER" \ --registry-password "$REGISTRY_PASS" \ + --assign-identity "$IDENTITY_ID" \ --command-line "node /usr/src/repos/jobs/firehose.js" \ --restart-policy OnFailure \ --os-type Linux \ @@ -72,8 +88,10 @@ jobs: GITHUB_ORGANIZATIONS_SOURCE=postgres \ GITHUB_WEBHOOKS_PROVIDER=servicebus \ GITHUB_WEBHOOKS_SERVICEBUS_QUEUE=events \ + GITHUB_WEBHOOKS_SERVICEBUS_ENDPOINT="$SB_ENDPOINT" \ + AZURE_CLIENT_ID="$IDENTITY_CLIENT_ID" \ --secure-environment-variables \ REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ - GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ + "${LA_ARGS[@]}" \ --no-wait diff --git a/.github/workflows/main_terraform_prod.yml b/.github/workflows/main_terraform_prod.yml new file mode 100644 index 000000000..a7de0112f --- /dev/null +++ b/.github/workflows/main_terraform_prod.yml @@ -0,0 +1,93 @@ +name: NIH GHMP (Prod) - Terraform + +on: + push: + branches: + - main + paths: + - 'infra/terraform/prod/**' + workflow_dispatch: + inputs: + action: + description: 'Terraform action to run' + required: true + default: 'plan' + type: choice + options: + - plan + - apply + +permissions: + id-token: write + contents: read + +jobs: + terraform: + runs-on: ubuntu-latest + + env: + ARM_CLIENT_ID: ${{ secrets.PROD_AAD_CLIENT_ID }} + ARM_TENANT_ID: ${{ secrets.PROD_AAD_TENANT_ID }} + ARM_SUBSCRIPTION_ID: ${{ secrets.PROD_AAD_SUBSCRIPTION_ID }} + ARM_USE_OIDC: 'true' + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Azure Login + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + client-id: ${{ secrets.PROD_AAD_CLIENT_ID }} + tenant-id: ${{ secrets.PROD_AAD_TENANT_ID }} + subscription-id: ${{ secrets.PROD_AAD_SUBSCRIPTION_ID }} + + - name: Bootstrap Terraform backend storage + env: + TF_SA: ${{ secrets.PROD_TF_STORAGE_ACCOUNT }} + TF_CONTAINER: ${{ secrets.PROD_TF_STORAGE_CONTAINER }} + RG: ${{ secrets.PROD_RG }} + run: | + az storage account create \ + --name "$TF_SA" \ + --resource-group "$RG" \ + --sku Standard_LRS \ + --allow-blob-public-access false \ + --min-tls-version TLS1_2 \ + 2>/dev/null || echo "Storage account already exists" + az storage container create \ + --name "$TF_CONTAINER" \ + --account-name "$TF_SA" \ + --auth-mode login \ + 2>/dev/null || echo "Container already exists" + + - name: Setup Terraform + uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3 + + - name: Terraform Init + working-directory: infra/terraform/prod + run: | + terraform init \ + -backend-config="resource_group_name=${{ secrets.PROD_RG }}" \ + -backend-config="storage_account_name=${{ secrets.PROD_TF_STORAGE_ACCOUNT }}" \ + -backend-config="container_name=${{ secrets.PROD_TF_STORAGE_CONTAINER }}" \ + -backend-config="key=prod/terraform.tfstate" \ + -backend-config="use_azuread_auth=true" + + - name: Terraform Plan + working-directory: infra/terraform/prod + run: | + terraform plan \ + -var="resource_group_name=${{ secrets.PROD_RG }}" \ + -var="servicebus_namespace_name=${{ secrets.PROD_SERVICEBUS_NAMESPACE }}" + + - name: Terraform Apply + if: ${{ github.event_name == 'push' || github.event.inputs.action == 'apply' }} + working-directory: infra/terraform/prod + run: | + terraform apply -auto-approve \ + -var="resource_group_name=${{ secrets.PROD_RG }}" \ + -var="servicebus_namespace_name=${{ secrets.PROD_SERVICEBUS_NAMESPACE }}" + + # Log Analytics workspace ID and key are NOT stored as secrets. + # ACI deploy workflows look them up at deploy time via az monitor. diff --git a/.github/workflows/staging_nihdevgithubportalfh.yml b/.github/workflows/staging_nihdevgithubportalfh.yml index 752934bdf..a956c9ed1 100644 --- a/.github/workflows/staging_nihdevgithubportalfh.yml +++ b/.github/workflows/staging_nihdevgithubportalfh.yml @@ -40,7 +40,7 @@ jobs: POSTGRES_DB: ${{ secrets.DEV_POSTGRES_DB }} POSTGRES_USER: ${{ secrets.DEV_POSTGRES_USER }} POSTGRES_PASSWORD: ${{ secrets.DEV_POSTGRES_PASSWORD }} - SERVICEBUS_CONN: ${{ secrets.DEV_SERVICEBUS_CONNECTIONSTRING }} + SB_NAMESPACE: ${{ secrets.DEV_SERVICEBUS_NAMESPACE }} RG: ${{ secrets.DEV_RG }} run: | LA_WORKSPACE_ID=$(az monitor log-analytics workspace show \ @@ -58,6 +58,9 @@ jobs: ACR_NAME="${REGISTRY_SERVER%%.*}" REGISTRY_USER=$(az acr credential show --name "$ACR_NAME" --query username --output tsv) REGISTRY_PASS=$(az acr credential show --name "$ACR_NAME" --query "passwords[0].value" --output tsv) + IDENTITY_ID=$(az identity show --resource-group "$RG" --name nihdevgithubportal-firehose --query id --output tsv) + IDENTITY_CLIENT_ID=$(az identity show --resource-group "$RG" --name nihdevgithubportal-firehose --query clientId --output tsv) + SB_ENDPOINT="${SB_NAMESPACE}.servicebus.windows.net" az container create \ --resource-group "$RG" \ --name nihdevgithubportalfh \ @@ -66,6 +69,7 @@ jobs: --registry-login-server "$REGISTRY_SERVER" \ --registry-username "$REGISTRY_USER" \ --registry-password "$REGISTRY_PASS" \ + --assign-identity "$IDENTITY_ID" \ --command-line "node /usr/src/repos/jobs/firehose.js" \ --restart-policy OnFailure \ --os-type Linux \ @@ -84,9 +88,10 @@ jobs: GITHUB_ORGANIZATIONS_SOURCE=postgres \ GITHUB_WEBHOOKS_PROVIDER=servicebus \ GITHUB_WEBHOOKS_SERVICEBUS_QUEUE=events \ + GITHUB_WEBHOOKS_SERVICEBUS_ENDPOINT="$SB_ENDPOINT" \ + AZURE_CLIENT_ID="$IDENTITY_CLIENT_ID" \ --secure-environment-variables \ REDIS_KEY="$REDIS_KEY" \ REPOS_POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ - GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING="$SERVICEBUS_CONN" \ "${LA_ARGS[@]}" \ --no-wait diff --git a/.github/workflows/staging_terraform_dev.yml b/.github/workflows/staging_terraform_dev.yml index 6c111493c..8b9105a44 100644 --- a/.github/workflows/staging_terraform_dev.yml +++ b/.github/workflows/staging_terraform_dev.yml @@ -81,14 +81,16 @@ jobs: working-directory: infra/terraform/dev run: | terraform plan \ - -var="resource_group_name=${{ secrets.DEV_RG }}" + -var="resource_group_name=${{ secrets.DEV_RG }}" \ + -var="servicebus_namespace_name=${{ secrets.DEV_SERVICEBUS_NAMESPACE }}" - name: Terraform Apply if: ${{ github.event_name == 'push' || github.event.inputs.action == 'apply' }} working-directory: infra/terraform/dev run: | terraform apply -auto-approve \ - -var="resource_group_name=${{ secrets.DEV_RG }}" + -var="resource_group_name=${{ secrets.DEV_RG }}" \ + -var="servicebus_namespace_name=${{ secrets.DEV_SERVICEBUS_NAMESPACE }}" # Log Analytics workspace ID and key are NOT stored as secrets. # ACI deploy workflows look them up at deploy time via az monitor. diff --git a/config/github.webhooks.json b/config/github.webhooks.json index 847d9691a..daec8f8df 100644 --- a/config/github.webhooks.json +++ b/config/github.webhooks.json @@ -11,6 +11,7 @@ "serviceBus": { "connectionString": "env://GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING", + "fullyQualifiedNamespace": "env://GITHUB_WEBHOOKS_SERVICEBUS_ENDPOINT", "queue": "env://GITHUB_WEBHOOKS_SERVICEBUS_QUEUE" }, diff --git a/config/github.webhooks.types.ts b/config/github.webhooks.types.ts index dbcf64a94..4b3cd5ac6 100644 --- a/config/github.webhooks.types.ts +++ b/config/github.webhooks.types.ts @@ -17,7 +17,8 @@ export type ConfigGitHubWebhooks = { provider: string; serviceBus: { - connectionString: string; + connectionString?: string; + fullyQualifiedNamespace?: string; queue: string; }; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..994510394 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,109 @@ +// +// Copyright (c) Microsoft. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +import globals from 'globals'; +import typescriptEslint from '@typescript-eslint/eslint-plugin'; +import pluginSecurity from 'eslint-plugin-security'; +import pluginN from 'eslint-plugin-n'; +import tsParser from '@typescript-eslint/parser'; +import js from '@eslint/js'; +import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; + +export default [ + pluginSecurity.configs.recommended, + { + rules: { + // These are so common in Node codebases it does not provide sufficient value to warn + 'security/detect-object-injection': 'off', + 'security/detect-non-literal-fs-filename': 'off', + }, + }, + { + ignores: [ + '.github/build/*.cjs', + '.github/build/*.js', + 'default-assets-package/thirdparty/**/*.js', + 'dist/**/*.js', + 'dist/**/*.cjs', + 'dist/**/*.mjs', + 'dist/**/*.d.ts', + '.environment/validate.js', + '.ossdev/build/*.cjs', + '**/frontend/', + '**/vendor/**/*', + '**/vendor.nocommit/**/*', + 'views/js/**/*', + '.eslint.config.mjs', // this file + ], + }, + js.configs.recommended, + eslintPluginPrettierRecommended, + { + // Rules added in eslint:recommended for ESLint v10 - disable for now + rules: { + 'no-useless-assignment': 'off', + 'preserve-caught-error': 'off', + 'no-unassigned-vars': 'off', + }, + }, + { + languageOptions: { + ecmaVersion: 2021, + sourceType: 'module', + }, + }, + { + files: ['**/*.js'], + + languageOptions: { + globals: { + ...globals.node, + }, + }, + }, + ...typescriptEslint.configs['flat/recommended'].map((config) => ({ + ...config, + files: ['**/*.ts'], + })), + ...[pluginN.configs['flat/recommended']].map((config) => ({ + ...config, + files: ['**/*.ts'], + })), + { + files: ['**/*.ts'], + + languageOptions: { + parser: tsParser, + }, + + rules: { + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-empty-interface': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-this-alias': 'off', + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-var-requires': 'off', + 'n/no-missing-import': 'off', + 'n/no-process-exit': 'off', + 'n/shebang': 'off', + 'no-case-declarations': 'off', + 'no-empty': 'off', + 'no-ex-assign': 'off', + 'no-inner-declarations': 'off', + 'no-useless-catch': 'off', + + 'prefer-const': [ + 'error', + { + destructuring: 'all', + }, + ], + + 'prefer-rest-params': 'off', + 'prefer-spread': 'off', + }, + }, +]; diff --git a/infra/terraform/dev/main.tf b/infra/terraform/dev/main.tf index 9d5df08b2..e335f6d9b 100644 --- a/infra/terraform/dev/main.tf +++ b/infra/terraform/dev/main.tf @@ -5,3 +5,20 @@ resource "azurerm_log_analytics_workspace" "main" { sku = "PerGB2018" retention_in_days = var.log_retention_days } + +data "azurerm_servicebus_namespace" "main" { + name = var.servicebus_namespace_name + resource_group_name = var.resource_group_name +} + +resource "azurerm_user_assigned_identity" "firehose" { + name = "nihdevgithubportal-firehose" + resource_group_name = var.resource_group_name + location = var.location +} + +resource "azurerm_role_assignment" "firehose_servicebus" { + scope = data.azurerm_servicebus_namespace.main.id + role_definition_name = "Azure Service Bus Data Receiver" + principal_id = azurerm_user_assigned_identity.firehose.principal_id +} diff --git a/infra/terraform/dev/outputs.tf b/infra/terraform/dev/outputs.tf index bfa5ea352..fc0ea4ea5 100644 --- a/infra/terraform/dev/outputs.tf +++ b/infra/terraform/dev/outputs.tf @@ -8,3 +8,18 @@ output "primary_shared_key" { value = azurerm_log_analytics_workspace.main.primary_shared_key sensitive = true } + +output "firehose_identity_id" { + description = "Resource ID of the firehose user-assigned managed identity. Used with --assign-identity in az container create." + value = azurerm_user_assigned_identity.firehose.id +} + +output "firehose_identity_client_id" { + description = "Client ID of the firehose managed identity. Passed as AZURE_CLIENT_ID to the ACI container so DefaultAzureCredential selects the right identity." + value = azurerm_user_assigned_identity.firehose.client_id +} + +output "servicebus_endpoint" { + description = "Fully qualified Service Bus namespace endpoint URL." + value = data.azurerm_servicebus_namespace.main.endpoint +} diff --git a/infra/terraform/dev/variables.tf b/infra/terraform/dev/variables.tf index d85944f10..533995348 100644 --- a/infra/terraform/dev/variables.tf +++ b/infra/terraform/dev/variables.tf @@ -20,3 +20,8 @@ variable "log_retention_days" { type = number default = 30 } + +variable "servicebus_namespace_name" { + description = "Name of the existing Azure Service Bus namespace" + type = string +} diff --git a/infra/terraform/prod/main.tf b/infra/terraform/prod/main.tf new file mode 100644 index 000000000..f67785863 --- /dev/null +++ b/infra/terraform/prod/main.tf @@ -0,0 +1,24 @@ +resource "azurerm_log_analytics_workspace" "main" { + name = var.log_analytics_workspace_name + location = var.location + resource_group_name = var.resource_group_name + sku = "PerGB2018" + retention_in_days = var.log_retention_days +} + +data "azurerm_servicebus_namespace" "main" { + name = var.servicebus_namespace_name + resource_group_name = var.resource_group_name +} + +resource "azurerm_user_assigned_identity" "firehose" { + name = "nihgithubportal-firehose" + resource_group_name = var.resource_group_name + location = var.location +} + +resource "azurerm_role_assignment" "firehose_servicebus" { + scope = data.azurerm_servicebus_namespace.main.id + role_definition_name = "Azure Service Bus Data Receiver" + principal_id = azurerm_user_assigned_identity.firehose.principal_id +} diff --git a/infra/terraform/prod/outputs.tf b/infra/terraform/prod/outputs.tf new file mode 100644 index 000000000..fc0ea4ea5 --- /dev/null +++ b/infra/terraform/prod/outputs.tf @@ -0,0 +1,25 @@ +output "workspace_id" { + description = "Log Analytics workspace ID (customer ID). Looked up at deploy time via az monitor โ€” not stored as a secret." + value = azurerm_log_analytics_workspace.main.workspace_id +} + +output "primary_shared_key" { + description = "Log Analytics primary shared key. Looked up at deploy time via az monitor โ€” not stored as a secret." + value = azurerm_log_analytics_workspace.main.primary_shared_key + sensitive = true +} + +output "firehose_identity_id" { + description = "Resource ID of the firehose user-assigned managed identity. Used with --assign-identity in az container create." + value = azurerm_user_assigned_identity.firehose.id +} + +output "firehose_identity_client_id" { + description = "Client ID of the firehose managed identity. Passed as AZURE_CLIENT_ID to the ACI container so DefaultAzureCredential selects the right identity." + value = azurerm_user_assigned_identity.firehose.client_id +} + +output "servicebus_endpoint" { + description = "Fully qualified Service Bus namespace endpoint URL." + value = data.azurerm_servicebus_namespace.main.endpoint +} diff --git a/infra/terraform/prod/providers.tf b/infra/terraform/prod/providers.tf new file mode 100644 index 000000000..104cec937 --- /dev/null +++ b/infra/terraform/prod/providers.tf @@ -0,0 +1,22 @@ +terraform { + required_version = ">= 1.5" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.110" + } + } + + # Backend config is supplied at init time via -backend-config flags. + # Required keys: storage_account_name, container_name, resource_group_name, key + backend "azurerm" {} +} + +provider "azurerm" { + features {} + + # Authenticates via OIDC federated identity (no client secret). + # ARM_CLIENT_ID, ARM_TENANT_ID, ARM_SUBSCRIPTION_ID are set from env by the workflow. + use_oidc = true +} diff --git a/infra/terraform/prod/variables.tf b/infra/terraform/prod/variables.tf new file mode 100644 index 000000000..b37fd54ea --- /dev/null +++ b/infra/terraform/prod/variables.tf @@ -0,0 +1,27 @@ +variable "resource_group_name" { + description = "Name of the prod Azure resource group" + type = string +} + +variable "location" { + description = "Azure region for all resources" + type = string + default = "centralus" +} + +variable "log_analytics_workspace_name" { + description = "Name for the Log Analytics workspace" + type = string + default = "nihgithubportal-logs" +} + +variable "log_retention_days" { + description = "Number of days to retain logs" + type = number + default = 30 +} + +variable "servicebus_namespace_name" { + description = "Name of the existing Azure Service Bus namespace" + type = string +} diff --git a/lib/queues/servicebus.ts b/lib/queues/servicebus.ts index e7e2f9061..336164c56 100644 --- a/lib/queues/servicebus.ts +++ b/lib/queues/servicebus.ts @@ -4,6 +4,7 @@ // import { DateTime } from 'luxon'; +import { DefaultAzureCredential } from '@azure/identity'; import { ServiceBusClient, ServiceBusReceivedMessage, ServiceBusReceiver } from '@azure/service-bus'; import { IQueueMessage, IQueueProcessor } from '.'; @@ -18,7 +19,8 @@ const maxWaitTimeInMs = 30 /* seconds */ * 1000; export interface IServiceBusQueueProcessorOptions { queue: string; - connectionString: string; + connectionString?: string; + fullyQualifiedNamespace?: string; } export class ServiceBusMessage implements IQueueMessage { @@ -52,15 +54,14 @@ export class ServiceBusMessage implements IQueueMessage { export default class ServiceBusQueueProcessor implements IQueueProcessor { #options: IServiceBusQueueProcessorOptions; - #service: ServiceBusClient; #receiver: ServiceBusReceiver; #initialized: boolean; supportsMultipleThreads: false; constructor(options: IServiceBusQueueProcessorOptions) { - if (!options.connectionString) { - throw new Error('options.connectionString required'); + if (!options.connectionString && !options.fullyQualifiedNamespace) { + throw new Error('options.connectionString or options.fullyQualifiedNamespace required'); } if (!options.queue) { throw new Error('options.queue required'); @@ -70,8 +71,9 @@ export default class ServiceBusQueueProcessor implements IQueueProcessor { async initialize(): Promise { const options = this.#options; - const service = new ServiceBusClient(options.connectionString); - this.#service = service; + const service = options.fullyQualifiedNamespace + ? new ServiceBusClient(options.fullyQualifiedNamespace, new DefaultAzureCredential()) + : new ServiceBusClient(options.connectionString); this.#receiver = service.createReceiver(options.queue, { receiveMode: 'peekLock' }); this.#initialized = true; } From 07a955ebbd00f64c61ab7979a00780a6f52b6140 Mon Sep 17 00:00:00 2001 From: Joel Peterson <54716797+petersonjdNIH@users.noreply.github.com> Date: Wed, 10 Jun 2026 02:23:27 +0000 Subject: [PATCH 208/209] revert: restore non-workflow files on main; fix #service ESLint error Reverts application/config/infra changes that should only live on staging: - lib/queues/servicebus.ts (restored to pre-managed-identity version) - config/github.webhooks.json + .types.ts - infra/terraform/dev/ (managed identity additions) - infra/terraform/prod/ (new prod Terraform) Keeps: - .github/workflows/ changes (intended for main) - eslint.config.mjs migration (required by ESLint 10; .eslintrc.js removed) Also fixes pre-existing ESLint error: #service private field was write-only --- config/github.webhooks.json | 1 - config/github.webhooks.types.ts | 3 +-- infra/terraform/dev/main.tf | 17 ----------------- infra/terraform/dev/outputs.tf | 15 --------------- infra/terraform/dev/variables.tf | 5 ----- infra/terraform/prod/main.tf | 24 ------------------------ infra/terraform/prod/outputs.tf | 25 ------------------------- infra/terraform/prod/providers.tf | 22 ---------------------- infra/terraform/prod/variables.tf | 27 --------------------------- lib/queues/servicebus.ts | 12 ++++-------- 10 files changed, 5 insertions(+), 146 deletions(-) delete mode 100644 infra/terraform/prod/main.tf delete mode 100644 infra/terraform/prod/outputs.tf delete mode 100644 infra/terraform/prod/providers.tf delete mode 100644 infra/terraform/prod/variables.tf diff --git a/config/github.webhooks.json b/config/github.webhooks.json index daec8f8df..847d9691a 100644 --- a/config/github.webhooks.json +++ b/config/github.webhooks.json @@ -11,7 +11,6 @@ "serviceBus": { "connectionString": "env://GITHUB_WEBHOOKS_SERVICEBUS_CONNECTIONSTRING", - "fullyQualifiedNamespace": "env://GITHUB_WEBHOOKS_SERVICEBUS_ENDPOINT", "queue": "env://GITHUB_WEBHOOKS_SERVICEBUS_QUEUE" }, diff --git a/config/github.webhooks.types.ts b/config/github.webhooks.types.ts index 4b3cd5ac6..dbcf64a94 100644 --- a/config/github.webhooks.types.ts +++ b/config/github.webhooks.types.ts @@ -17,8 +17,7 @@ export type ConfigGitHubWebhooks = { provider: string; serviceBus: { - connectionString?: string; - fullyQualifiedNamespace?: string; + connectionString: string; queue: string; }; diff --git a/infra/terraform/dev/main.tf b/infra/terraform/dev/main.tf index e335f6d9b..9d5df08b2 100644 --- a/infra/terraform/dev/main.tf +++ b/infra/terraform/dev/main.tf @@ -5,20 +5,3 @@ resource "azurerm_log_analytics_workspace" "main" { sku = "PerGB2018" retention_in_days = var.log_retention_days } - -data "azurerm_servicebus_namespace" "main" { - name = var.servicebus_namespace_name - resource_group_name = var.resource_group_name -} - -resource "azurerm_user_assigned_identity" "firehose" { - name = "nihdevgithubportal-firehose" - resource_group_name = var.resource_group_name - location = var.location -} - -resource "azurerm_role_assignment" "firehose_servicebus" { - scope = data.azurerm_servicebus_namespace.main.id - role_definition_name = "Azure Service Bus Data Receiver" - principal_id = azurerm_user_assigned_identity.firehose.principal_id -} diff --git a/infra/terraform/dev/outputs.tf b/infra/terraform/dev/outputs.tf index fc0ea4ea5..bfa5ea352 100644 --- a/infra/terraform/dev/outputs.tf +++ b/infra/terraform/dev/outputs.tf @@ -8,18 +8,3 @@ output "primary_shared_key" { value = azurerm_log_analytics_workspace.main.primary_shared_key sensitive = true } - -output "firehose_identity_id" { - description = "Resource ID of the firehose user-assigned managed identity. Used with --assign-identity in az container create." - value = azurerm_user_assigned_identity.firehose.id -} - -output "firehose_identity_client_id" { - description = "Client ID of the firehose managed identity. Passed as AZURE_CLIENT_ID to the ACI container so DefaultAzureCredential selects the right identity." - value = azurerm_user_assigned_identity.firehose.client_id -} - -output "servicebus_endpoint" { - description = "Fully qualified Service Bus namespace endpoint URL." - value = data.azurerm_servicebus_namespace.main.endpoint -} diff --git a/infra/terraform/dev/variables.tf b/infra/terraform/dev/variables.tf index 533995348..d85944f10 100644 --- a/infra/terraform/dev/variables.tf +++ b/infra/terraform/dev/variables.tf @@ -20,8 +20,3 @@ variable "log_retention_days" { type = number default = 30 } - -variable "servicebus_namespace_name" { - description = "Name of the existing Azure Service Bus namespace" - type = string -} diff --git a/infra/terraform/prod/main.tf b/infra/terraform/prod/main.tf deleted file mode 100644 index f67785863..000000000 --- a/infra/terraform/prod/main.tf +++ /dev/null @@ -1,24 +0,0 @@ -resource "azurerm_log_analytics_workspace" "main" { - name = var.log_analytics_workspace_name - location = var.location - resource_group_name = var.resource_group_name - sku = "PerGB2018" - retention_in_days = var.log_retention_days -} - -data "azurerm_servicebus_namespace" "main" { - name = var.servicebus_namespace_name - resource_group_name = var.resource_group_name -} - -resource "azurerm_user_assigned_identity" "firehose" { - name = "nihgithubportal-firehose" - resource_group_name = var.resource_group_name - location = var.location -} - -resource "azurerm_role_assignment" "firehose_servicebus" { - scope = data.azurerm_servicebus_namespace.main.id - role_definition_name = "Azure Service Bus Data Receiver" - principal_id = azurerm_user_assigned_identity.firehose.principal_id -} diff --git a/infra/terraform/prod/outputs.tf b/infra/terraform/prod/outputs.tf deleted file mode 100644 index fc0ea4ea5..000000000 --- a/infra/terraform/prod/outputs.tf +++ /dev/null @@ -1,25 +0,0 @@ -output "workspace_id" { - description = "Log Analytics workspace ID (customer ID). Looked up at deploy time via az monitor โ€” not stored as a secret." - value = azurerm_log_analytics_workspace.main.workspace_id -} - -output "primary_shared_key" { - description = "Log Analytics primary shared key. Looked up at deploy time via az monitor โ€” not stored as a secret." - value = azurerm_log_analytics_workspace.main.primary_shared_key - sensitive = true -} - -output "firehose_identity_id" { - description = "Resource ID of the firehose user-assigned managed identity. Used with --assign-identity in az container create." - value = azurerm_user_assigned_identity.firehose.id -} - -output "firehose_identity_client_id" { - description = "Client ID of the firehose managed identity. Passed as AZURE_CLIENT_ID to the ACI container so DefaultAzureCredential selects the right identity." - value = azurerm_user_assigned_identity.firehose.client_id -} - -output "servicebus_endpoint" { - description = "Fully qualified Service Bus namespace endpoint URL." - value = data.azurerm_servicebus_namespace.main.endpoint -} diff --git a/infra/terraform/prod/providers.tf b/infra/terraform/prod/providers.tf deleted file mode 100644 index 104cec937..000000000 --- a/infra/terraform/prod/providers.tf +++ /dev/null @@ -1,22 +0,0 @@ -terraform { - required_version = ">= 1.5" - - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "~> 3.110" - } - } - - # Backend config is supplied at init time via -backend-config flags. - # Required keys: storage_account_name, container_name, resource_group_name, key - backend "azurerm" {} -} - -provider "azurerm" { - features {} - - # Authenticates via OIDC federated identity (no client secret). - # ARM_CLIENT_ID, ARM_TENANT_ID, ARM_SUBSCRIPTION_ID are set from env by the workflow. - use_oidc = true -} diff --git a/infra/terraform/prod/variables.tf b/infra/terraform/prod/variables.tf deleted file mode 100644 index b37fd54ea..000000000 --- a/infra/terraform/prod/variables.tf +++ /dev/null @@ -1,27 +0,0 @@ -variable "resource_group_name" { - description = "Name of the prod Azure resource group" - type = string -} - -variable "location" { - description = "Azure region for all resources" - type = string - default = "centralus" -} - -variable "log_analytics_workspace_name" { - description = "Name for the Log Analytics workspace" - type = string - default = "nihgithubportal-logs" -} - -variable "log_retention_days" { - description = "Number of days to retain logs" - type = number - default = 30 -} - -variable "servicebus_namespace_name" { - description = "Name of the existing Azure Service Bus namespace" - type = string -} diff --git a/lib/queues/servicebus.ts b/lib/queues/servicebus.ts index 336164c56..71257a776 100644 --- a/lib/queues/servicebus.ts +++ b/lib/queues/servicebus.ts @@ -4,7 +4,6 @@ // import { DateTime } from 'luxon'; -import { DefaultAzureCredential } from '@azure/identity'; import { ServiceBusClient, ServiceBusReceivedMessage, ServiceBusReceiver } from '@azure/service-bus'; import { IQueueMessage, IQueueProcessor } from '.'; @@ -19,8 +18,7 @@ const maxWaitTimeInMs = 30 /* seconds */ * 1000; export interface IServiceBusQueueProcessorOptions { queue: string; - connectionString?: string; - fullyQualifiedNamespace?: string; + connectionString: string; } export class ServiceBusMessage implements IQueueMessage { @@ -60,8 +58,8 @@ export default class ServiceBusQueueProcessor implements IQueueProcessor { supportsMultipleThreads: false; constructor(options: IServiceBusQueueProcessorOptions) { - if (!options.connectionString && !options.fullyQualifiedNamespace) { - throw new Error('options.connectionString or options.fullyQualifiedNamespace required'); + if (!options.connectionString) { + throw new Error('options.connectionString required'); } if (!options.queue) { throw new Error('options.queue required'); @@ -71,9 +69,7 @@ export default class ServiceBusQueueProcessor implements IQueueProcessor { async initialize(): Promise { const options = this.#options; - const service = options.fullyQualifiedNamespace - ? new ServiceBusClient(options.fullyQualifiedNamespace, new DefaultAzureCredential()) - : new ServiceBusClient(options.connectionString); + const service = new ServiceBusClient(options.connectionString); this.#receiver = service.createReceiver(options.queue, { receiveMode: 'peekLock' }); this.#initialized = true; } From 995b4560b827d5ce897fcb46a84a87c624665344 Mon Sep 17 00:00:00 2001 From: purnesh-cit Date: Tue, 23 Jun 2026 12:45:40 -0400 Subject: [PATCH 209/209] Update SECURITY.md --- SECURITY.md | 101 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 24 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index a86e8a182..1ef015379 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,41 +1,94 @@ - +# Security Policy -# Security +This policy governs vulnerability research and reporting for NIH systems and services under the [HHS Vulnerability Disclosure Policy](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). +--- -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](), please report it to us as described below. +## Reporting a Vulnerability -## Reporting Security Issues +**Report all security issues using GitHub's private vulnerability reporting feature.** -**Please do not report security vulnerabilities through public GitHub issues.** +Click **"Report a vulnerability"** on the [Security Advisories](../../security/advisories) tab. Do not open a public issue or report through email, Slack, or any other channel. -Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). +Your report will be received securely, kept confidential, and routed to the right people. See [GitHub's documentation](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability) for how the process works. -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). +> **Note:** The HHS VDP also accepts reports at [hhs.responsibledisclosure.com](https://hhs.responsibledisclosure.com). For vulnerabilities in this repository or NIH systems hosted here, use the GitHub report link above so the responsible team is notified directly. -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). +Please include: +- What the vulnerability is and its potential impact +- Where it was found +- Steps to reproduce (proof-of-concept scripts or screenshots are helpful) -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: +--- -- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) -- Full paths of source file(s) related to the manifestation of the issue -- The location of the affected source code (tag/branch/commit or direct URL) -- Any special configuration required to reproduce the issue -- Step-by-step instructions to reproduce the issue -- Proof-of-concept or exploit code (if possible) -- Impact of the issue, including how an attacker might exploit the issue +## Authorization -This information will help us triage your report more quickly. +*Issued under the [HHS VDP โ€” Authorization](https://www.hhs.gov/vulnerability-disclosure-policy/index.html#authorization).* -If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. +Good faith research conducted under this policy is authorized. NIH and HHS will work with you to resolve issues quickly and will not pursue legal action related to your research. -## Preferred Languages +--- -We prefer all communications to be in English. +## Guidelines -## Policy +*Issued under the [HHS VDP โ€” Guidelines](https://www.hhs.gov/vulnerability-disclosure-policy/index.html#guidelines).* -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). +Authorized research means you: - +- Notify us as soon as possible after discovering a real or potential security issue +- Avoid privacy violations, user experience degradation, production system disruption, and data destruction or manipulation +- Use exploits only to the extent necessary to confirm a vulnerability โ€” do not exfiltrate data, establish access or persistence, or pivot to other systems +- Allow a reasonable amount of time to resolve the issue before public disclosure +- Do not compromise the privacy, safety, intellectual property, or financial interests of HHS/NIH personnel or third parties + +If you discover a vulnerability or encounter any sensitive data (PII, financial, proprietary, or trade secrets), **stop testing, report immediately via the GitHub private vulnerability report, and do not disclose the data to anyone else**. + +--- + +## Scope + +*Issued under the [HHS VDP โ€” Scope](https://www.hhs.gov/vulnerability-disclosure-policy/index.html#scope).* + +`nih.gov` and all its subdomains are in scope. Vendor systems are out of scope โ€” report those to the vendor directly. + +Unsure if a system is in scope? Contact [support@responsibledisclosure.com](mailto:support@responsibledisclosure.com) before testing. + +--- + +## Rules of Engagement + +*Issued under the [HHS VDP โ€” Rules of Engagement](https://www.hhs.gov/vulnerability-disclosure-policy/index.html#rules-engagement).* + +**Must not:** +- Test systems outside the scope above +- Disclose vulnerability information except as described in this policy +- Conduct physical testing, social engineering, or phishing +- Execute denial-of-service or resource exhaustion attacks +- Introduce malicious software +- Degrade, impair, disrupt, or disable HHS/NIH systems +- Test third-party applications or services that integrate with NIH systems +- Delete, alter, share, retain, destroy, or exfiltrate HHS/NIH data +- Use an exploit to establish access, persistence, or pivot to other systems + +**May:** +- View or store NIH nonpublic data only as necessary to document a potential vulnerability + +**Must:** +- Cease testing and immediately report any vulnerability or nonpublic data exposure via the GitHub private vulnerability report +- Purge any stored NIH nonpublic data upon reporting + +--- + +## Disclosure + +*Issued under the [HHS VDP โ€” Disclosure](https://www.hhs.gov/vulnerability-disclosure-policy/index.html#disclosure).* + +Do not share details about discovered vulnerabilities for **90 calendar days** after receiving our acknowledgment. If you believe earlier disclosure is warranted, coordinate with us in advance. + +Reports may be shared with [CISA](https://www.cisa.gov/) and affected vendors under their [coordinated vulnerability disclosure process](https://www.cisa.gov/coordinated-vulnerability-disclosure-process). We will not share your name or contact information without explicit permission. + +--- + +## Questions + +Email [HHS.Cybersecurity@hhs.gov](mailto:HHS.Cybersecurity@hhs.gov) or see the [HHS VDP](https://www.hhs.gov/vulnerability-disclosure-policy/index.html#questions).