Fixed issues around the Azure OpenAI API in the code reviewer

This commit is contained in:
Jimmy Royer 2024-09-04 17:14:09 -04:00
parent cb0db573b8
commit ea35bd1354
15 changed files with 5705 additions and 348 deletions

View file

@ -1,36 +1,13 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
"name": "Node.js & TypeScript",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
"features": {
"ghcr.io/devcontainers/features/aws-cli:1": {},
// "ghcr.io/devcontainers/features/azure-cli:1": {},
// "ghcr.io/devcontainers/features/common-utils:2": {},
// "ghcr.io/devcontainers/features/git:1": {},
// "ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/eitsupi/devcontainer-features/jq-likes:2": {},
"ghcr.io/dhoeric/features/act:1": {}
// "ghcr.io/guiyomh/features/just:0": {},
// "ghcr.io/jungaretti/features/ripgrep:1": {},
// "ghcr.io/lukewiwa/features/shellcheck:0": {},
// "ghcr.io/jsburckhardt/devcontainer-features/gitleaks:1": {},
// "ghcr.io/va-h/devcontainers-features/difftastic:1": {}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "yarn install",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

View file

@ -16,5 +16,7 @@ jobs:
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_API_MODEL: "gpt-4-1106-preview"
OPENAI_API_MODEL: ${{ vars.OPENAI_API_MODEL }}
OPENAI_API_VERSION: ${{ vars.OPENAI_API_VERSION }}
OPENAI_BASE_URL: ${{ vars.OPENAI_BASE_URL }}
exclude: "yarn.lock,dist/**"

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
node_modules
.idea
lib/**/*
.secrets
act/.secrets

3
act/codereview.vars Normal file
View file

@ -0,0 +1,3 @@
OPENAI_BASE_URL=https://cds-snc.openai.azure.com/openai/deployments/gpt-4o/
OPENAI_API_MODEL=gpt-4o
OPENAI_API_VERSION=2024-02-15-preview

10
act/event.json Normal file
View file

@ -0,0 +1,10 @@
{
"action": "opened",
"repository": {
"owner": {
"login": "cds-snc"
},
"name": "cds-ai-codereviewer"
},
"number": 3
}

28
act/fixtures/action.yml Normal file
View file

@ -0,0 +1,28 @@
name: "CDS AI Code Review Action (act fixture)"
description: "Perform code reviews and comment on diffs using OpenAI API."
inputs:
GITHUB_TOKEN:
description: "GitHub token to interact with the repository."
required: true
OPENAI_API_KEY:
description: "OpenAI API key for GPT."
required: true
OPENAI_API_MODEL:
description: "OpenAI API model."
required: true
OPENAI_API_VERSION:
description: "OpenAI API version."
required: true
OPENAI_BASE_URL:
description: "Base URL to the OpenAI API model (OpenAI or Azure)."
required: true
exclude:
description: "Glob patterns to exclude files from the diff analysis"
required: false
default: ""
runs:
using: "node16"
main: "dist/index.js"
branding:
icon: "aperture"
color: "green"

View file

@ -0,0 +1,25 @@
name: CDS Code Review with OpenAI
on:
pull_request:
types:
- opened
- synchronize
permissions: write-all
jobs:
code_review:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
path: ./
- name: Code Review
uses: ./act/fixtures/
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_API_MODEL: ${{ vars.OPENAI_API_MODEL }}
OPENAI_API_VERSION: ${{ vars.OPENAI_API_VERSION }}
OPENAI_BASE_URL: ${{ vars.OPENAI_BASE_URL }}
exclude: "yarn.lock,dist/**"

View file

@ -9,11 +9,13 @@ inputs:
required: true
OPENAI_API_MODEL:
description: "OpenAI API model."
required: false
default: "gpt-4"
OPEN_AI_BASE_URL:
description: "Base URL to the API model (Open AI or Azure portal)."
required: false
required: true
OPENAI_API_VERSION:
description: "OpenAI API version."
required: true
OPENAI_BASE_URL:
description: "Base URL to the OpenAI API model (OpenAI or Azure)."
required: true
exclude:
description: "Glob patterns to exclude files from the diff analysis"
required: false

5399
dist/index.js vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

93
dist/licenses.txt vendored
View file

@ -561,6 +561,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
debug
MIT
(The MIT License)
Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2018-2021 Josh Junon
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the 'Software'), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
deprecation
ISC
The ISC License
@ -702,6 +726,25 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
json-stringify-safe
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
minimatch
ISC
The ISC License
@ -746,6 +789,31 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
nock
MIT
MIT License
Copyright (c) 2011-2019 Pedro Teixeira and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
node-domexception
MIT
MIT License
@ -1045,6 +1113,31 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
propagate
MIT
The MIT License
Copyright (c) 2015-2019 Pedro Teixeira and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
tr46
MIT

