From a2930f15038b8142bcab052cc94562450dcae087 Mon Sep 17 00:00:00 2001 From: Winston Liu Date: Sun, 19 Nov 2023 17:26:09 -0800 Subject: [PATCH] Switch to ESLint (#555) * Initial migration to ESLint * Recommend ESLint instead of TSLint * Fix prefer-const * Fix no-useless-escape * Fix restrict-template-expressions * Fix no-floating-promises * Fix no-unsafe-enum-comparison * Fix ban-types * Fix no-unused-vars * Fix no-array-constructor, no-var * Fix require-await * Fix no-misused-promises * Fix no-unbound-method * Fix no-namespace * Lint telemetryHelper * Lint graphHelper * Delete unused OperationsClient * Lint ServiceConnection* * Lint configure * Another round of lint configuration * Lint restClient * Ignore parseError * Lint in CI * Make it stricter * Better fix for schemaContributor * Add a missing progress notification * Ignore tools for CI, I guess --- .azure-pipelines/common-steps.yml | 3 + .eslintignore | 4 + .eslintrc.js | 24 + .vscode/extensions.json | 4 +- package-lock.json | 1904 +++++++++++++---- package.json | 5 +- src/configure/activate.ts | 2 +- .../clients/azure/appServiceClient.ts | 21 +- .../clients/devOps/operationsClient.ts | 47 - .../clients/devOps/serviceConnectionClient.ts | 74 +- src/configure/clients/restClient.ts | 8 +- src/configure/configure.ts | 267 ++- src/configure/helper/commonHelper.ts | 18 +- src/configure/helper/controlProvider.ts | 19 +- .../helper/devOps/azureDevOpsHelper.ts | 238 +-- .../helper/devOps/serviceConnectionHelper.ts | 28 +- src/configure/helper/gitHubHelper.ts | 58 +- src/configure/helper/graphHelper.ts | 20 +- src/configure/helper/templateHelper.ts | 26 +- src/configure/model/models.ts | 2 +- src/configure/resources/constants.ts | 140 -- src/configure/resources/tracePoints.ts | 23 +- src/extension.ts | 4 +- src/extensionApis.ts | 10 +- src/helpers/constants.ts | 28 - src/helpers/parseError.ts | 3 + src/helpers/telemetryHelper.ts | 28 +- src/helpers/telemetryKeys.ts | 40 +- src/messages.ts | 123 +- src/schema-association-service-1espt.ts | 18 +- src/schema-association-service.ts | 54 +- src/schema-contributor.ts | 27 +- src/test/helper.ts | 5 +- src/test/index.ts | 3 +- src/test/runTest.ts | 2 +- .../suite/configure/azureDevOpsHelper.test.ts | 46 +- src/test/suite/configure/gitHubHelper.test.ts | 22 +- src/test/suite/fromserver.test.ts | 2 +- .../extract-yaml-testcases/package-lock.json | 740 +------ tools/extract-yaml-testcases/package.json | 9 +- tools/extract-yaml-testcases/src/main.ts | 53 +- tools/extract-yaml-testcases/tsconfig.json | 14 +- tsconfig.json | 3 - tsconfig.test.json | 4 +- tslint.json | 15 - 45 files changed, 2121 insertions(+), 2067 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js delete mode 100644 src/configure/clients/devOps/operationsClient.ts delete mode 100644 src/helpers/constants.ts delete mode 100644 tslint.json diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml index 335fad05..4634c286 100644 --- a/.azure-pipelines/common-steps.yml +++ b/.azure-pipelines/common-steps.yml @@ -26,6 +26,9 @@ steps: env: DISPLAY: ':99.0' +- script: npm run lint + displayName: Lint + # Acquire the `vsce` tool and use it to package - script: | npm install -g vsce diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..9ed27677 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +dist +node_modules +out +tools diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..7ab6e119 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,24 @@ +/* eslint-env node */ +module.exports = { + extends: [ + 'eslint:recommended', + ], + env: { + node: true + }, + parserOptions: { + ecmaVersion: "latest" + }, + root: true, + overrides: [ + { + extends: ['plugin:@typescript-eslint/strict-type-checked'], + files: ['./**/*.{ts,tsx}'], + parser: '@typescript-eslint/parser', + parserOptions: { + project: true, + }, + plugins: ['@typescript-eslint'], + }, + ], +}; diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 0a18b9c4..3ac9aeb6 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,6 +2,6 @@ // See http://go.microsoft.com/fwlink/?LinkId=827846 // for the documentation about the extensions.json format "recommendations": [ - "ms-vscode.vscode-typescript-tslint-plugin" + "dbaeumer.vscode-eslint" ] -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index 03082540..224e9ba5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,15 +31,17 @@ "@types/node": "^14.16.0", "@types/uuid": "^8.3.4", "@types/vscode": "~1.64.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", "@vscode/test-electron": "^1.6.2", "ajv": "^6.9.1", "assert": "1.4.1", "copy-webpack-plugin": "^10.2.0", + "eslint": "^8.54.0", "glob": "^7.1.6", "mocha": "^9.1.1", "ts-loader": "^8.0.14", "ts-node": "7.0.1", - "tslint": "5.8.0", "typescript": "~5.2.2", "webpack": "^5.76.0", "webpack-cli": "^4.4.0" @@ -49,6 +51,15 @@ "vscode": "^1.64.0" } }, + "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/@azure/abort-controller": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.4.tgz", @@ -154,6 +165,113 @@ "node": ">=10.0.0" } }, + "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, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/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==", + "dev": true + }, + "node_modules/@eslint/eslintrc/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==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/js": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", + "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "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": "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 + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -308,9 +426,9 @@ "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "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/minimatch": { @@ -337,6 +455,12 @@ "integrity": "sha512-USUftMYpmuMzeWobskoPfzDi+vkpe0dvcOBRNOscFrGxVp4jomnRxWuVohgqBow2xyIPC0S3gjxV/5079jhmDg==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", + "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==", + "dev": true + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -349,12 +473,313 @@ "integrity": "sha512-bSlAWz5WtcSL3cO9tAT/KpEH9rv5OBnm93OIIFwdCshaAiqr2bp1AUyEwW9MWeCvZBHEXc3V0fTYVdVyzDNwHA==", "dev": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.11.0.tgz", + "integrity": "sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.11.0", + "@typescript-eslint/type-utils": "6.11.0", + "@typescript-eslint/utils": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "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" + }, + "engines": { + "node": "^16.0.0 || >=18.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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.11.0.tgz", + "integrity": "sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.11.0", + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/typescript-estree": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz", + "integrity": "sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.11.0.tgz", + "integrity": "sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.11.0", + "@typescript-eslint/utils": "6.11.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.11.0.tgz", + "integrity": "sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz", + "integrity": "sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.11.0.tgz", + "integrity": "sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.11.0", + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/typescript-estree": "6.11.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz", + "integrity": "sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, + "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/@vscode/extension-telemetry": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.5.1.tgz", @@ -592,9 +1017,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -612,6 +1037,15 @@ "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, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/adal-node": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.2.3.tgz", @@ -863,81 +1297,6 @@ "node": "*" } }, - "node_modules/babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "node_modules/babel-code-frame/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/babel-code-frame/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1068,15 +1427,6 @@ "node": ">=0.2.0" } }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -1089,6 +1439,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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, + "engines": { + "node": ">=6" + } + }, "node_modules/camelcase": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", @@ -1404,6 +1763,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1433,6 +1798,18 @@ "node": ">=8" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -1634,6 +2011,61 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", + "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.54.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" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -1647,6 +2079,90 @@ "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==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/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==", + "dev": true + }, + "node_modules/eslint/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==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/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, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/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, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/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==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "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==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -1659,6 +2175,27 @@ "node": ">=4" } }, + "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, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/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, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -1766,6 +2303,12 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "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 + }, "node_modules/fastest-levenshtein": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", @@ -1781,6 +2324,18 @@ "reusify": "^1.0.4" } }, + "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/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1818,6 +2373,26 @@ "flat": "cli.js" } }, + "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/flatted": { + "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.14.8", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", @@ -1974,6 +2549,21 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globby": { "version": "12.2.0", "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", @@ -2000,6 +2590,12 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -2020,27 +2616,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2136,12 +2711,37 @@ } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "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, + "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, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, "engines": { - "node": ">= 4" + "node": ">=4" } }, "node_modules/import-local": { @@ -2160,6 +2760,15 @@ "node": ">=8" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2247,6 +2856,15 @@ "node": ">=0.12.0" } }, + "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, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -2327,12 +2945,6 @@ "node": ">= 10.13.0" } }, - "node_modules/js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, "node_modules/js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", @@ -2345,6 +2957,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "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-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", @@ -2357,6 +2975,12 @@ "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", @@ -2393,6 +3017,15 @@ "safe-buffer": "^5.0.1" } }, + "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" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -2402,6 +3035,19 @@ "node": ">=0.10.0" } }, + "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, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/listenercount": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", @@ -2451,6 +3097,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "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/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -2716,6 +3368,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "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 + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -2800,6 +3458,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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, + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2839,6 +3514,18 @@ "node": ">=6" } }, + "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, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2963,6 +3650,15 @@ "node": ">=8" } }, + "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, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -3517,6 +4213,12 @@ } } }, + "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 + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3543,6 +4245,18 @@ "node": "*" } }, + "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-loader": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.3.0.tgz", @@ -3599,141 +4313,36 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "dependencies": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.1.2" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev" - } - }, - "node_modules/tslint/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" - }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "engines": { - "node": ">=4" + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, - "node_modules/tslint/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==", + "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, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/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==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/tslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/tslint/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslint/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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/tslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" + "node": ">= 0.8.0" } }, - "node_modules/tslint/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/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, - "dependencies": { - "has-flag": "^3.0.0" - }, "engines": { - "node": ">=4" - } - }, - "node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" + "node": ">=10" }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "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" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typed-rest-client": { @@ -4259,6 +4868,12 @@ } }, "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 + }, "@azure/abort-controller": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.4.tgz", @@ -4357,6 +4972,84 @@ "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", "dev": true }, + "@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, + "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.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "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" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, + "@eslint/js": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", + "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", + "dev": true + }, + "@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", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "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 + }, "@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -4490,9 +5183,9 @@ "dev": true }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "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/minimatch": { @@ -4519,17 +5212,193 @@ "integrity": "sha512-USUftMYpmuMzeWobskoPfzDi+vkpe0dvcOBRNOscFrGxVp4jomnRxWuVohgqBow2xyIPC0S3gjxV/5079jhmDg==", "dev": true }, + "@types/semver": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", + "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==", + "dev": true + }, "@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, - "@types/vscode": { - "version": "1.64.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.64.0.tgz", - "integrity": "sha512-bSlAWz5WtcSL3cO9tAT/KpEH9rv5OBnm93OIIFwdCshaAiqr2bp1AUyEwW9MWeCvZBHEXc3V0fTYVdVyzDNwHA==", - "dev": true + "@types/vscode": { + "version": "1.64.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.64.0.tgz", + "integrity": "sha512-bSlAWz5WtcSL3cO9tAT/KpEH9rv5OBnm93OIIFwdCshaAiqr2bp1AUyEwW9MWeCvZBHEXc3V0fTYVdVyzDNwHA==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.11.0.tgz", + "integrity": "sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.11.0", + "@typescript-eslint/type-utils": "6.11.0", + "@typescript-eslint/utils": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "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" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.11.0.tgz", + "integrity": "sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "6.11.0", + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/typescript-estree": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "debug": "^4.3.4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz", + "integrity": "sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.11.0.tgz", + "integrity": "sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "6.11.0", + "@typescript-eslint/utils": "6.11.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@typescript-eslint/types": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.11.0.tgz", + "integrity": "sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz", + "integrity": "sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "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 + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.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" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, + "@typescript-eslint/utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.11.0.tgz", + "integrity": "sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==", + "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.11.0", + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/typescript-estree": "6.11.0", + "semver": "^7.5.4" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz", + "integrity": "sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.11.0", + "eslint-visitor-keys": "^3.4.1" + } }, "@ungap/promise-all-settled": { "version": "1.1.2", @@ -4537,6 +5406,12 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, + "@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 + }, "@vscode/extension-telemetry": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.5.1.tgz", @@ -4749,9 +5624,9 @@ } }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true }, "acorn-import-assertions": { @@ -4761,6 +5636,13 @@ "dev": true, "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": {} + }, "adal-node": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.2.3.tgz", @@ -4958,65 +5840,6 @@ "yaml-ast-parser": "0.0.43" } }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -5116,12 +5939,6 @@ "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -5131,6 +5948,12 @@ "get-intrinsic": "^1.0.2" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camelcase": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", @@ -5358,6 +6181,12 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, + "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 + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5378,6 +6207,15 @@ "path-type": "^4.0.0" } }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -5550,6 +6388,94 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "eslint": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", + "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.54.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" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "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" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "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, + "requires": { + "is-glob": "^4.0.3" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5560,11 +6486,45 @@ "estraverse": "^4.1.1" } }, + "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", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -5647,6 +6607,12 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "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 + }, "fastest-levenshtein": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", @@ -5662,6 +6628,15 @@ "reusify": "^1.0.4" } }, + "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, + "requires": { + "flat-cache": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -5687,6 +6662,23 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "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": { "version": "1.14.8", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", @@ -5794,6 +6786,15 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, "globby": { "version": "12.2.0", "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", @@ -5814,6 +6815,12 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -5828,23 +6835,6 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5913,11 +6903,29 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "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", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "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 + } + } + }, "import-local": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", @@ -5928,6 +6936,12 @@ "resolve-cwd": "^3.0.0" } }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5994,6 +7008,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "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 + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -6050,12 +7070,6 @@ "supports-color": "^8.0.0" } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", @@ -6065,6 +7079,12 @@ "esprima": "^4.0.0" } }, + "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-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", @@ -6077,6 +7097,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "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 + }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -6107,12 +7133,31 @@ "safe-buffer": "^5.0.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" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "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" + } + }, "listenercount": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", @@ -6150,6 +7195,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "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 + }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -6360,6 +7411,12 @@ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -6418,6 +7475,20 @@ "mimic-fn": "^2.1.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", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6442,6 +7513,15 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "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, + "requires": { + "callsites": "^3.0.0" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6532,6 +7612,12 @@ } } }, + "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 + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -6909,6 +7995,12 @@ "terser": "^5.7.2" } }, + "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 + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6929,6 +8021,13 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", "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-loader": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.3.0.tgz", @@ -6971,108 +8070,25 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "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, - "requires": { - "color-convert": "^1.9.0" - } - }, - "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, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "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, - "requires": { - "has-flag": "^3.0.0" - } - } - } + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "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": { - "tslib": "^1.8.1" + "prelude-ls": "^1.2.1" } }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + "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 }, "typed-rest-client": { "version": "1.8.6", diff --git a/package.json b/package.json index bbd01707..a1d81f99 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,7 @@ "compile": "webpack --mode production --progress --color", "compile:dev": "webpack --mode development --progress --color", "compile:test": "tsc --project ./tsconfig.test.json", + "lint": "eslint .", "watch": "webpack --mode development --progress --color --watch", "test": "npm run compile:test && node ./out/test/runTest.js" }, @@ -147,15 +148,17 @@ "@types/node": "^14.16.0", "@types/uuid": "^8.3.4", "@types/vscode": "~1.64.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", "@vscode/test-electron": "^1.6.2", "ajv": "^6.9.1", "assert": "1.4.1", "copy-webpack-plugin": "^10.2.0", + "eslint": "^8.54.0", "glob": "^7.1.6", "mocha": "^9.1.1", "ts-loader": "^8.0.14", "ts-node": "7.0.1", - "tslint": "5.8.0", "typescript": "~5.2.2", "webpack": "^5.76.0", "webpack-cli": "^4.4.0" diff --git a/src/configure/activate.ts b/src/configure/activate.ts index 41550a1a..66b64234 100644 --- a/src/configure/activate.ts +++ b/src/configure/activate.ts @@ -3,7 +3,7 @@ import * as vscode from 'vscode'; import { configurePipeline } from './configure'; import { telemetryHelper } from '../helpers/telemetryHelper'; -export async function activateConfigurePipeline(): Promise { +export function activateConfigurePipeline(): void { vscode.commands.registerCommand('azure-pipelines.configure-pipeline', async () => { await telemetryHelper.callWithTelemetryAndErrorHandling('azurePipelines.configure-pipeline', async () => { await configurePipeline(); diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts index 8d1576c0..66e84518 100644 --- a/src/configure/clients/azure/appServiceClient.ts +++ b/src/configure/clients/azure/appServiceClient.ts @@ -3,18 +3,12 @@ import { WebSiteManagementClient, WebSiteManagementModels } from '@azure/arm-app import { TokenCredentialsBase } from '@azure/ms-rest-nodeauth'; import { WebAppKind, ValidatedSite } from '../../model/models'; -import { Messages } from '../../../messages'; export class AppServiceClient { - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private portalUrl: string; - constructor(credentials: TokenCredentialsBase, tenantId: string, portalUrl: string, subscriptionId: string) { + constructor(credentials: TokenCredentialsBase, subscriptionId: string) { this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.portalUrl = portalUrl; } public async getAppServices(filterForResourceKind: WebAppKind): Promise { @@ -22,19 +16,6 @@ export class AppServiceClient { return sites.filter(site => site.kind === filterForResourceKind); } - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(site: ValidatedSite): Promise { - const metadata = await this.getAppServiceMetadata(site); - if (metadata.properties?.['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - public async getAppServiceConfig(site: ValidatedSite): Promise { return this.webSiteManagementClient.webApps.getConfiguration(site.resourceGroup, site.name); } diff --git a/src/configure/clients/devOps/operationsClient.ts b/src/configure/clients/devOps/operationsClient.ts deleted file mode 100644 index a4e65386..00000000 --- a/src/configure/clients/devOps/operationsClient.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as azdev from 'azure-devops-node-api'; -import * as util from 'util'; -import { OperationReference, OperationStatus } from 'azure-devops-node-api/interfaces/common/OperationsInterfaces'; -import { sleepForMilliSeconds } from '../../helper/commonHelper'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { Messages } from '../../../messages'; - -export class OperationsClient { - private connection: azdev.WebApi; - private organizationName: string; - - constructor(organizationName: string, connection: azdev.WebApi) { - this.connection = connection; - this.organizationName = organizationName; - } - - public async waitForOperationSuccess(operationId: string): Promise { - const url = `${AzureDevOpsBaseUrl}/${this.organizationName}/_apis/operations/${operationId}`; - - for (let attempt = 0; attempt < 30; attempt++) { - const response = await this.connection.rest.get(url, { - acceptHeader: "application/json;api-version=5.1-preview.1", - additionalHeaders: { - "Content-Type": "application/json", - }, - }); - - if (response.statusCode !== 200) { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, response.statusCode)); - } - - const operation = response.result; - if (operation?.status === OperationStatus.Succeeded) { - return; - } - - if (operation?.status === OperationStatus.Failed) { - // OperationReference is missing some properties so cast it to any - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, (operation as any).detailedMessage)); - } - - await sleepForMilliSeconds(2000); - } - - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, Messages.operationTimedOut)); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts index 36d48c83..9bec2c83 100644 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ b/src/configure/clients/devOps/serviceConnectionClient.ts @@ -1,22 +1,29 @@ import * as azdev from 'azure-devops-node-api'; import { AadApplication } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -export class ServiceConnectionClient { - private connection: azdev.WebApi; - private organizationName: string; - private projectName: string; +// Definitive interface at https://github.com/microsoft/azure-devops-node-api/blob/master/api/interfaces/ServiceEndpointInterfaces.ts, +// but it isn't exported :(. +interface ServiceConnection { + allPipelines: { + authorized: boolean; + } + id: string; + isReady: boolean; + type: string; + operationStatus: { + state: string; + statusMessage: string; + }; +} - constructor(organizationName: string, projectName: string, connection: azdev.WebApi) { - this.connection = connection; - this.organizationName = organizationName; - this.projectName = projectName; +export class ServiceConnectionClient { + constructor(private connection: azdev.WebApi, private project: string) { } - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - const url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; + public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { + const url = `${this.connection.serverUrl}/${this.project}/_apis/serviceendpoint/endpoints`; - return this.connection.rest.create(url, { + const response = await this.connection.rest.create(url, { "administratorsGroup": null, "authorization": { "parameters": { @@ -37,12 +44,18 @@ export class ServiceConnectionClient { "Content-Type": "application/json", }, }); + + if (response.result) { + return response.result; + } else { + throw new Error(`Failed to create GitHub service connection: ${response.statusCode}`); + } } - public async createAzureServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - const url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; + public async createAzureServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { + const url = `${this.connection.serverUrl}/${this.project}/_apis/serviceendpoint/endpoints`; - return this.connection.rest.create(url, { + const response = await this.connection.rest.create(url, { "administratorsGroup": null, "authorization": { "parameters": { @@ -72,23 +85,36 @@ export class ServiceConnectionClient { "Content-Type": "application/json", }, }); + + if (response.result) { + return response.result; + } else { + throw new Error(`Failed to create Azure service connection: ${response.statusCode}`); + } } - public async getEndpointStatus(endpointId: string): Promise { - const url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; + public async getEndpointStatus(endpointId: string): Promise { + const url = `${this.connection.serverUrl}/${this.project}/_apis/serviceendpoint/endpoints/${endpointId}`; - return this.connection.rest.get(url, { + const response = await this.connection.rest.get(url, { acceptHeader: "application/json;api-version=5.1-preview.2;excludeUrls=true", additionalHeaders: { "Content-Type": "application/json", }, }); + + if (response.result) { + return response.result; + } else { + throw new Error(`Failed to get service connection status: ${response.statusCode}`); + } } - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - const url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; + // TODO: Authorize individual pipelines instead of all pipelines. + public async authorizeEndpointForAllPipelines(endpointId: string): Promise { + const url = `${this.connection.serverUrl}/${this.project}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - return this.connection.rest.update(url, { + const response = await this.connection.rest.update(url, { "allPipelines": { "authorized": true, "authorizedBy": null, @@ -105,5 +131,11 @@ export class ServiceConnectionClient { "Content-Type": "application/json", }, }); + + if (response.result) { + return response.result; + } else { + throw new Error(`Failed to authorize service connection: ${response.statusCode}`); + } } } diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts index 1e845101..d1f12701 100644 --- a/src/configure/clients/restClient.ts +++ b/src/configure/clients/restClient.ts @@ -1,10 +1,6 @@ -import { ServiceClient, ServiceClientCredentials, ServiceClientOptions, RequestPrepareOptions } from "@azure/ms-rest-js"; +import { ServiceClient, RequestPrepareOptions } from "@azure/ms-rest-js"; export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - public sendRequest(options: RequestPrepareOptions): Promise { return new Promise((resolve, reject) => { super.sendRequest(options) @@ -12,7 +8,7 @@ export class RestClient extends ServiceClient { if (response.status >= 300) { reject(response.parsedBody); } - resolve(response.parsedBody); + resolve(response.parsedBody as TResult); }) .catch(error => { reject(error); diff --git a/src/configure/configure.ts b/src/configure/configure.ts index f92b09e2..2ecd956d 100644 --- a/src/configure/configure.ts +++ b/src/configure/configure.ts @@ -1,15 +1,15 @@ import { v4 as uuid } from 'uuid'; import { AppServiceClient } from './clients/azure/appServiceClient'; import { OrganizationsClient } from './clients/devOps/organizationsClient'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { Messages } from '../messages'; +import * as AzureDevOpsHelper from './helper/devOps/azureDevOpsHelper'; +import * as Messages from '../messages'; import { ServiceConnectionHelper } from './helper/devOps/serviceConnectionHelper'; import { SourceOptions, RepositoryProvider, QuickPickItemWithData, GitRepositoryDetails, PipelineTemplate, AzureDevOpsDetails, ValidatedBuild, ValidatedProject, WebAppKind, TargetResourceType, ValidatedSite } from './model/models'; import * as constants from './resources/constants'; -import { TracePoints } from './resources/tracePoints'; +import * as TracePoints from './resources/tracePoints'; import { getAzureAccountExtensionApi, getGitExtensionApi } from '../extensionApis'; import { telemetryHelper } from '../helpers/telemetryHelper'; -import { TelemetryKeys } from '../helpers/telemetryKeys'; +import * as TelemetryKeys from '../helpers/telemetryKeys'; import * as utils from 'util'; import * as vscode from 'vscode'; import { URI, Utils } from 'vscode-uri'; @@ -23,7 +23,7 @@ import { AzureSiteDetails } from './model/models'; import { GraphHelper } from './helper/graphHelper'; import { TeamProject } from 'azure-devops-node-api/interfaces/CoreInterfaces'; import { WebApi, getBearerHandler } from 'azure-devops-node-api'; -import { GitHubProvider } from './helper/gitHubHelper'; +import * as GitHubHelper from './helper/gitHubHelper'; import { WebSiteManagementModels } from '@azure/arm-appservice'; const Layer: string = 'configure'; @@ -37,7 +37,7 @@ export async function configurePipeline(): Promise { if (signIn?.toLowerCase() === Messages.signInLabel.toLowerCase()) { await vscode.commands.executeCommand("azure-account.login"); } else { - vscode.window.showWarningMessage(Messages.azureLoginRequired); + void vscode.window.showWarningMessage(Messages.azureLoginRequired); return; } } @@ -50,7 +50,7 @@ export async function configurePipeline(): Promise { const repo = gitExtension.getRepository(workspaceUri); if (repo === null) { - vscode.window.showWarningMessage(Messages.notAGitRepository); + void vscode.window.showWarningMessage(Messages.notAGitRepository); return; } @@ -138,10 +138,7 @@ class PipelineConfigurer { } telemetryHelper.setCurrentStep('CreatePreRequisites'); - const serviceConnectionHelper = new ServiceConnectionHelper( - adoDetails.organizationName, - adoDetails.project.name, - adoDetails.adoClient); + const serviceConnectionHelper = new ServiceConnectionHelper(adoDetails.adoClient, adoDetails.project.name); let repositoryProperties: Record | undefined; if (repoDetails.repositoryProvider === RepositoryProvider.Github) { @@ -213,11 +210,13 @@ class PipelineConfigurer { } telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) + void vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) .then(action => { - if (action?.toLowerCase() === Messages.browsePipeline.toLowerCase()) { + if (action === Messages.browsePipeline) { telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(URI.parse(queuedPipeline._links.web.href)); + // _links is weakly typed and it's not worth the effort to verify. + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access + void vscode.env.openExternal(URI.parse(queuedPipeline._links.web.href)); } }); } @@ -225,13 +224,14 @@ class PipelineConfigurer { private async getGitDetailsFromRepository(): Promise { const { HEAD } = this.repo.state; if (!HEAD) { - vscode.window.showWarningMessage(Messages.branchHeadMissing); + void vscode.window.showWarningMessage(Messages.branchHeadMissing); return undefined; } - let { name, remote } = HEAD; + const { name } = HEAD; + let { remote } = HEAD; if (!name) { - vscode.window.showWarningMessage(Messages.branchNameMissing); + void vscode.window.showWarningMessage(Messages.branchNameMissing); return undefined; } @@ -239,7 +239,7 @@ class PipelineConfigurer { // Remote tracking branch is not set, see if we have any remotes we can use. const remotes = this.repo.state.remotes; if (remotes.length === 0) { - vscode.window.showWarningMessage(Messages.branchRemoteMissing); + void vscode.window.showWarningMessage(Messages.branchRemoteMissing); return undefined; } else if (remotes.length === 1) { remote = remotes[0].name; @@ -276,9 +276,9 @@ class PipelineConfigurer { remoteUrl, branch: name, }; - } else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - const { ownerName, repositoryName } = GitHubProvider.getRepositoryDetailsFromRemoteUrl(remoteUrl); + } else if (GitHubHelper.isGitHubUrl(remoteUrl)) { + remoteUrl = GitHubHelper.getFormattedRemoteUrl(remoteUrl); + const { ownerName, repositoryName } = GitHubHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); repoDetails = { repositoryProvider: RepositoryProvider.Github, ownerName, @@ -288,11 +288,11 @@ class PipelineConfigurer { branch: name, }; } else { - vscode.window.showWarningMessage(Messages.cannotIdentifyRepositoryDetails); + void vscode.window.showWarningMessage(Messages.cannotIdentifyRepositoryDetails); return undefined; } } else { - vscode.window.showWarningMessage(Messages.remoteRepositoryNotConfigured); + void vscode.window.showWarningMessage(Messages.remoteRepositoryNotConfigured); return undefined; } @@ -332,7 +332,7 @@ class PipelineConfigurer { const adoClient = await this.getAzureDevOpsClient(repoDetails.organizationName, session); const coreApi = await adoClient.getCoreApi(); const project = await coreApi.getProject(repoDetails.projectName); - if (this.isValidProject(project)) { + if (isValidProject(project)) { return { session, adoClient, @@ -343,39 +343,34 @@ class PipelineConfigurer { } } - vscode.window.showWarningMessage("You are not signed in to the Azure DevOps organization that contains this repository."); + void vscode.window.showWarningMessage("You are not signed in to the Azure DevOps organization that contains this repository."); return undefined; } else { // Lazily construct list of organizations so that we can immediately show the quick pick, // then fill in the choices as they come in. - const organizationAndSessionsPromise = new Promise< - QuickPickItemWithData[] - >(async resolve => { - const organizationAndSessions: QuickPickItemWithData[] = []; - - for (const session of this.azureAccount.filters.map(({ session }) => session)) { - const organizationsClient = new OrganizationsClient(session.credentials2); - const organizations = await organizationsClient.listOrganizations(); - organizationAndSessions.push(...organizations.map(organization => ({ - label: organization.accountName, - data: session, - }))); - } - - organizationAndSessions.push({ - // This is safe because ADO orgs can't have spaces in them. - label: "Create new Azure DevOps organization...", - data: undefined, - }); - - resolve(organizationAndSessions); - }); + const getOrganizationsAndSessions = async (): Promise[]> => { + return [ + ...(await Promise.all(this.azureAccount.filters.map(async ({ session }) => { + const organizationsClient = new OrganizationsClient(session.credentials2); + const organizations = await organizationsClient.listOrganizations(); + return organizations.map(organization => ({ + label: organization.accountName, + data: session, + })); + }))).flat(), + { + // This is safe because ADO orgs can't have spaces in them. + label: "Create new Azure DevOps organization...", + data: undefined, + } + ]; + }; const result = await showQuickPick( 'organization', - organizationAndSessionsPromise, { + getOrganizationsAndSessions(), { placeHolder: "Select the Azure DevOps organization to create this pipeline in", - }); + }, TelemetryKeys.OrganizationListCount); if (result === undefined) { return undefined; } @@ -390,29 +385,24 @@ class PipelineConfigurer { const adoClient = await this.getAzureDevOpsClient(organizationName, session); // Ditto for the projects. - const projectsPromise = new Promise< - QuickPickItemWithData[] - >(async resolve => { - const validatedProjects: QuickPickItemWithData[] = []; - + const getProjects = async (): Promise[]> => { const coreApi = await adoClient.getCoreApi(); const projects = await coreApi.getProjects(); - validatedProjects.push(...projects - .filter(this.isValidProject) - .map(project => { return { label: project.name, data: project }; })); - - validatedProjects.push({ - // This is safe because ADO projects can't end with periods. - label: "Create new project...", - data: undefined, - }); - - resolve(validatedProjects); - }); + return [ + ...projects + .filter(isValidProject) + .map(project => { return { label: project.name, data: project }; }), + { + // This is safe because ADO projects can't end with periods. + label: "Create new project...", + data: undefined, + } + ]; + }; const selectedProject = await showQuickPick( constants.SelectProject, - projectsPromise, + getProjects(), { placeHolder: Messages.selectProject }, TelemetryKeys.ProjectListCount); if (selectedProject === undefined) { @@ -463,22 +453,18 @@ class PipelineConfigurer { const { subscriptionId } = selectedSubscription.data.subscription; if (subscriptionId === undefined) { - vscode.window.showErrorMessage("Unable to get ID for subscription, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); + void vscode.window.showErrorMessage("Unable to get ID for subscription, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); return undefined; } // show available resources and get the chosen one - const appServiceClient = new AppServiceClient( - session.credentials2, - session.tenantId, - session.environment.portalUrl, - subscriptionId); + const appServiceClient = new AppServiceClient(session.credentials2, subscriptionId); // TODO: Refactor kind so we don't need three kind.includes const sites = await appServiceClient.getAppServices(kind); const items: QuickPickItemWithData[] = sites - .filter(this.isValidSite) + .filter(isValidSite) .map(site => { return { label: site.name, data: site }; }); const appType = kind.includes("functionapp") ? "Function App" : "Web App"; @@ -632,14 +618,14 @@ class PipelineConfigurer { const commit = this.repo.state.HEAD?.commit; if (commit === undefined) { - vscode.window.showErrorMessage("Unable to get commit after pushing pipeline, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); + void vscode.window.showErrorMessage("Unable to get commit after pushing pipeline, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); return undefined; } return commit; } catch (error) { telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error as Error); - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( utils.format(Messages.commitFailedErrorMessage, (error as Error).message)); return undefined; } @@ -673,7 +659,7 @@ class PipelineConfigurer { [constants.HostedVS2017QueueName], adoDetails.project.name); if (queues.length === 0) { - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( utils.format(Messages.noAgentQueueFound, constants.HostedVS2017QueueName)); return undefined; } @@ -696,7 +682,7 @@ class PipelineConfigurer { sourceVersion: commit }, adoDetails.project.name); - if (!this.isValidBuild(build)) { + if (!isValidBuild(build)) { return undefined; } @@ -714,50 +700,55 @@ class PipelineConfigurer { adoDetails: AzureDevOpsDetails, azureSiteDetails: AzureSiteDetails, ): Promise { - try { - // update SCM type - azureSiteDetails.appServiceClient.updateScmType(azureSiteDetails.site); - - const buildDefinitionUrl = AzureDevOpsHelper.getOldFormatBuildDefinitionUrl( - adoDetails.organizationName, - adoDetails.project.id, - queuedPipeline.definition.id); - const buildUrl = AzureDevOpsHelper.getOldFormatBuildUrl( - adoDetails.organizationName, - adoDetails.project.id, - queuedPipeline.id); - - const locationsApi = await adoDetails.adoClient.getLocationsApi(); - const { instanceId } = await locationsApi.getConnectionData(); - if (instanceId === undefined) { - vscode.window.showErrorMessage("Unable to determine the organization ID, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); - return; - } + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: Messages.runningPostDeploymentActions + }, async () => { + try { + // update SCM type + await azureSiteDetails.appServiceClient.updateScmType(azureSiteDetails.site); + + const buildDefinitionUrl = AzureDevOpsHelper.getOldFormatBuildDefinitionUrl( + adoDetails.organizationName, + adoDetails.project.id, + queuedPipeline.definition.id); + const buildUrl = AzureDevOpsHelper.getOldFormatBuildUrl( + adoDetails.organizationName, + adoDetails.project.id, + queuedPipeline.id); + + const locationsApi = await adoDetails.adoClient.getLocationsApi(); + const { instanceId } = await locationsApi.getConnectionData(); + if (instanceId === undefined) { + void vscode.window.showErrorMessage("Unable to determine the organization ID, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); + return; + } - // update metadata of app service to store information about the pipeline deploying to web app. - const metadata = await azureSiteDetails.appServiceClient.getAppServiceMetadata(azureSiteDetails.site); - metadata.properties = { - ...metadata.properties, - VSTSRM_ProjectId: adoDetails.project.id, - VSTSRM_AccountId: instanceId, - VSTSRM_BuildDefinitionId: queuedPipeline.definition.id.toString(), - VSTSRM_BuildDefinitionWebAccessUrl: buildDefinitionUrl, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_ReleaseDefinitionId: '', - }; + // update metadata of app service to store information about the pipeline deploying to web app. + const metadata = await azureSiteDetails.appServiceClient.getAppServiceMetadata(azureSiteDetails.site); + metadata.properties = { + ...metadata.properties, + VSTSRM_ProjectId: adoDetails.project.id, + VSTSRM_AccountId: instanceId, + VSTSRM_BuildDefinitionId: queuedPipeline.definition.id.toString(), + VSTSRM_BuildDefinitionWebAccessUrl: buildDefinitionUrl, + VSTSRM_ConfiguredCDEndPoint: '', + VSTSRM_ReleaseDefinitionId: '', + }; - azureSiteDetails.appServiceClient.updateAppServiceMetadata(azureSiteDetails.site, metadata); + await azureSiteDetails.appServiceClient.updateAppServiceMetadata(azureSiteDetails.site, metadata); - // send a deployment log with information about the setup pipeline and links. - azureSiteDetails.appServiceClient.publishDeploymentToAppService( - azureSiteDetails.site, - buildDefinitionUrl, - buildDefinitionUrl, - buildUrl); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error as Error); - throw error; - } + // send a deployment log with information about the setup pipeline and links. + await azureSiteDetails.appServiceClient.publishDeploymentToAppService( + azureSiteDetails.site, + buildDefinitionUrl, + buildDefinitionUrl, + buildUrl); + } catch (error) { + telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error as Error); + throw error; + } + }); } private async getAzureDevOpsClient(organization: string, session: AzureSession): Promise { @@ -770,31 +761,31 @@ class PipelineConfigurer { this.azureDevOpsClient = new WebApi(`https://dev.azure.com/${organization}`, authHandler); return this.azureDevOpsClient; } +} - private isValidProject(project: TeamProject): project is ValidatedProject { - if (project.name === undefined || project.id === undefined) { - vscode.window.showErrorMessage("Unable to get name or ID for project, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); - return false; - } - - return true; +function isValidProject(project: TeamProject): project is ValidatedProject { + if (project.name === undefined || project.id === undefined) { + void vscode.window.showErrorMessage("Unable to get name or ID for project, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); + return false; } - private isValidSite(resource: WebSiteManagementModels.Site): resource is ValidatedSite { - if (resource.name === undefined || resource.id === undefined) { - vscode.window.showErrorMessage("Unable to get name or ID for resource, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); - return false; - } + return true; +} - return true; +function isValidSite(resource: WebSiteManagementModels.Site): resource is ValidatedSite { + if (resource.name === undefined || resource.id === undefined) { + void vscode.window.showErrorMessage("Unable to get name or ID for resource, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); + return false; } - private isValidBuild(build: Build): build is ValidatedBuild { - if (build.definition === undefined || build.definition.id === undefined || build.id === undefined) { - vscode.window.showErrorMessage("Unable to get definition or ID for build, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); - return false; - } + return true; +} - return true; +function isValidBuild(build: Build): build is ValidatedBuild { + if (build.definition === undefined || build.definition.id === undefined || build.id === undefined) { + void vscode.window.showErrorMessage("Unable to get definition or ID for build, please file a bug at https://github.com/microsoft/azure-pipelines-vscode/issues/new"); + return false; } + + return true; } diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts index a3fd4d6f..c350b5a8 100644 --- a/src/configure/helper/commonHelper.ts +++ b/src/configure/helper/commonHelper.ts @@ -1,7 +1,7 @@ import * as vscode from 'vscode'; import { URI } from 'vscode-uri'; import * as util from 'util'; -import { Messages } from '../../messages'; +import * as Messages from '../../messages'; import * as logger from '../../logger'; export async function sleepForMilliSeconds(timeInMs: number): Promise { @@ -13,12 +13,12 @@ export async function sleepForMilliSeconds(timeInMs: number): Promise { } export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); + const characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; + const charTypeSize = [26, 26, 10, 10]; + const charTypeStartIndex = [0, 26, 52, 62]; + let password = ""; + for (let x = 0; x < length; x++) { + const i = Math.floor(Math.random() * charTypeSize[x % 4]); password += characters.charAt(i + charTypeStartIndex[x % 4]); } return password; @@ -40,7 +40,9 @@ export async function executeFunctionWithRetry( } } - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))): util.format (Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); + throw new Error(errorMessage ? + errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : + util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))); } export async function getAvailableFileName(fileName: string, repoPath: URI): Promise { diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts index af2f3dc0..9b13eb7f 100644 --- a/src/configure/helper/controlProvider.ts +++ b/src/configure/helper/controlProvider.ts @@ -1,7 +1,6 @@ import { InputBoxOptions, QuickPickItem, QuickPickOptions, window } from 'vscode'; import { telemetryHelper } from '../../helpers/telemetryHelper'; -import { TelemetryKeys } from '../../helpers/telemetryKeys'; -import { UserCancelledError } from './userCancelledError'; +import * as TelemetryKeys from '../../helpers/telemetryKeys'; export async function showQuickPick(listName: string, listItems: T[] | Thenable, options: QuickPickOptions, itemCountTelemetryKey?: string): Promise { try { @@ -25,19 +24,3 @@ export async function showInputBox(inputName: string, options: InputBoxOptions): ...options }); } - -export async function showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(); - } - - return result; - } - else { - return window.showInformationMessage(informationMessage, ...actions); - } - -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts index 9a272b68..46e336b5 100644 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ b/src/configure/helper/devOps/azureDevOpsHelper.ts @@ -2,141 +2,139 @@ import { BuildDefinition, ContinuousIntegrationTrigger, DefinitionQuality, Defin import { TaskAgentQueue } from 'azure-devops-node-api/interfaces/TaskAgentInterfaces'; import { RepositoryProvider, GitRepositoryDetails, AzureDevOpsDetails } from '../../model/models'; -import { Messages } from '../../../messages'; +import * as Messages from '../../../messages'; -export class AzureDevOpsHelper { - // https://dev.azure.com/ OR https://org@dev.azure.com/ - private static AzureReposUrl = 'dev.azure.com/'; +// https://dev.azure.com/ OR https://org@dev.azure.com/ +const AzureReposUrl = 'dev.azure.com/'; - // git@ssh.dev.azure.com:v3/ - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; +// git@ssh.dev.azure.com:v3/ +const SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - // https://org.visualstudio.com/ - private static VSOUrl = '.visualstudio.com/'; +// https://org.visualstudio.com/ +const VSOUrl = '.visualstudio.com/'; - // org@vs-ssh.visualstudio.com:v3/ - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; +// org@vs-ssh.visualstudio.com:v3/ +const SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - public static isAzureReposUrl(remoteUrl: string): boolean { - return remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || - remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || - remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || - remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0; +export function isAzureReposUrl(remoteUrl: string): boolean { + return remoteUrl.includes(AzureReposUrl) || + remoteUrl.includes(VSOUrl) || + remoteUrl.includes(SSHAzureReposUrl) || + remoteUrl.includes(SSHVsoReposUrl); +} + +// TODO: Use ADO instead. +export function getFormattedRemoteUrl(remoteUrl: string): string { + // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL + if (remoteUrl.includes(SSHAzureReposUrl) || remoteUrl.includes(SSHVsoReposUrl)) { + const details = getRepositoryDetailsFromRemoteUrl(remoteUrl); + return `https://${details.organizationName}${VSOUrl}${details.projectName}/_git/${details.repositoryName}`; } - // TODO: Use ADO instead. - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - const details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}${details.projectName}/_git/${details.repositoryName}`; + return remoteUrl; +} + +export function getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { + if (remoteUrl.includes(AzureReposUrl)) { + const part = remoteUrl.substring(remoteUrl.indexOf(AzureReposUrl) + AzureReposUrl.length); + const parts = part.split('/'); + if (parts.length !== 4) { + throw new Error(Messages.failedToDetermineAzureRepoDetails); } - return remoteUrl; - } + return { + organizationName: parts[0].trim(), + projectName: parts[1].trim(), + repositoryName: parts[3].trim() + }; + } else if (remoteUrl.includes(VSOUrl)) { + const part = remoteUrl.substring(remoteUrl.indexOf(VSOUrl) + VSOUrl.length); + const organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); + const parts = part.split('/'); + + if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { + // Handle scenario where part is 'DefaultCollection//_git/' + parts.shift(); + } - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - const part = remoteUrl.substring(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - const parts = part.split('/'); - if (parts.length !== 4) { - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - - return { - organizationName: parts[0].trim(), - projectName: parts[1].trim(), - repositoryName: parts[3].trim() - }; - } else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - const part = remoteUrl.substring(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - const organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - const parts = part.split('/'); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts.shift(); - } - - if (parts.length !== 3) { - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - - return { - organizationName: organizationName, - projectName: parts[0].trim(), - repositoryName: parts[2].trim() - }; - } else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - const urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - const part = remoteUrl.substring(remoteUrl.indexOf(urlFormat) + urlFormat.length); - const parts = part.split('/'); - if (parts.length !== 3) { - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - - return { - organizationName: parts[0].trim(), - projectName: parts[1].trim(), - repositoryName: parts[2].trim() - }; - } else { - throw new Error(Messages.notAzureRepoUrl); + if (parts.length !== 3) { + throw new Error(Messages.failedToDetermineAzureRepoDetails); } - } - public static getBuildDefinitionPayload( - pipelineName: string, - queue: TaskAgentQueue, - repoDetails: GitRepositoryDetails, - adoDetails: AzureDevOpsDetails, - repositoryProperties: Record | undefined, - pipelineFileName: string, - ): BuildDefinition { return { - name: pipelineName, - type: DefinitionType.Build, - quality: DefinitionQuality.Definition, - path: "\\", //Folder path of build definition. Root folder in this case - project: adoDetails.project, - process: { - type: 2, - yamlFileName: pipelineFileName, - } as YamlProcess, - queue: { - id: queue.id, - }, - triggers: [ - { - triggerType: DefinitionTriggerType.ContinuousIntegration, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false, - } as ContinuousIntegrationTrigger, - ], - repository: { - id: repoDetails.repositoryProvider === RepositoryProvider.Github - ? `${repoDetails.ownerName}/${repoDetails.repositoryName}` - : undefined, - name: repoDetails.repositoryProvider === RepositoryProvider.Github - ? `${repoDetails.ownerName}/${repoDetails.repositoryName}` - : repoDetails.repositoryName, - type: repoDetails.repositoryProvider, - defaultBranch: repoDetails.branch, - url: repoDetails.remoteUrl, - properties: repositoryProperties, - }, - properties: { - source: 'ms-azure-devops.azure-pipelines', - }, + organizationName: organizationName, + projectName: parts[0].trim(), + repositoryName: parts[2].trim() }; - } + } else if (remoteUrl.includes(SSHAzureReposUrl) || remoteUrl.includes(SSHVsoReposUrl)) { + const urlFormat = remoteUrl.includes(SSHAzureReposUrl) ? SSHAzureReposUrl : SSHVsoReposUrl; + const part = remoteUrl.substring(remoteUrl.indexOf(urlFormat) + urlFormat.length); + const parts = part.split('/'); + if (parts.length !== 3) { + throw new Error(Messages.failedToDetermineAzureRepoDetails); + } - // TODO: These should be able to be changed to use ADO instead. - public static getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; + return { + organizationName: parts[0].trim(), + projectName: parts[1].trim(), + repositoryName: parts[2].trim() + }; + } else { + throw new Error(Messages.notAzureRepoUrl); } +} - public static getOldFormatBuildUrl(accountName: string, projectName: string, buildId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } +export function getBuildDefinitionPayload( + pipelineName: string, + queue: TaskAgentQueue, + repoDetails: GitRepositoryDetails, + adoDetails: AzureDevOpsDetails, + repositoryProperties: Record | undefined, + pipelineFileName: string, +): BuildDefinition { + return { + name: pipelineName, + type: DefinitionType.Build, + quality: DefinitionQuality.Definition, + path: "\\", //Folder path of build definition. Root folder in this case + project: adoDetails.project, + process: { + type: 2, + yamlFileName: pipelineFileName, + } as YamlProcess, + queue: { + id: queue.id, + }, + triggers: [ + { + triggerType: DefinitionTriggerType.ContinuousIntegration, // Continuous integration trigger type + settingsSourceType: 2, // Use trigger source as specified in YAML + batchChanges: false, + } as ContinuousIntegrationTrigger, + ], + repository: { + id: repoDetails.repositoryProvider === RepositoryProvider.Github + ? `${repoDetails.ownerName}/${repoDetails.repositoryName}` + : undefined, + name: repoDetails.repositoryProvider === RepositoryProvider.Github + ? `${repoDetails.ownerName}/${repoDetails.repositoryName}` + : repoDetails.repositoryName, + type: repoDetails.repositoryProvider, + defaultBranch: repoDetails.branch, + url: repoDetails.remoteUrl, + properties: repositoryProperties, + }, + properties: { + source: 'ms-azure-devops.azure-pipelines', + }, + }; +} + +// TODO: These should be able to be changed to use ADO instead. +export function getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { + return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; +} + +export function getOldFormatBuildUrl(accountName: string, projectName: string, buildId: number) { + return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; } diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts index abbc52d3..244076b0 100644 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ b/src/configure/helper/devOps/serviceConnectionHelper.ts @@ -4,21 +4,21 @@ import * as util from 'util'; import { sleepForMilliSeconds } from '../commonHelper'; import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; import { AadApplication } from '../../model/models'; -import { Messages } from '../../../messages'; +import * as Messages from '../../../messages'; export class ServiceConnectionHelper { private serviceConnectionClient: ServiceConnectionClient; - public constructor(organizationName: string, projectName: string, connection: azdev.WebApi) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, connection); + public constructor(connection: azdev.WebApi, project: string) { + this.serviceConnectionClient = new ServiceConnectionClient(connection, project); } public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - const response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - const endpointId: string = response.result.id; + const connection = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); + const endpointId = connection.id; await this.waitForEndpointToBeReady(endpointId); const authorizationResponse = await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId); - if (authorizationResponse.result.allPipelines.authorized !== true) { + if (!authorizationResponse.allPipelines.authorized) { throw new Error(Messages.couldNotAuthorizeEndpoint); } @@ -26,11 +26,11 @@ export class ServiceConnectionHelper { } public async createAzureServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - const response = await this.serviceConnectionClient.createAzureServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - const endpointId: string = response.result.id; + const connection = await this.serviceConnectionClient.createAzureServiceConnection(name, tenantId, subscriptionId, scope, aadApp); + const endpointId: string = connection.id; await this.waitForEndpointToBeReady(endpointId); const authorizationResponse = await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId); - if (authorizationResponse.result.allPipelines.authorized !== true) { + if (!authorizationResponse.allPipelines.authorized) { throw new Error(Messages.couldNotAuthorizeEndpoint); } @@ -39,15 +39,15 @@ export class ServiceConnectionHelper { private async waitForEndpointToBeReady(endpointId: string): Promise { for (let attempt = 0; attempt < 30; attempt++) { - const response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - const operationStatus = response.result.operationStatus; + const connection = await this.serviceConnectionClient.getEndpointStatus(endpointId); - if (response.result.isReady) { + if (connection.isReady) { return; } - if (operationStatus?.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateServiceConnection, response.result.type, operationStatus.state, operationStatus.statusMessage)); + const { operationStatus } = connection; + if (operationStatus.state.toLowerCase() === "failed") { + throw Error(util.format(Messages.unableToCreateServiceConnection, connection.type, operationStatus.state, operationStatus.statusMessage)); } await sleepForMilliSeconds(2000); diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts index 11e33cf7..9e99e0f5 100644 --- a/src/configure/helper/gitHubHelper.ts +++ b/src/configure/helper/gitHubHelper.ts @@ -1,35 +1,33 @@ -export class GitHubProvider { - // Note that this is not intended to be be completely accurate. - // This is the canonical URL that GitHub provides when cloning, - // and the only one that we'll support to keep the code simple. - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; +// Note that this is not intended to be be completely accurate. +// This is the canonical URL that GitHub provides when cloning, +// and the only one that we'll support to keep the code simple. +const GitHubUrl = 'https://github.com/'; +const SSHGitHubUrl = 'git@github.com:'; - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { ownerName: string, repositoryName: string } { - // https://github.com/microsoft/azure-pipelines-vscode.git - // => ['https:', '', 'github.com', 'microsoft', 'azure-pipelines-vscode.git'] - // => { ownerName: 'microsoft', repositoryName: 'azure-pipelines-vscode'} - // =============================================== - // git@github.com:microsoft/azure-pipelines-vscode - // => microsoft/zure-pipelines-vscode - // => ['microsoft', 'azure-pipelines-vscode'] - // => { ownerName: 'microsoft', repositoryName: 'azure-pipelines-vscode'} - const parts = remoteUrl.replace(GitHubProvider.SSHGitHubUrl, '').split('/'); - return { - ownerName: parts[parts.length - 2], - repositoryName: parts[parts.length - 1].replace(/\.git$/, '') - }; - } +export function isGitHubUrl(remoteUrl: string): boolean { + return remoteUrl.startsWith(GitHubUrl) || remoteUrl.startsWith(SSHGitHubUrl); +} - public static getFormattedRemoteUrl(remoteUrl: string): string { - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } +export function getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { ownerName: string, repositoryName: string } { + // https://github.com/microsoft/azure-pipelines-vscode.git + // => ['https:', '', 'github.com', 'microsoft', 'azure-pipelines-vscode.git'] + // => { ownerName: 'microsoft', repositoryName: 'azure-pipelines-vscode'} + // =============================================== + // git@github.com:microsoft/azure-pipelines-vscode + // => microsoft/zure-pipelines-vscode + // => ['microsoft', 'azure-pipelines-vscode'] + // => { ownerName: 'microsoft', repositoryName: 'azure-pipelines-vscode'} + const parts = remoteUrl.replace(SSHGitHubUrl, '').split('/'); + return { + ownerName: parts[parts.length - 2], + repositoryName: parts[parts.length - 1].replace(/\.git$/, '') + }; +} - return remoteUrl; +export function getFormattedRemoteUrl(remoteUrl: string): string { + if (remoteUrl.startsWith(SSHGitHubUrl)) { + return `https://github.com/${remoteUrl.substring(SSHGitHubUrl.length)}`; } + + return remoteUrl; } diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts index 08fc426f..79bb07d8 100644 --- a/src/configure/helper/graphHelper.ts +++ b/src/configure/helper/graphHelper.ts @@ -1,7 +1,7 @@ import { v4 as uuid } from 'uuid'; import { AadApplication } from '../model/models'; import { generateRandomPassword, executeFunctionWithRetry } from './commonHelper'; -import { Messages } from '../../messages'; +import * as Messages from '../../messages'; import { RestClient } from '../clients/restClient'; import { TokenCredentials } from '@azure/ms-rest-js'; import { TokenCredentialsBase } from '@azure/ms-rest-nodeauth'; @@ -12,6 +12,8 @@ import { AzureSession } from '../../typings/azure-account.api'; // client.api("/applications").post() // client.api("/servicePrincipals").post() // new AuthorizationManagementClient().roleAssignments.create() +// Disable ESLint rules because there won't be any investment into this file; see above. +/* eslint-disable */ export class GraphHelper { private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; @@ -100,8 +102,8 @@ export class GraphHelper { } private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); + const secret = generateRandomPassword(20); + const startDate = new Date(Date.now()); return graphClient.sendRequest({ url: `https://graph.windows.net/${tenantId}/applications`, @@ -131,7 +133,7 @@ export class GraphHelper { } private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { + const createSpnPromise = () => { return graphClient.sendRequest({ url: `https://graph.windows.net/${tenantId}/servicePrincipals`, queryParameters: { @@ -153,19 +155,17 @@ export class GraphHelper { } private static async createRoleAssignment(credentials: TokenCredentialsBase, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let createRoleAssignmentPromise = () => { + const restClient = new RestClient(credentials); + const createRoleAssignmentPromise = () => { return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, + url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${uuid()}`, queryParameters: { "api-version": "2021-04-01-preview" // So we have access to the "principalType" property }, method: "PUT", body: { "properties": { - "roleDefinitionId": roleDefinitionId, + "roleDefinitionId": `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`, "principalId": objectId, "principalType": "ServicePrincipal", // Makes the assignment work for newly-created service principals } diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts index d73b5ab0..0eb39011 100644 --- a/src/configure/helper/templateHelper.ts +++ b/src/configure/helper/templateHelper.ts @@ -8,8 +8,7 @@ import { URI } from 'vscode-uri'; export async function analyzeRepoAndListAppropriatePipeline(repoUri: URI): Promise { // TO-DO: To populate the possible templates on the basis of azure target resource. let templateList = simpleWebAppTemplates; - let analysisResult = await analyzeRepo(repoUri); - + const analysisResult = await analyzeRepo(repoUri); if (analysisResult.isNodeApplication) { // add all node application templates @@ -24,7 +23,7 @@ export async function analyzeRepoAndListAppropriatePipeline(repoUri: URI): Promi templateList = functionTemplates.concat(templateList); } - if(analysisResult.isDotnetApplication) { + if (analysisResult.isDotnetApplication) { templateList = dotnetTemplates.concat(templateList); } @@ -67,31 +66,20 @@ async function analyzeRepo(repoUri: URI): Promise<{ isNodeApplication: boolean, } function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); + const nodeFilesRegex = /\.ts$|\.js$|package\.json$|node_modules/; + return files.some((file) => nodeFilesRegex.test(file.toLowerCase())); } function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); + return files.some((file) => file.toLowerCase().endsWith("host.json")); } function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }) + return files.some((file) => path.extname(file).toLowerCase() === '.py'); } function isDotnetApplication(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }) + return files.some((file) => ['.sln', '.csproj', '.fsproj'].includes(path.extname(file).toLowerCase())); } const nodeTemplates: Array = [ diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts index ccbfab6a..7e92a816 100644 --- a/src/configure/model/models.ts +++ b/src/configure/model/models.ts @@ -10,7 +10,7 @@ export interface Organization { accountId: string; accountName: string; accountUri: string; - properties: {}; + properties: Record; } /** diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts index 835a8bbb..4856cb65 100644 --- a/src/configure/resources/constants.ts +++ b/src/configure/resources/constants.ts @@ -1,147 +1,7 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", - "start", - "status", - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; export const SelectPipelineTemplate = 'selectPipelineTemplate'; export const SelectSubscription = 'selectSubscription'; export const GitHubPat = 'gitHubPat'; export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const DeploymentResourceAlreadyConfigured = 'DeploymentResourceAlreadyConfigured'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts index 6629daa4..177e7d1b 100644 --- a/src/configure/resources/tracePoints.ts +++ b/src/configure/resources/tracePoints.ts @@ -1,15 +1,8 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; -} +// Failure trace points +export const AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; +export const AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; +export const CheckInPipelineFailure = 'checkInPipelineFailure'; +export const CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; +export const GitHubServiceConnectionError = 'gitHubServiceConnectionError'; +export const PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; +export const PostDeploymentActionFailed = 'PostDeploymentActionFailed'; diff --git a/src/extension.ts b/src/extension.ts index 05cf8441..71e1def0 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -34,7 +34,7 @@ export async function activate(context: vscode.ExtensionContext) { await activateYmlContributor(context); if (configurePipelineEnabled) { const { activateConfigurePipeline } = await import('./configure/activate'); - await activateConfigurePipeline(); + activateConfigurePipeline(); } }); @@ -69,7 +69,7 @@ async function activateYmlContributor(context: vscode.ExtensionContext) { }); // TODO: Can we get rid of this since it's set in package.json? - vscode.languages.setLanguageConfiguration(LANGUAGE_IDENTIFIER, { wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/ }); + vscode.languages.setLanguageConfiguration(LANGUAGE_IDENTIFIER, { wordPattern: /("(?:[^\\"]*(?:\\.)?)*"?)|[^\s{}[\],:]+/ }); // Let the server know of any schema changes. context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(async event => { diff --git a/src/extensionApis.ts b/src/extensionApis.ts index a962c972..c4787f12 100644 --- a/src/extensionApis.ts +++ b/src/extensionApis.ts @@ -1,11 +1,11 @@ import * as vscode from 'vscode'; -import { Messages } from './messages'; +import * as Messages from './messages'; import { AzureAccount } from './typings/azure-account.api'; import { API, GitExtension } from './typings/git'; -let azureAccountExtensionApi: AzureAccount; +let azureAccountExtensionApi: AzureAccount | undefined; export async function getAzureAccountExtensionApi(): Promise { - if (azureAccountExtensionApi == null) { + if (azureAccountExtensionApi === undefined) { const azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); if (!azureAccountExtension) { throw new Error(Messages.azureAccountExtensionUnavailable); @@ -21,9 +21,9 @@ export async function getAzureAccountExtensionApi(): Promise { return azureAccountExtensionApi; } -let gitExtensionApi: API; +let gitExtensionApi: API | undefined; export async function getGitExtensionApi(): Promise { - if (gitExtensionApi == null) { + if (gitExtensionApi === undefined) { const gitExtension = vscode.extensions.getExtension("vscode.git"); if (!gitExtension) { throw new Error(Messages.gitExtensionUnavailable); diff --git a/src/helpers/constants.ts b/src/helpers/constants.ts deleted file mode 100644 index 2630397a..00000000 --- a/src/helpers/constants.ts +++ /dev/null @@ -1,28 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -export class Constants { - static ExtensionName: string = 'azure-pipelines'; - static UserAgent: string = 'azure-pipelines-vscode-extension'; -} - -export class CommandNames { - static CommandPrefix: string = Constants.ExtensionName + "."; - - static DisplayCurrentSchemaFile: string = CommandNames.CommandPrefix + 'DisplayCurrentSchemaFile'; - static LoadLatestTaskSchema: string = CommandNames.CommandPrefix + 'LoadLatestTaskSchema'; - static PATUpdated: string = CommandNames.CommandPrefix + "PATUpdated"; - static Signin: string = CommandNames.CommandPrefix + 'Signin'; - static Signout: string = CommandNames.CommandPrefix + 'Signout'; -} - -export class LogEvents { - static SkippingDownloadLatestTasks: string = 'SkippingDownloadLatestTasks'; -} - -export class LogMessages { - static AccountRequiredToDownloadTasks: string = 'Account name is required to download tasks. Please set azure-pipelines.account setting.'; - static PatRequiredToDownloadTasks: string = 'PAT is required to download tasks. Please set using Signin command.'; -} diff --git a/src/helpers/parseError.ts b/src/helpers/parseError.ts index 0c714197..4151715a 100644 --- a/src/helpers/parseError.ts +++ b/src/helpers/parseError.ts @@ -1,6 +1,9 @@ // Copied from https://github.com/microsoft/vscode-azuretools/blob/5999c2ad4423e86f22d2c648027242d8816a50e4/ui/src/parseError.ts // with inline IParsedError interface and no localization +// Disable linting precisely because this file is copied. +/* eslint-disable */ + /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. diff --git a/src/helpers/telemetryHelper.ts b/src/helpers/telemetryHelper.ts index 39df35be..ad29e417 100644 --- a/src/helpers/telemetryHelper.ts +++ b/src/helpers/telemetryHelper.ts @@ -1,25 +1,27 @@ import * as vscode from 'vscode'; import TelemetryReporter from '@vscode/extension-telemetry'; -import { TelemetryKeys } from './telemetryKeys'; +import * as TelemetryKeys from './telemetryKeys'; import * as logger from '../logger'; import { parseError } from './parseError'; import { v4 as uuid } from 'uuid'; const extensionName = 'ms-azure-devops.azure-pipelines'; -const packageJSON = vscode.extensions.getExtension(extensionName)!.packageJSON; // Guaranteed to exist -const extensionVersion = packageJSON.version; -const aiKey = packageJSON.aiKey; +/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */ +const packageJSON = vscode.extensions.getExtension(extensionName)?.packageJSON; // Guaranteed to exist +const extensionVersion: string = packageJSON.version; +const aiKey: string = packageJSON.aiKey; +/* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */ interface TelemetryProperties { [key: string]: string; } enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' + Succeeded = 'Succeeded', + Failed = 'Failed', + Canceled = 'Canceled' } @@ -34,7 +36,7 @@ class TelemetryHelper { private static reporter = new TelemetryReporter(extensionName, extensionVersion, aiKey); public dispose() { - TelemetryHelper.reporter.dispose(); + void TelemetryHelper.reporter.dispose(); } public getJourneyId(): string { @@ -84,7 +86,7 @@ class TelemetryHelper { // supplied through initialize() or setTelemetry(). // If the function errors, the telemetry event will additionally contain metadata about the error that occurred. // https://github.com/microsoft/vscode-azuretools/blob/5999c2ad4423e86f22d2c648027242d8816a50e4/ui/src/callWithTelemetryAndErrorHandling.ts - public async callWithTelemetryAndErrorHandling(command: string, callback: () => Promise): Promise { + public async callWithTelemetryAndErrorHandling(command: string, callback: () => Promise): Promise { try { return await this.executeFunctionWithTimeTelemetry(callback, 'duration'); } catch (error) { @@ -99,13 +101,13 @@ class TelemetryHelper { logger.log(parsedError.message); if (parsedError.message.includes('\n')) { - vscode.window.showErrorMessage('An error has occurred. Check the output window for more details.'); + void vscode.window.showErrorMessage('An error has occurred. Check the output window for more details.'); } else { - vscode.window.showErrorMessage(parsedError.message); + void vscode.window.showErrorMessage(parsedError.message); } } } finally { - if (this.properties.result === Result.Failed) { + if (this.properties.result === Result.Failed.toString()) { TelemetryHelper.reporter.sendTelemetryErrorEvent( command, { ...this.properties, @@ -119,6 +121,8 @@ class TelemetryHelper { }); } } + + return undefined; } } diff --git a/src/helpers/telemetryKeys.ts b/src/helpers/telemetryKeys.ts index aa98be67..b59ecfe2 100644 --- a/src/helpers/telemetryKeys.ts +++ b/src/helpers/telemetryKeys.ts @@ -1,25 +1,17 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static Result: string = 'result'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'openedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static GitHubPatDuration = 'gitHubPatDuration'; +export const CurrentUserInput = 'currentUserInput'; +export const RepoProvider = 'repoProvider'; +export const AzureLoginRequired = 'azureLoginRequired'; +export const JourneyId = 'journeyId'; +export const Result = 'result'; +export const SourceRepoLocation = 'sourceRepoLocation'; +export const ChosenTemplate = 'chosenTemplate'; +export const PipelineDiscarded = 'pipelineDiscarded'; +export const BrowsePipelineClicked = 'browsePipelineClicked'; +export const MultipleWorkspaceFolders = 'multipleWorkspaceFolders'; +export const GitHubPatDuration = 'gitHubPatDuration'; - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; -} +// Count of drop down items +export const OrganizationListCount = 'OrganizationListCount'; +export const ProjectListCount = 'ProjectListCount'; +export const WebAppListCount = 'WebAppListCount'; +export const PipelineTempateListCount = 'pipelineTempateListCount'; diff --git a/src/messages.ts b/src/messages.ts index 0ffcf06b..f0cfefd0 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -1,69 +1,54 @@ -export class Messages { - public static acquireAccessTokenFailed: string = 'Acquiring access token failed. Error: %s.'; - public static addYmlFile: string = 'Add Azure Pipelines YAML definition.'; - public static analyzingRepo: string = 'Analyzing your repo'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureAccountExtensionUnavailable: string = 'Azure Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static gitExtensionUnavailable: string = 'Git extension could not be fetched. Please ensure it\'s installed and activated.'; - public static gitExtensionNotEnabled: string = 'Git extension is not enabled. Please change the `git.enabled` setting to true.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchHeadMissing: string = `The current repository doesn't have any commits. Please [create a commit](https://git-scm.com/docs/git-commit) first, and then try this again.`; - public static branchNameMissing: string = `The current repository isn't on a branch. Please [checkout a branch](https://git-scm.com/docs/git-checkout) first, and then try this again.`; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRepositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string =`Commit failed due to error: %s`; - public static pushingPipelineFile: string = 'Pushing pipeline file...'; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Connecting Azure Pipelines with your subscription: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT)'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static gitHubPatErrorMessage: string = 'GitHub PAT cannot be empty.'; - public static noGitHubPatError: string = 'Please enter a GitHub PAT to configure pipeline'; - public static githubPatHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: full access to repository webhooks and services, read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static noAvailableFileNames: string = 'No available filenames found.'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectOrganizationForEnhancedIntelliSense: string = 'Select Azure DevOps organization associated with the %s repository for enhanced Azure Pipelines IntelliSense.'; - public static selectOrganizationLabel: string = 'Select organization'; - public static selectOrganizationPlaceholder: string = 'Select Azure DevOps organization associated with the %s repository'; - public static selectPipelineTemplate: string = 'Select an Azure Pipelines template...'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select an Azure subscription'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static unableToAccessOrganization: string = 'Unable to access the "%s" organization. Make sure you\'re signed into the right Azure account.'; - public static unableToCreateServiceConnection: string = `Unable to create %s service connection.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static timedOutCreatingServiceConnection: string =`Timed out creating %s service connection.\nService connection is not in ready state.`; - public static retryFailedMessage: string =`Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string =`Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string =`Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static signInForEnhancedIntelliSense = 'Sign in to Azure for enhanced Azure Pipelines IntelliSense'; - public static userEligibleForEnahanced1ESPTIntellisense = 'Enable 1ESPT Schema in Azure Pipelines Extension settings for enhanced Intellisense'; - public static notUsing1ESPTSchemaAsUserNotSignedInMessage = '1ESPT Schema is not used for Intellisense as you are not signed in with a `@microsoft.com` account'; - public static enable1ESPTSchema = 'Enable'; - public static doNotAskAgain = "Don't Ask Again"; -} +export const acquireAccessTokenFailed: string = 'Acquiring access token failed. Error: %s.'; +export const addYmlFile: string = 'Add Azure Pipelines YAML definition.'; +export const analyzingRepo: string = 'Analyzing your repo'; +export const azureAccountExtensionUnavailable: string = 'Azure Account extension could not be fetched. Please ensure it\'s installed and activated.'; +export const gitExtensionUnavailable: string = 'Git extension could not be fetched. Please ensure it\'s installed and activated.'; +export const gitExtensionNotEnabled: string = 'Git extension is not enabled. Please change the `git.enabled` setting to true.'; +export const azureLoginRequired: string = 'Please sign in to your Azure account first.'; +export const branchHeadMissing: string = `The current repository doesn't have any commits. Please [create a commit](https://git-scm.com/docs/git-commit) first, and then try this again.`; +export const branchNameMissing: string = `The current repository isn't on a branch. Please [checkout a branch](https://git-scm.com/docs/git-checkout) first, and then try this again.`; +export const branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; +export const browsePipeline: string = 'Browse Pipeline'; +export const cannotIdentifyRepositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; +export const commitAndPush: string = 'Commit & push'; +export const commitFailedErrorMessage: string =`Commit failed due to error: %s`; +export const pushingPipelineFile: string = 'Pushing pipeline file...'; +export const configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; +export const runningPostDeploymentActions: string = 'Running post-deployment actions...'; +export const couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; +export const creatingAzureServiceConnection: string = 'Connecting Azure Pipelines with your subscription: %s'; +export const creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; +export const discardPipeline: string = 'Discard pipeline'; +export const enterGitHubPat: string = 'Enter GitHub personal access token (PAT)'; +export const failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; +export const gitHubPatErrorMessage: string = 'GitHub PAT cannot be empty.'; +export const githubPatHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: full access to repository webhooks and services, read and write access to all repository data.'; +export const modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; +export const noAgentQueueFound: string = 'No agent pool found named "%s".'; +export const noAvailableFileNames: string = 'No available filenames found.'; +export const notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; +export const notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; +export const pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; +export const remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; +export const selectFolderLabel: string = 'Select source folder for configuring pipeline'; +export const selectOrganizationForEnhancedIntelliSense: string = 'Select Azure DevOps organization associated with the %s repository for enhanced Azure Pipelines IntelliSense.'; +export const selectOrganizationLabel: string = 'Select organization'; +export const selectOrganizationPlaceholder: string = 'Select Azure DevOps organization associated with the %s repository'; +export const selectPipelineTemplate: string = 'Select an Azure Pipelines template...'; +export const selectProject: string = 'Select an Azure DevOps project'; +export const selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; +export const selectSubscription: string = 'Select an Azure subscription'; +export const selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; +export const signInLabel: string = 'Sign In'; +export const unableToAccessOrganization: string = 'Unable to access the "%s" organization. Make sure you\'re signed into the right Azure account.'; +export const unableToCreateServiceConnection: string = `Unable to create %s service connection.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; +export const timedOutCreatingServiceConnection: string =`Timed out creating %s service connection.\nService connection is not in ready state.`; +export const retryFailedMessage: string =`Failed after retrying: %s times. Internal Error: %s`; +export const azureServicePrincipalFailedMessage: string =`Failed while creating Azure service principal.`; +export const roleAssignmentFailedMessage: string =`Failed while role assignement.`; +export const waitForAzureSignIn: string = `Waiting for Azure sign-in...`; +export const signInForEnhancedIntelliSense = 'Sign in to Azure for enhanced Azure Pipelines IntelliSense'; +export const userEligibleForEnahanced1ESPTIntellisense = 'Enable 1ESPT Schema in Azure Pipelines Extension settings for enhanced Intellisense'; +export const notUsing1ESPTSchemaAsUserNotSignedInMessage = '1ESPT Schema is not used for Intellisense as you are not signed in with a `@microsoft.com` account'; +export const enable1ESPTSchema = 'Enable'; +export const doNotAskAgain = "Don't Ask Again"; diff --git a/src/schema-association-service-1espt.ts b/src/schema-association-service-1espt.ts index 82edce17..3e2ece09 100644 --- a/src/schema-association-service-1espt.ts +++ b/src/schema-association-service-1espt.ts @@ -8,7 +8,7 @@ import { URI, Utils } from 'vscode-uri'; import * as azdev from 'azure-devops-node-api'; import * as logger from './logger'; import { AzureSession } from './typings/azure-account.api'; -import { Messages } from './messages'; +import * as Messages from './messages'; const milliseconds24hours = 86400000; @@ -35,7 +35,7 @@ export async function get1ESPTSchemaUri(azureDevOpsClient: azdev.WebApi, organiz } } catch (error) { - logger.log(`Error : ${error} while fetching 1ESPT schema for org: ${organizationName} : `, 'SchemaDetection'); + logger.log(`Error : ${String(error)} while fetching 1ESPT schema for org: ${organizationName} : `, 'SchemaDetection'); } return undefined; } @@ -63,10 +63,12 @@ export async function getCached1ESPTSchema(context: vscode.ExtensionContext, org try { if (session.userId.endsWith("@microsoft.com")) { if ((new Date().getTime() - lastUpdatedDate.getTime()) < milliseconds24hours) { - const schemaFileExists = await vscode.workspace.fs.stat(schemaUri1ESPT); - if (schemaFileExists) { + try { + await vscode.workspace.fs.stat(schemaUri1ESPT); logger.log("Returning cached schema for 1ESPT", 'SchemaDetection'); return schemaUri1ESPT; + } catch { + // Expected failure if file doesn't exist. } } // schema is older than 24 hours, fetch schema file again @@ -88,7 +90,7 @@ export async function getCached1ESPTSchema(context: vscode.ExtensionContext, org } } catch (error) { - logger.log(`Error : ${error} while fetching cached 1ESPT schema for org: ${organizationName}. It's possible that the schema does not exist.`, 'SchemaDetection'); + logger.log(`Error : ${String(error)} while fetching cached 1ESPT schema for org: ${organizationName}. It's possible that the schema does not exist.`, 'SchemaDetection'); } return undefined; @@ -104,7 +106,7 @@ export async function get1ESPTRepoIdIfAvailable(azureDevOpsClient: azdev.WebApi, try { const gitApi = await azureDevOpsClient.getGitApi(); const repositories = await gitApi.getRepositories('1ESPipelineTemplates'); - if (!repositories || repositories.length === 0) { + if (repositories.length === 0) { logger.log(`1ESPipelineTemplates ADO project not found for org ${organizationName}`, `SchemaDetection`); return ""; // 1ESPT ADO project not found } @@ -118,7 +120,7 @@ export async function get1ESPTRepoIdIfAvailable(azureDevOpsClient: azdev.WebApi, return repository.id; } catch (error) { - logger.log(`Error : ${error} while checking eligibility for enhanced Intellisense for 1ESPT schema for org: ${organizationName}.`, 'SchemaDetection'); + logger.log(`Error : ${String(error)} while checking eligibility for enhanced Intellisense for 1ESPT schema for org: ${organizationName}.`, 'SchemaDetection'); return ""; } } @@ -128,6 +130,6 @@ export async function delete1ESPTSchemaFileIfPresent(context: vscode.ExtensionCo await vscode.workspace.fs.delete(Utils.joinPath(context.globalStorageUri, '1ESPTSchema'), { recursive: true }); } catch (error) { - logger.log(`Error: ${error} while deleting 1ESPT schema. It's possible that the schema file does not exist`, 'SchemaDetection'); + logger.log(`Error: ${String(error)} while deleting 1ESPT schema. It's possible that the schema file does not exist`, 'SchemaDetection'); } } diff --git a/src/schema-association-service.ts b/src/schema-association-service.ts index 63e18c8c..7f9a3df8 100644 --- a/src/schema-association-service.ts +++ b/src/schema-association-service.ts @@ -11,11 +11,11 @@ import * as azdev from 'azure-devops-node-api'; import { format } from 'util'; import { getAzureAccountExtensionApi, getGitExtensionApi } from './extensionApis'; import { OrganizationsClient } from './configure/clients/devOps/organizationsClient'; -import { AzureDevOpsHelper } from './configure/helper/devOps/azureDevOpsHelper'; +import { getRepositoryDetailsFromRemoteUrl, isAzureReposUrl } from './configure/helper/devOps/azureDevOpsHelper'; import { showQuickPick } from './configure/helper/controlProvider'; import { QuickPickItemWithData } from './configure/model/models'; import * as logger from './logger'; -import { Messages } from './messages'; +import * as Messages from './messages'; import { AzureSession } from './typings/azure-account.api'; import { get1ESPTSchemaUri, getCached1ESPTSchema, get1ESPTRepoIdIfAvailable, delete1ESPTSchemaFileIfPresent } from './schema-association-service-1espt'; @@ -49,7 +49,7 @@ export async function locateSchemaFile( // Well, we tried our best. Fall back to the predetermined schema paths. // TODO: Re-throw error once we're more confident in the schema detection. logger.log( - `Error auto-detecting schema for workspace folder ${workspaceFolder.name}: ${error}`, + `Error auto-detecting schema for workspace folder ${workspaceFolder.name}: ${String(error)}`, 'SchemaDetection'); } } @@ -112,12 +112,12 @@ async function autoDetectSchema( logger.log("1ESPTSchema folder deleted as user is not signed in", 'SchemaDetection') } catch (error) { - logger.log(`Error ${error} while trying to delete 1ESPTSchema folder. Either the folder does not exist or there is an actual error.`, 'SchemaDetection') + logger.log(`Error ${String(error)} while trying to delete 1ESPTSchema folder. Either the folder does not exist or there is an actual error.`, 'SchemaDetection') } // Don't await this message so that we can return the fallback schema instead of blocking. // We'll detect the login in extension.ts and then re-request the schema. - vscode.window.showInformationMessage(Messages.signInForEnhancedIntelliSense, Messages.signInLabel) + void vscode.window.showInformationMessage(Messages.signInForEnhancedIntelliSense, Messages.signInLabel) .then(async action => { if (action === Messages.signInLabel) { await vscode.window.withProgress({ @@ -156,16 +156,16 @@ async function autoDetectSchema( } } catch (error) { // Log and that's it - perhaps they're not in a Git repo, and so don't have the Git extension enabled. - logger.log(`${workspaceFolder.name} has no remote URLs: ${error}`, 'SchemaDetection'); + logger.log(`${workspaceFolder.name} has no remote URLs: ${String(error)}`, 'SchemaDetection'); } let organizationName: string; let session: AzureSession | undefined; - if (remoteUrl !== undefined && AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { + if (remoteUrl !== undefined && isAzureReposUrl(remoteUrl)) { logger.log(`${workspaceFolder.name} is an Azure repo`, 'SchemaDetection'); // If we're in an Azure repo, we can silently determine the organization name and session. - organizationName = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).organizationName; + organizationName = getRepositoryDetailsFromRemoteUrl(remoteUrl).organizationName; for (const azureSession of azureAccountApi.sessions) { const organizationsClient = new OrganizationsClient(azureSession.credentials2); const organizations = await organizationsClient.listOrganizations(); @@ -197,33 +197,27 @@ async function autoDetectSchema( // then displaying the quick pick of all the organizations they have access to. // We *do not* await this message so that we can use the fallback schema while waiting. // We'll detect when they choose the organization in extension.ts and then re-request the schema. - vscode.window.showInformationMessage( + void vscode.window.showInformationMessage( format(Messages.selectOrganizationForEnhancedIntelliSense, workspaceFolder.name), Messages.selectOrganizationLabel) .then(async action => { if (action === Messages.selectOrganizationLabel) { // Lazily construct list of organizations so that we can immediately show the quick pick, // then fill in the choices as they come in. - const organizationAndSessionsPromise = new Promise< - QuickPickItemWithData[] - >(async resolve => { - const organizationAndSessions: QuickPickItemWithData[] = []; - - for (const azureSession of azureAccountApi.sessions) { - const organizationsClient = new OrganizationsClient(azureSession.credentials2); + const getOrganizationsAndSessions = async (): Promise[]> => { + return (await Promise.all(azureAccountApi.sessions.map(async session => { + const organizationsClient = new OrganizationsClient(session.credentials2); const organizations = await organizationsClient.listOrganizations(); - organizationAndSessions.push(...organizations.map(organization => ({ + return organizations.map(organization => ({ label: organization.accountName, - data: azureSession, - }))); - } - - resolve(organizationAndSessions); - }); + data: session, + })); + }))).flat(); + }; const selectedOrganizationAndSession = await showQuickPick( 'organization', - organizationAndSessionsPromise, { + getOrganizationsAndSessions(), { placeHolder: format(Messages.selectOrganizationPlaceholder, workspaceFolder.name), }); @@ -252,7 +246,7 @@ async function autoDetectSchema( // Not logged into an account that has access. if (session === undefined) { logger.log(`No organization found for ${workspaceFolder.name}`, 'SchemaDetection'); - vscode.window.showErrorMessage(format(Messages.unableToAccessOrganization, organizationName)); + void vscode.window.showErrorMessage(format(Messages.unableToAccessOrganization, organizationName)); await delete1ESPTSchemaFileIfPresent(context); return undefined; } @@ -276,7 +270,7 @@ async function autoDetectSchema( repoId1espt = await get1ESPTRepoIdIfAvailable(azureDevOpsClient, organizationName); } - if (repoId1espt?.length > 0) { + if (repoId1espt.length > 0) { // user has enabled 1ESPT schema if (vscode.workspace.getConfiguration('azure-pipelines', workspaceFolder).get('1ESPipelineTemplatesSchemaFile', false)) { const cachedSchemaUri1ESPT = await getCached1ESPTSchema(context, organizationName, session, lastUpdated1ESPTSchema); @@ -297,10 +291,10 @@ async function autoDetectSchema( if (context.globalState.get('doNotAskAgain1ESPTSchema') == undefined || !context.globalState.get('doNotAskAgain1ESPTSchema')) { const schema1esptPopupResponse = await vscode.window.showInformationMessage(Messages.userEligibleForEnahanced1ESPTIntellisense, Messages.enable1ESPTSchema, Messages.doNotAskAgain); if (schema1esptPopupResponse === Messages.enable1ESPTSchema) { - vscode.workspace.getConfiguration('azure-pipelines').update('1ESPipelineTemplatesSchemaFile', true, vscode.ConfigurationTarget.Workspace); + await vscode.workspace.getConfiguration('azure-pipelines').update('1ESPipelineTemplatesSchemaFile', true, vscode.ConfigurationTarget.Workspace); } else if (schema1esptPopupResponse === Messages.doNotAskAgain) { - context.globalState.update('doNotAskAgain1ESPTSchema', true); + await context.globalState.update('doNotAskAgain1ESPTSchema', true); } } } @@ -336,6 +330,6 @@ interface ISchemaAssociations { [pattern: string]: string[]; } -export namespace SchemaAssociationNotification { - export const type = new languageclient.NotificationType('json/schemaAssociations'); +export const SchemaAssociationNotification = { + type: new languageclient.NotificationType('json/schemaAssociations'), } diff --git a/src/schema-contributor.ts b/src/schema-contributor.ts index 9a4884c0..b96a2d4c 100644 --- a/src/schema-contributor.ts +++ b/src/schema-contributor.ts @@ -12,8 +12,9 @@ interface SchemaContributorProvider { // TODO: Add tests for this class. // TODO: Can we just get rid of this class? +// registerContributor is never called, which means the other two methods always throw. class SchemaContributor { - private _customSchemaContributors: { [index: string]: SchemaContributorProvider } = {}; + private _customSchemaContributors = new Map(); /** * Register a custom schema provider. @@ -27,18 +28,14 @@ class SchemaContributor { public registerContributor(schema: string, requestSchema: (resource: string) => string, requestSchemaContent: (uri: string) => string): boolean { - if (this._customSchemaContributors[schema]) { + if (this._customSchemaContributors.has(schema)) { return false; } - if (!requestSchema) { - throw new Error("Illegal parameter for requestSchema."); - } - - this._customSchemaContributors[schema] = { + this._customSchemaContributors.set(schema, { requestSchema, requestSchemaContent - }; + }); return true; } @@ -51,8 +48,7 @@ class SchemaContributor { * @returns {string} the schema uri */ public requestCustomSchema(resource: string): string { - for (let customKey of Object.keys(this._customSchemaContributors)) { - const contributor = this._customSchemaContributors[customKey]; + for (const contributor of this._customSchemaContributors.values()) { const uri = contributor.requestSchema(resource); if (uri) { return uri; @@ -62,6 +58,7 @@ class SchemaContributor { // TODO: This is currently the only way to fallback to the default schema provider. // The upstream Red Hat server also falls back when receiving a falsy value, // so sync with their changes and change this to return false or something. + // eslint-disable-next-line @typescript-eslint/no-throw-literal throw `Unable to find custom schema for resource: '${resource}'`; } @@ -74,13 +71,13 @@ class SchemaContributor { * @returns {string} the schema content */ public requestCustomSchemaContent(uri: string): string { - if (uri) { - const { scheme } = URI.parse(uri); - if (scheme && this._customSchemaContributors[scheme]) { - return this._customSchemaContributors[scheme].requestSchemaContent(uri); - } + const { scheme } = URI.parse(uri); + const contributor = this._customSchemaContributors.get(scheme); + if (contributor) { + return contributor.requestSchemaContent(uri); } + // eslint-disable-next-line @typescript-eslint/no-throw-literal throw `Unable to find custom schema content for uri: '${uri}'`; } } diff --git a/src/test/helper.ts b/src/test/helper.ts index a40b766c..8844447c 100644 --- a/src/test/helper.ts +++ b/src/test/helper.ts @@ -13,6 +13,7 @@ export let platformEol: string; */ export async function activate(docUri: vscode.Uri) { // The extensionId is `publisher.name` from package.json + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const ext = vscode.extensions.getExtension('ms-azure-devops.azure-pipelines')!; await ext.activate(); try { @@ -41,5 +42,7 @@ export async function setTestContent(content: string): Promise { doc.positionAt(0), doc.positionAt(doc.getText().length) ); - return editor.edit(eb => eb.replace(all, content)); + return editor.edit(eb => { + eb.replace(all, content) + }); } diff --git a/src/test/index.ts b/src/test/index.ts index ee90e5ee..b5924dad 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -15,7 +15,8 @@ export function run(): Promise { return new Promise((c, e) => { glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { - return e(err); + e(err); + return; } // Add files to the test suite diff --git a/src/test/runTest.ts b/src/test/runTest.ts index f4f28957..e57eb508 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -48,4 +48,4 @@ async function main() { } } -main(); +void main(); diff --git a/src/test/suite/configure/azureDevOpsHelper.test.ts b/src/test/suite/configure/azureDevOpsHelper.test.ts index 4772975a..5c71d54b 100644 --- a/src/test/suite/configure/azureDevOpsHelper.test.ts +++ b/src/test/suite/configure/azureDevOpsHelper.test.ts @@ -1,53 +1,53 @@ import * as assert from 'assert'; -import { AzureDevOpsHelper } from '../../../configure/helper/devOps/azureDevOpsHelper'; +import { isAzureReposUrl, getFormattedRemoteUrl, getRepositoryDetailsFromRemoteUrl, getOldFormatBuildDefinitionUrl, getOldFormatBuildUrl } from '../../../configure/helper/devOps/azureDevOpsHelper'; suite('Azure DevOps Helper', () => { suite('isAzureReposUrl', () => { test('Returns true for HTTPS ADO URLs', () => { - assert.ok(AzureDevOpsHelper.isAzureReposUrl('https://dev.azure.com/ms/example/_git/repo')); + assert.ok(isAzureReposUrl('https://dev.azure.com/ms/example/_git/repo')); }); test('Returns true for HTTPS ADO URLs with leading organization', () => { - assert.ok(AzureDevOpsHelper.isAzureReposUrl('https://ms@dev.azure.com/ms/example/_git/repo')); + assert.ok(isAzureReposUrl('https://ms@dev.azure.com/ms/example/_git/repo')); }); test('Returns true for SSH ADO URLs', () => { - assert.ok(AzureDevOpsHelper.isAzureReposUrl('git@ssh.dev.azure.com:v3/ms/example/repo')); + assert.ok(isAzureReposUrl('git@ssh.dev.azure.com:v3/ms/example/repo')); }); test('Returns true for legacy HTTPS VSTS URLs', () => { - assert.ok(AzureDevOpsHelper.isAzureReposUrl('https://ms.visualstudio.com/example/_git/repo')); + assert.ok(isAzureReposUrl('https://ms.visualstudio.com/example/_git/repo')); }); test('Returns true for legacy HTTPS VSTS URLs with DefaultCollection', () => { - assert.ok(AzureDevOpsHelper.isAzureReposUrl('https://ms.visualstudio.com/DefaultCollection/example/_git/repo')); + assert.ok(isAzureReposUrl('https://ms.visualstudio.com/DefaultCollection/example/_git/repo')); }); test('Returns true for legacy SSH VSTS URLs', () => { - assert.ok(AzureDevOpsHelper.isAzureReposUrl('ms@vs-ssh.visualstudio.com:v3/ms/example/repo')); + assert.ok(isAzureReposUrl('ms@vs-ssh.visualstudio.com:v3/ms/example/repo')); }); test('Returns false for non-ADO HTTPS URLs', () => { assert.strictEqual( - AzureDevOpsHelper.isAzureReposUrl('https://dev.azure.coms/ms/example/_git/repo'), + isAzureReposUrl('https://dev.azure.coms/ms/example/_git/repo'), false); }); test('Returns false for non-ADO SSH URLs', () => { assert.strictEqual( - AzureDevOpsHelper.isAzureReposUrl('git@dev.azure.com:v3/ms/example/repo'), + isAzureReposUrl('git@dev.azure.com:v3/ms/example/repo'), false); }); test('Returns false for non-VSTS HTTPS URLs', () => { assert.strictEqual( - AzureDevOpsHelper.isAzureReposUrl('https://ms.visualstudio.coms/example/_git/repo'), + isAzureReposUrl('https://ms.visualstudio.coms/example/_git/repo'), false); }); test('Returns false for non-VSTS SSH URLs', () => { assert.strictEqual( - AzureDevOpsHelper.isAzureReposUrl('ms@ssh.visualstudio.com:v3/ms/example/repo'), + isAzureReposUrl('ms@ssh.visualstudio.com:v3/ms/example/repo'), false); }); }); @@ -55,7 +55,7 @@ suite('Azure DevOps Helper', () => { suite('getRepositoryIdFromUrl', () => { test('Returns details from an HTTPS ADO URL', () => { assert.deepStrictEqual( - AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl('https://dev.azure.com/ms/example/_git/repo'), + getRepositoryDetailsFromRemoteUrl('https://dev.azure.com/ms/example/_git/repo'), { organizationName: 'ms', projectName: 'example', @@ -65,7 +65,7 @@ suite('Azure DevOps Helper', () => { test('Returns details from an HTTPS ADO URL with leading organization', () => { assert.deepStrictEqual( - AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl('https://ms@dev.azure.com/ms/example/_git/repo'), + getRepositoryDetailsFromRemoteUrl('https://ms@dev.azure.com/ms/example/_git/repo'), { organizationName: 'ms', projectName: 'example', @@ -75,7 +75,7 @@ suite('Azure DevOps Helper', () => { test('Returns details from a SSH ADO URL', () => { assert.deepStrictEqual( - AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl('git@ssh.dev.azure.com:v3/ms/example/repo'), + getRepositoryDetailsFromRemoteUrl('git@ssh.dev.azure.com:v3/ms/example/repo'), { organizationName: 'ms', projectName: 'example', @@ -85,7 +85,7 @@ suite('Azure DevOps Helper', () => { test('Returns details from a legacy HTTPS VSTS URL', () => { assert.deepStrictEqual( - AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl('https://ms.visualstudio.com/example/_git/repo'), + getRepositoryDetailsFromRemoteUrl('https://ms.visualstudio.com/example/_git/repo'), { organizationName: 'ms', projectName: 'example', @@ -95,7 +95,7 @@ suite('Azure DevOps Helper', () => { test('Returns details from a legacy HTTPS VSTS URL with DefaultCollection', () => { assert.deepStrictEqual( - AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl('https://ms.visualstudio.com/DefaultCollection/example/_git/repo'), + getRepositoryDetailsFromRemoteUrl('https://ms.visualstudio.com/DefaultCollection/example/_git/repo'), { organizationName: 'ms', projectName: 'example', @@ -105,7 +105,7 @@ suite('Azure DevOps Helper', () => { test('Returns details from a legacy SSH VSTS URL', () => { assert.deepStrictEqual( - AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl('ms@vs-ssh.visualstudio.com:v3/ms/example/repo'), + getRepositoryDetailsFromRemoteUrl('ms@vs-ssh.visualstudio.com:v3/ms/example/repo'), { organizationName: 'ms', projectName: 'example', @@ -117,25 +117,25 @@ suite('Azure DevOps Helper', () => { suite('getFormattedRemoteUrl', () => { test('Returns HTTPS ADO URLs as-is', () => { assert.strictEqual( - AzureDevOpsHelper.getFormattedRemoteUrl('https://dev.azure.com/ms/example/_git/repo'), + getFormattedRemoteUrl('https://dev.azure.com/ms/example/_git/repo'), 'https://dev.azure.com/ms/example/_git/repo'); }); test('Returns HTTPS ADO URLs with leading organization as-is', () => { assert.strictEqual( - AzureDevOpsHelper.getFormattedRemoteUrl('https://ms@dev.azure.com/ms/example/_git/repo'), + getFormattedRemoteUrl('https://ms@dev.azure.com/ms/example/_git/repo'), 'https://ms@dev.azure.com/ms/example/_git/repo'); }); test('Returns an HTTPS VSTS URL from a SSH ADO URL', () => { assert.strictEqual( - AzureDevOpsHelper.getFormattedRemoteUrl('git@ssh.dev.azure.com:v3/ms/example/repo'), + getFormattedRemoteUrl('git@ssh.dev.azure.com:v3/ms/example/repo'), 'https://ms.visualstudio.com/example/_git/repo'); }); test('Returns an HTTPS VSTS URL from a SSH VSTS URL', () => { assert.strictEqual( - AzureDevOpsHelper.getFormattedRemoteUrl('ms@vs-ssh.visualstudio.com:v3/ms/example/repo'), + getFormattedRemoteUrl('ms@vs-ssh.visualstudio.com:v3/ms/example/repo'), 'https://ms.visualstudio.com/example/_git/repo'); }); }); @@ -143,7 +143,7 @@ suite('Azure DevOps Helper', () => { suite('getOldFormatBuildDefinitionUrl', () => { test('Returns a legacy HTTPS VSTS build definition URL', () => { assert.strictEqual( - AzureDevOpsHelper.getOldFormatBuildDefinitionUrl('ms', 'example', 42), + getOldFormatBuildDefinitionUrl('ms', 'example', 42), 'https://ms.visualstudio.com/example/_build?definitionId=42&_a=summary'); }); }); @@ -151,7 +151,7 @@ suite('Azure DevOps Helper', () => { suite('getOldFormatBuildUrl', () => { test('Returns a legacy HTTPS VSTS build URL', () => { assert.strictEqual( - AzureDevOpsHelper.getOldFormatBuildUrl('ms', 'example', 42), + getOldFormatBuildUrl('ms', 'example', 42), 'https://ms.visualstudio.com/example/_build/results?buildId=42&view=results'); }); }); diff --git a/src/test/suite/configure/gitHubHelper.test.ts b/src/test/suite/configure/gitHubHelper.test.ts index 6e814211..fe6bf162 100644 --- a/src/test/suite/configure/gitHubHelper.test.ts +++ b/src/test/suite/configure/gitHubHelper.test.ts @@ -1,29 +1,29 @@ import * as assert from 'assert'; -import { GitHubProvider } from '../../../configure/helper/gitHubHelper'; +import { isGitHubUrl, getFormattedRemoteUrl, getRepositoryDetailsFromRemoteUrl } from '../../../configure/helper/gitHubHelper'; suite('GitHub Helper', () => { suite('isGitHubUrl', () => { test('Returns true for HTTPS GitHub URLs', () => { - assert.ok(GitHubProvider.isGitHubUrl('https://github.com/microsoft/azure-pipelines-vscode')); + assert.ok(isGitHubUrl('https://github.com/microsoft/azure-pipelines-vscode')); }); test('Returns true for HTTPS GitHub URLs with trailing .git', () => { - assert.ok(GitHubProvider.isGitHubUrl('https://github.com/microsoft/azure-pipelines-vscode.git')); + assert.ok(isGitHubUrl('https://github.com/microsoft/azure-pipelines-vscode.git')); }); test('Returns true for SSH GitHub URLs', () => { - assert.ok(GitHubProvider.isGitHubUrl('git@github.com:microsoft/azure-pipelines-vscode.git')); + assert.ok(isGitHubUrl('git@github.com:microsoft/azure-pipelines-vscode.git')); }); test('Returns false for non-GitHub HTTPS URLs', () => { assert.strictEqual( - GitHubProvider.isGitHubUrl('https://github.coms/microsoft/azure-pipelines-vscode'), + isGitHubUrl('https://github.coms/microsoft/azure-pipelines-vscode'), false); }); test('Returns false for non-GitHub SSH URLs', () => { assert.strictEqual( - GitHubProvider.isGitHubUrl('sgit@github.com:microsoft/azure-pipelines-vscode.git'), + isGitHubUrl('sgit@github.com:microsoft/azure-pipelines-vscode.git'), false); }); }); @@ -31,19 +31,19 @@ suite('GitHub Helper', () => { suite('getRepositoryDetailsFromRemoteUrl', () => { test('Returns owner and repo from an HTTPS URL', () => { assert.deepStrictEqual( - GitHubProvider.getRepositoryDetailsFromRemoteUrl('https://github.com/microsoft/azure-pipelines-vscode'), + getRepositoryDetailsFromRemoteUrl('https://github.com/microsoft/azure-pipelines-vscode'), { ownerName: 'microsoft', repositoryName: 'azure-pipelines-vscode' }); }); test('Returns owner from an HTTPS URL with trailing .git', () => { assert.deepStrictEqual( - GitHubProvider.getRepositoryDetailsFromRemoteUrl('https://github.com/microsoft/azure-pipelines-vscode.git'), + getRepositoryDetailsFromRemoteUrl('https://github.com/microsoft/azure-pipelines-vscode.git'), { ownerName: 'microsoft', repositoryName: 'azure-pipelines-vscode' }); }); test('Returns owner from a SSH URL', () => { assert.deepStrictEqual( - GitHubProvider.getRepositoryDetailsFromRemoteUrl('git@github.com:microsoft/azure-pipelines-vscode.git'), + getRepositoryDetailsFromRemoteUrl('git@github.com:microsoft/azure-pipelines-vscode.git'), { ownerName: 'microsoft', repositoryName: 'azure-pipelines-vscode' }); }); }); @@ -51,13 +51,13 @@ suite('GitHub Helper', () => { suite('getFormattedRemoteUrl', () => { test('Returns HTTPS URLs as-is', () => { assert.strictEqual( - GitHubProvider.getFormattedRemoteUrl('https://github.com/microsoft/azure-pipelines-vscode.git'), + getFormattedRemoteUrl('https://github.com/microsoft/azure-pipelines-vscode.git'), 'https://github.com/microsoft/azure-pipelines-vscode.git'); }); test('Returns an HTTPS URL from a SSH URL', () => { assert.strictEqual( - GitHubProvider.getFormattedRemoteUrl('git@github.com:microsoft/azure-pipelines-vscode.git'), + getFormattedRemoteUrl('git@github.com:microsoft/azure-pipelines-vscode.git'), 'https://github.com/microsoft/azure-pipelines-vscode.git'); }); }); diff --git a/src/test/suite/fromserver.test.ts b/src/test/suite/fromserver.test.ts index 10350fa6..4af4b197 100644 --- a/src/test/suite/fromserver.test.ts +++ b/src/test/suite/fromserver.test.ts @@ -17,7 +17,7 @@ import * as vscode from 'vscode'; // console.log('workspace configuration: ' + JSON.stringify(vscode.workspace.getConfiguration())); // 2. -suite('Validation Tests From Server', async function() { +suite('Validation Tests From Server', function() { this.timeout(1000000); test ('Validate all files from server', async function () { diff --git a/tools/extract-yaml-testcases/package-lock.json b/tools/extract-yaml-testcases/package-lock.json index fa761bf2..07acd34f 100644 --- a/tools/extract-yaml-testcases/package-lock.json +++ b/tools/extract-yaml-testcases/package-lock.json @@ -8,735 +8,61 @@ "name": "extract-yaml-testcases", "version": "1.0.0", "license": "MIT", - "dependencies": { - "@types/node": "10.7.1", - "ts-node": "7.0.1", - "tslint": "5.18.0", - "typescript": "3.0.1" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dependencies": { - "@babel/highlight": "^7.0.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dependencies": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" + "devDependencies": { + "@types/node": "~20.9.2", + "typescript": "~5.2.2" } }, "node_modules/@types/node": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.7.1.tgz", - "integrity": "sha512-EGoI4ylB/lPOaqXqtzAyL8HcgOuCtH2hkEaLmkueOYufsTFWBn4VCvlCDC2HW8Q+9iF+QVC3sxjDKQYjHQeZ9w==" - }, - "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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "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/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "engines": { - "node": ">=0.3.1" - } - }, - "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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "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==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dependencies": { - "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" - }, - "engines": { - "node": "*" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "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==" - }, - "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/make-error": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", - "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==" - }, - "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/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "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": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "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/resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dependencies": { - "path-parse": "^1.0.6" - } - }, - "node_modules/semver": { - "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/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.8.tgz", - "integrity": "sha512-WqAEWPdb78u25RfKzOF0swBpY0dKrNdjc4GvLwm7ScX/o9bj8Eh/YL8mcMhBHYDGl87UkkSXDOFnW4G7GhWhGg==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "version": "20.9.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.2.tgz", + "integrity": "sha512-WHZXKFCEyIUJzAwh3NyyTHYSR35SevJ6mZ1nWwJafKtiQbqRTIKSRcw3Ma3acqgsent3RRDqeVwpHntMk+9irg==", + "dev": true, "dependencies": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - }, - "node_modules/tslint": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz", - "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^3.2.0", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.8.0" - }, - "peerDependencies": { - "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" - } - }, - "node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + "undici-types": "~5.26.4" } }, "node_modules/typescript": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.1.tgz", - "integrity": "sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "engines": { - "node": ">=4" - } + "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==", + "dev": true } }, "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, "@types/node": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.7.1.tgz", - "integrity": "sha512-EGoI4ylB/lPOaqXqtzAyL8HcgOuCtH2hkEaLmkueOYufsTFWBn4VCvlCDC2HW8Q+9iF+QVC3sxjDKQYjHQeZ9w==" - }, - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "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" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "make-error": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", - "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "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==" - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "requires": { - "minimist": "^1.2.6" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "version": "20.9.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.2.tgz", + "integrity": "sha512-WHZXKFCEyIUJzAwh3NyyTHYSR35SevJ6mZ1nWwJafKtiQbqRTIKSRcw3Ma3acqgsent3RRDqeVwpHntMk+9irg==", + "dev": true, "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "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==" - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.8.tgz", - "integrity": "sha512-WqAEWPdb78u25RfKzOF0swBpY0dKrNdjc4GvLwm7ScX/o9bj8Eh/YL8mcMhBHYDGl87UkkSXDOFnW4G7GhWhGg==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - }, - "tslint": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz", - "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==", - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^3.2.0", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "requires": { - "tslib": "^1.8.1" + "undici-types": "~5.26.4" } }, "typescript": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.1.tgz", - "integrity": "sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=" + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true + }, + "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==", + "dev": true } } } diff --git a/tools/extract-yaml-testcases/package.json b/tools/extract-yaml-testcases/package.json index d29b69c4..65e68777 100644 --- a/tools/extract-yaml-testcases/package.json +++ b/tools/extract-yaml-testcases/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "A tool for extracting YAML test cases from a C# file", "main": "./out/main.js", + "type": "module", "scripts": { "prestart": "npm run compile", "start": "node ./out/main.js", @@ -11,10 +12,8 @@ }, "author": "Microsoft", "license": "MIT", - "dependencies": { - "@types/node": "10.7.1", - "ts-node": "7.0.1", - "tslint": "5.18.0", - "typescript": "3.0.1" + "devDependencies": { + "@types/node": "~20.9.2", + "typescript": "~5.2.2" } } diff --git a/tools/extract-yaml-testcases/src/main.ts b/tools/extract-yaml-testcases/src/main.ts index bcee0fc7..59074479 100644 --- a/tools/extract-yaml-testcases/src/main.ts +++ b/tools/extract-yaml-testcases/src/main.ts @@ -1,41 +1,22 @@ -const fs = require('fs'); -const path = require('path'); +import fs from 'node:fs/promises'; +import path from 'node:path'; if (process.argv.length <= 2) { usage(); } else { - let options = parseOptions(process.argv); - console.log(options); + const options = parseOptions(process.argv); - fs.readFile(options.input, 'utf8', (err: NodeJS.ErrnoException, data: string) => { - if (err) { - if (err.code === 'ENOENT') { - console.error('could not read input file'); - process.exit(1); - } - - console.error('some error reading input file'); - process.exit(1); - } - - fs.mkdir(options.outputDir, (err: NodeJS.ErrnoException) => { - if (err && err.code !== 'EEXIST') { - console.error('error creating output directory'); - process.exit(1); - } - - // here we do something with the input file - extractYaml(data, options.outputDir); - }); - }); + const data = await fs.readFile(options.input, 'utf-8'); + await fs.mkdir(options.outputDir, { recursive: true }); + await extractYaml(data, options.outputDir); } -function usage() { +function usage(): void { console.log("usage: extract-yaml-testcases []"); } -function parseOptions(rawArgs: string[]) { - let interestingArgs = rawArgs.slice(2); +function parseOptions(rawArgs: string[]): { input: string, outputDir: string } { + const interestingArgs = rawArgs.slice(2); if (interestingArgs.length > 2) { usage(); process.exit(1); @@ -43,21 +24,21 @@ function parseOptions(rawArgs: string[]) { return { input: interestingArgs[0], - outputDir: interestingArgs[1] || "./output" + outputDir: interestingArgs[1] ?? "./output" }; } -function extractYaml(fileData: string, outputDir: string) { +async function extractYaml(fileData: string, outputDir: string): Promise { // find the TestMethod-attributed code blocks, extract their name and contents const matcher = /\[TestMethod\][^]*?public void (.*?)\([^]*?\{([^]*?)\}/g; let chunk = matcher.exec(fileData); while (chunk !== null) { - outputYaml(chunk[1], chunk[2], outputDir); + await outputYaml(chunk[1], chunk[2], outputDir); chunk = matcher.exec(fileData); } } -function outputYaml(name: string, body: string, outputDir: string) { +async function outputYaml(name: string, body: string, outputDir: string): Promise { const testCaseName = name.split('_').slice(1).join('_'); const outputBaseName = path.join(outputDir, testCaseName); @@ -69,12 +50,8 @@ function outputYaml(name: string, body: string, outputDir: string) { const rawContents = mlString[1].trim(); // replace artificial tasks "foo@1", "myTask@1", and "myOtherTask@2" with a real task name const cookedContents = rawContents.replace(/foo@1|myTask@1|myOtherTask@2/gi, "Bash@3"); - fs.writeFile(finalFileName, cookedContents, 'utf8', (err: NodeJS.ErrnoException) => { - if (err) { - console.error('trouble writing ' + finalFileName); - } - }); + await fs.writeFile(finalFileName, cookedContents, 'utf8'); mlString = multilineStringMatcher.exec(body); number++; } -} \ No newline at end of file +} diff --git a/tools/extract-yaml-testcases/tsconfig.json b/tools/extract-yaml-testcases/tsconfig.json index f17a468b..5d5161b0 100644 --- a/tools/extract-yaml-testcases/tsconfig.json +++ b/tools/extract-yaml-testcases/tsconfig.json @@ -1,11 +1,8 @@ { "compilerOptions": { - "module": "commonjs", - "target": "es6", + "module": "Node16", + "target": "ES2022", "outDir": "out", - "lib": [ - "es6" - ], "sourceMap": true, "rootDir": "src", "strict": true, @@ -13,8 +10,5 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "noUnusedParameters": true, - }, - "exclude": [ - "node_modules" - ] -} \ No newline at end of file + } +} diff --git a/tsconfig.json b/tsconfig.json index 2022a3a4..24bf8227 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -48,8 +48,5 @@ }, "include": [ "src" - ], - "exclude": [ - "src/test" ] } diff --git a/tsconfig.test.json b/tsconfig.test.json index a59b5072..eeacd5f8 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -11,7 +11,5 @@ }, "include": [ "src/test" - ], - // Clear exclude from the base config. - "exclude": [] + ] } diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 2bd680db..00000000 --- a/tslint.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "rules": { - "no-string-throw": true, - "no-unused-expression": true, - "no-duplicate-variable": true, - "curly": true, - "class-name": true, - "semicolon": [ - true, - "always" - ], - "triple-equals": true - }, - "defaultSeverity": "warning" -} \ No newline at end of file