72
package-lock.json generated
View file

@ -10,9 +10,9 @@
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
"@azure/openai": "2.0.0-beta.1",
"@octokit/rest": "^19.0.7",
"minimatch": "^7.4.2",
"nock": "^13.5.5",
"openai": "^4.20.1",
"parse-diff": "^0.11.1",
"ts-node": "^10.9.1"
@ -43,18 +43,6 @@
"tunnel": "^0.0.6"
}
},
"node_modules/@azure/openai": {
"version": "2.0.0-beta.1",
"resolved": "https://registry.npmjs.org/@azure/openai/-/openai-2.0.0-beta.1.tgz",
"integrity": "sha512-SMcGMbhv8gYiTvmv2aKlkDAW0sI5pjGW5KyC94DTAYgpZS7eK+B1WpCfuJLzVaLxbYZXYWTsmd+dCsS4rXJ9+w==",
"license": "MIT",
"dependencies": {
"tslib": "^2.6.3"
},
"engines": {
"node": ">=18.0.0"
}
},
"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",
@ -420,6 +408,29 @@
"node": "*"
}
},
"node_modules/debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/debug/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/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@ -529,6 +540,12 @@
"node": ">=0.10.0"
}
},
"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": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"license": "ISC"
},
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
@ -588,6 +605,20 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/nock": {
"version": "13.5.5",
"resolved": "https://registry.npmjs.org/nock/-/nock-13.5.5.tgz",
"integrity": "sha512-XKYnqUrCwXC8DGG1xX4YH5yNIrlh9c065uaMZZHUoeUUINTOyt+x/G+ezYk0Ft6ExSREVIs+qBJDK503viTfFA==",
"license": "MIT",
"dependencies": {
"debug": "^4.1.0",
"json-stringify-safe": "^5.0.1",
"propagate": "^2.0.0"
},
"engines": {
"node": ">= 10.13"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@ -678,6 +709,15 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/propagate": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
"license": "MIT",
"engines": {
"node": ">= 8"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@ -727,12 +767,6 @@
}
}
},
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"license": "0BSD"
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",

View file

@ -13,9 +13,9 @@
},
"dependencies": {
"@actions/core": "^1.10.0",
"@azure/openai": "2.0.0-beta.1",
"@octokit/rest": "^19.0.7",
"minimatch": "^7.4.2",
"nock": "^13.5.5",
"openai": "^4.20.1",
"parse-diff": "^0.11.1",
"ts-node": "^10.9.1"

View file

@ -4,20 +4,35 @@ import OpenAI from "openai";
import { Octokit } from "@octokit/rest";
import parseDiff, { Chunk, File } from "parse-diff";
import minimatch from "minimatch";
// import { OpenAI as AzureOpenAI } from "@azure/openai";
import { Certificate } from "crypto";
const GITHUB_TOKEN: string = core.getInput("GITHUB_TOKEN");
const OPENAI_API_KEY: string = core.getInput("OPENAI_API_KEY");
const OPENAI_API_MODEL: string = core.getInput("OPENAI_API_MODEL");
const OPEN_AI_BASE_URL: string | undefined =
core.getInput("OPEN_AI_BASE_URL") || undefined; // Keep the default value as undefined instead of empty strings.
const OPENAI_API_VERSION: string = core.getInput("OPENAI_API_VERSION");
const OPENAI_BASE_URL: string = core.getInput("OPENAI_BASE_URL"); // Keep the default value as undefined instead of empty strings.
// Supports HTTP requests debugging via an environment variable.
const debugHttp: string | undefined = process.env.DEBUG_HTTP;
if (debugHttp) {
// Intercept all HTTP requests
const nock = require('nock');
nock.recorder.rec({
output_objects: true,
logging: (content: any) => {
console.log('HTTP Request:', content);
}
});
console.log("HTTP calls interception enabled");
}
const octokit = new Octokit({ auth: GITHUB_TOKEN });
const openai = new OpenAI({
apiKey: OPENAI_API_KEY,
baseURL: OPEN_AI_BASE_URL || undefined,
baseURL: OPENAI_BASE_URL,
defaultQuery: { "api-version": OPENAI_API_VERSION },
defaultHeaders: { "api-key": OPENAI_API_KEY },
});
interface PRDetails {
@ -92,8 +107,7 @@ function createPrompt(file: File, chunk: Chunk, prDetails: PRDetails): string {
- Use the given description only for the overall context and only comment the code.
- IMPORTANT: NEVER suggest adding comments to the code.
Review the following code diff in the file "${
file.to
Review the following code diff in the file "${file.to
}" and take the pull request title and description into account when writing the response.
Pull request title: ${prDetails.title}
@ -132,7 +146,7 @@ async function getAIResponse(prompt: string): Promise<Array<{
const response = await openai.chat.completions.create({
...queryConfig,
// return JSON if the model supports it:
...(OPENAI_API_MODEL === "gpt-4-1106-preview"
...(OPENAI_API_MODEL === "gpt-4-1106-preview" || OPENAI_API_MODEL === "gpt-4o"
? { response_format: { type: "json_object" } }
: {}),
messages: [
@ -215,7 +229,7 @@ async function main() {
diff = String(response.data);
} else {
console.log("Unsupported event:", process.env.GITHUB_EVENT_NAME);
console.log(`Unsupported event: action=${eventData.action}, process.env.GITHUB_EVENT_NAME=${process.env.GITHUB_EVENT_NAME}`);
return;
}
@ -239,12 +253,13 @@ async function main() {
const comments = await analyzeCode(filteredDiff, prDetails);
if (comments.length > 0) {
await createReviewComment(
prDetails.owner,
prDetails.repo,
prDetails.pull_number,
comments
);
// await createReviewComment(
// prDetails.owner,
// prDetails.repo,
// prDetails.pull_number,
// comments
// );
await console.log("Comments:", comments);
}
}

View file

@ -17,13 +17,6 @@
dependencies:
tunnel "^0.0.6"
"@azure/openai@2.0.0-beta.1":
version "2.0.0-beta.1"
resolved "https://registry.npmjs.org/@azure/openai/-/openai-2.0.0-beta.1.tgz"
integrity sha512-SMcGMbhv8gYiTvmv2aKlkDAW0sI5pjGW5KyC94DTAYgpZS7eK+B1WpCfuJLzVaLxbYZXYWTsmd+dCsS4rXJ9+w==
dependencies:
tslib "^2.6.3"
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz"
@ -266,6 +259,13 @@ crypt@0.0.2:
resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz"
integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
debug@^4.1.0:
version "4.3.6"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz"
integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==
dependencies:
ms "2.1.2"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
@ -333,6 +333,11 @@ is-plain-object@^5.0.0:
resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
json-stringify-safe@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz"
@ -371,6 +376,20 @@ ms@^2.0.0:
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
nock@^13.5.5:
version "13.5.5"
resolved "https://registry.npmjs.org/nock/-/nock-13.5.5.tgz"
integrity sha512-XKYnqUrCwXC8DGG1xX4YH5yNIrlh9c065uaMZZHUoeUUINTOyt+x/G+ezYk0Ft6ExSREVIs+qBJDK503viTfFA==
dependencies:
debug "^4.1.0"
json-stringify-safe "^5.0.1"
propagate "^2.0.0"
node-domexception@1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz"
@ -415,6 +434,11 @@ prettier@^2.8.6:
resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.6.tgz"
integrity sha512-mtuzdiBbHwPEgl7NxWlqOkithPyp4VN93V7VeHVWBF+ad3I5avc0RVDT4oImXQy9H/AqxA2NSQH8pSxHW6FYbQ==
propagate@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz"
integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
@ -439,11 +463,6 @@ ts-node@^10.9.1:
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
tslib@^2.6.3:
version "2.7.0"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz"
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz"