diff --git a/deadlock-plugins/deadlock-extension/jest.config.ts b/deadlock-plugins/deadlock-extension/jest.config.ts index fd75b552d152352671a9e9dfb5175ac3e3a9f250..66ff808b26c59ed427f16c0643781dfe335d3256 100644 --- a/deadlock-plugins/deadlock-extension/jest.config.ts +++ b/deadlock-plugins/deadlock-extension/jest.config.ts @@ -142,6 +142,7 @@ export default { // A list of paths to modules that run some code to configure or set up the testing framework before each test // setupFilesAfterEnv: [], + setupFilesAfterEnv: ['<rootDir>/src/test/setupTests.ts'], // The number of seconds after which a test is considered as slow and reported as such in the results. // slowTestThreshold: 5, diff --git a/deadlock-plugins/deadlock-extension/package-lock.json b/deadlock-plugins/deadlock-extension/package-lock.json index ba6333d8f8331a21a52d2eb12fdec3aec16ecd08..8fb8b4ec2eb5564553fc4efa6f621d757686c21e 100644 --- a/deadlock-plugins/deadlock-extension/package-lock.json +++ b/deadlock-plugins/deadlock-extension/package-lock.json @@ -39,6 +39,7 @@ "eslint": "^7.32.0", "glob": "^7.2.0", "jest": "^28.1.0", + "msw": "^0.42.1", "prettier": "2.6.2", "terser-webpack-plugin": "^5.2.5", "ts-jest": "^28.0.4", @@ -1277,6 +1278,42 @@ "exenv-es6": "^1.1.1" } }, + "node_modules/@mswjs/cookies": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-0.2.1.tgz", + "integrity": "sha512-0tDfcPw5/s7QsNQqS3knAvAD5w5PF1nNPagRhKO/yECY+sMbJxoC2sLWnH7Lzmh52mTSVLKDhd1r92Q3kfljnQ==", + "dev": true, + "dependencies": { + "@types/set-cookie-parser": "^2.4.0", + "set-cookie-parser": "^2.4.6" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@mswjs/interceptors": { + "version": "0.16.4", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.16.4.tgz", + "integrity": "sha512-McPKUFlZNS/wo+OAor15k0fv2skK+EdWl9CEcdxAqsN4vKajlxCxDU4B5W/pn1y0TJPSAOmxR6LYFe/8esePrg==", + "dev": true, + "dependencies": { + "@open-draft/until": "^1.0.3", + "@xmldom/xmldom": "^0.7.5", + "debug": "^4.3.3", + "headers-polyfill": "^3.0.4", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.2.4" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@open-draft/until": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-1.0.3.tgz", + "integrity": "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==", + "dev": true + }, "node_modules/@sinclair/typebox": { "version": "0.23.5", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", @@ -1419,6 +1456,12 @@ "@types/node": "*" } }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, "node_modules/@types/crypto-js": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz", @@ -1542,6 +1585,12 @@ "pretty-format": "^27.0.0" } }, + "node_modules/@types/js-levenshtein": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz", + "integrity": "sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g==", + "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", @@ -1625,6 +1674,15 @@ "@types/node": "*" } }, + "node_modules/@types/set-cookie-parser": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz", + "integrity": "sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/sockjs": { "version": "0.3.33", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", @@ -2069,6 +2127,15 @@ } } }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz", + "integrity": "sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -2934,6 +3001,12 @@ "node": ">=10" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "node_modules/cheerio": { "version": "1.0.0-rc.10", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", @@ -3031,6 +3104,39 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -3042,6 +3148,15 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -3383,6 +3498,15 @@ "node": ">= 10" } }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -4174,6 +4298,32 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4228,6 +4378,30 @@ "pend": "~1.2.0" } }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -4620,6 +4794,15 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "node_modules/graphql": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.5.0.tgz", + "integrity": "sha512-qbHgh8Ix+j/qY+a/ZcJnFQ+j8ezakqPiHwPiZhV/3PgGlgf96QMBB5/f2rkiC9sgLoy/xvT6TSiaf2nTHJh5iA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -4686,6 +4869,12 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, + "node_modules/headers-polyfill": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.0.7.tgz", + "integrity": "sha512-JoLCAdCEab58+2/yEmSnOlficyHFpIl0XJqwu3l+Unkm1gXpFUYsThz6Yha3D6tNhocWkCPfyW0YVIGWFqTi7w==", + "dev": true + }, "node_modules/hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", @@ -4947,6 +5136,32 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "node_modules/inquirer": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", + "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -5039,6 +5254,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-node-process": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.0.1.tgz", + "integrity": "sha512-5IcdXuf++TTNt3oGl9EBdkvndXA8gmc4bz/Y+mdEpWh3Mcn/+kOw6hI7LD5CocqJWMzeb0I0ClndRVNdEPuJXQ==", + "dev": true + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5084,6 +5314,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -6252,6 +6494,15 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6429,6 +6680,22 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6694,6 +6961,150 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/msw": { + "version": "0.42.1", + "resolved": "https://registry.npmjs.org/msw/-/msw-0.42.1.tgz", + "integrity": "sha512-LZZuz7VddL45gCBgfBWHyXj6a4W7OTJY0mZPoipJ3P/xwbuJwrtwB3IJrWlqBM8aink/eTKlRxwzmtIAwCj5yQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@mswjs/cookies": "^0.2.0", + "@mswjs/interceptors": "^0.16.3", + "@open-draft/until": "^1.0.3", + "@types/cookie": "^0.4.1", + "@types/js-levenshtein": "^1.1.1", + "chalk": "4.1.1", + "chokidar": "^3.4.2", + "cookie": "^0.4.2", + "graphql": "^16.3.0", + "headers-polyfill": "^3.0.4", + "inquirer": "^8.2.0", + "is-node-process": "^1.0.1", + "js-levenshtein": "^1.1.6", + "node-fetch": "^2.6.7", + "outvariant": "^1.3.0", + "path-to-regexp": "^6.2.0", + "statuses": "^2.0.0", + "strict-event-emitter": "^0.2.0", + "type-fest": "^1.2.2", + "yargs": "^17.3.1" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.2.x <= 4.7.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/msw/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/msw/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/msw/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/msw/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/msw/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/msw/node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "dev": true + }, + "node_modules/msw/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/msw/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/multicast-dns": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", @@ -6973,9 +7384,47 @@ "word-wrap": "^1.2.3" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, + "node_modules/outvariant": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.3.0.tgz", + "integrity": "sha512-yeWM9k6UPfG/nzxdaPlJkB2p08hCg4xP6Lx99F+vP8YF7xyZVfTmJjrrNalkmzudD4WFvNLVudQikqUmF8zhVQ==", + "dev": true + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -7588,6 +8037,19 @@ "node": ">=10" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -7612,6 +8074,30 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/rxjs/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -7848,6 +8334,12 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "node_modules/set-cookie-parser": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.5.0.tgz", + "integrity": "sha512-cHMAtSXilfyBePduZEBVPTCftTQWz6ehWJD5YNUg4mqvRosrrjKbo4WS8JkB0/RxonMoohHm7cOGH60mDkRQ9w==", + "dev": true + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -8133,6 +8625,15 @@ "node": ">= 0.8" } }, + "node_modules/strict-event-emitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.2.4.tgz", + "integrity": "sha512-xIqTLS5azUH1djSUsLH9DbP6UnM/nI18vu8d43JigCQEoVsnY+mrlE+qv6kYqs6/1OkMnMIiL6ffedQSZStuoQ==", + "dev": true, + "dependencies": { + "events": "^3.3.0" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -8467,6 +8968,12 @@ "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "dev": true }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -8973,6 +9480,15 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -10508,6 +11024,36 @@ "exenv-es6": "^1.1.1" } }, + "@mswjs/cookies": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-0.2.1.tgz", + "integrity": "sha512-0tDfcPw5/s7QsNQqS3knAvAD5w5PF1nNPagRhKO/yECY+sMbJxoC2sLWnH7Lzmh52mTSVLKDhd1r92Q3kfljnQ==", + "dev": true, + "requires": { + "@types/set-cookie-parser": "^2.4.0", + "set-cookie-parser": "^2.4.6" + } + }, + "@mswjs/interceptors": { + "version": "0.16.4", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.16.4.tgz", + "integrity": "sha512-McPKUFlZNS/wo+OAor15k0fv2skK+EdWl9CEcdxAqsN4vKajlxCxDU4B5W/pn1y0TJPSAOmxR6LYFe/8esePrg==", + "dev": true, + "requires": { + "@open-draft/until": "^1.0.3", + "@xmldom/xmldom": "^0.7.5", + "debug": "^4.3.3", + "headers-polyfill": "^3.0.4", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.2.4" + } + }, + "@open-draft/until": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-1.0.3.tgz", + "integrity": "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==", + "dev": true + }, "@sinclair/typebox": { "version": "0.23.5", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", @@ -10562,12 +11108,6 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, - "@types/async": { - "version": "3.2.13", - "resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.13.tgz", - "integrity": "sha512-7Q3awrhnvm89OzfsmqeqRQh8mh+8Pxfgq1UvSAn2nWQ5y/F3+NrbIF0RbkWq8+5dY99ozgap2b3DNBNwjLVOxw==", - "dev": true - }, "@types/babel__core": { "version": "7.1.19", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", @@ -10647,6 +11187,12 @@ "@types/node": "*" } }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, "@types/crypto-js": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz", @@ -10770,6 +11316,12 @@ "pretty-format": "^27.0.0" } }, + "@types/js-levenshtein": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz", + "integrity": "sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g==", + "dev": true + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -10853,6 +11405,15 @@ "@types/node": "*" } }, + "@types/set-cookie-parser": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz", + "integrity": "sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/sockjs": { "version": "0.3.33", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", @@ -11202,6 +11763,12 @@ "dev": true, "requires": {} }, + "@xmldom/xmldom": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz", + "integrity": "sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==", + "dev": true + }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -11851,6 +12418,12 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "cheerio": { "version": "1.0.0-rc.10", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", @@ -11927,6 +12500,27 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -11938,6 +12532,12 @@ "wrap-ansi": "^7.0.0" } }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true + }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -12213,6 +12813,15 @@ "execa": "^5.0.0" } }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, "define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -12818,6 +13427,28 @@ } } }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -12869,6 +13500,23 @@ "pend": "~1.2.0" } }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + } + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -13171,6 +13819,12 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "graphql": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.5.0.tgz", + "integrity": "sha512-qbHgh8Ix+j/qY+a/ZcJnFQ+j8ezakqPiHwPiZhV/3PgGlgf96QMBB5/f2rkiC9sgLoy/xvT6TSiaf2nTHJh5iA==", + "dev": true + }, "handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -13217,6 +13871,12 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, + "headers-polyfill": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.0.7.tgz", + "integrity": "sha512-JoLCAdCEab58+2/yEmSnOlficyHFpIl0XJqwu3l+Unkm1gXpFUYsThz6Yha3D6tNhocWkCPfyW0YVIGWFqTi7w==", + "dev": true + }, "hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", @@ -13407,6 +14067,29 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "inquirer": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", + "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + } + }, "interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -13475,6 +14158,18 @@ "is-extglob": "^2.1.1" } }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, + "is-node-process": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.0.1.tgz", + "integrity": "sha512-5IcdXuf++TTNt3oGl9EBdkvndXA8gmc4bz/Y+mdEpWh3Mcn/+kOw6hI7LD5CocqJWMzeb0I0ClndRVNdEPuJXQ==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -13502,6 +14197,12 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -14395,6 +15096,12 @@ } } }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -14538,6 +15245,16 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -14741,6 +15458,103 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "msw": { + "version": "0.42.1", + "resolved": "https://registry.npmjs.org/msw/-/msw-0.42.1.tgz", + "integrity": "sha512-LZZuz7VddL45gCBgfBWHyXj6a4W7OTJY0mZPoipJ3P/xwbuJwrtwB3IJrWlqBM8aink/eTKlRxwzmtIAwCj5yQ==", + "dev": true, + "requires": { + "@mswjs/cookies": "^0.2.0", + "@mswjs/interceptors": "^0.16.3", + "@open-draft/until": "^1.0.3", + "@types/cookie": "^0.4.1", + "@types/js-levenshtein": "^1.1.1", + "chalk": "4.1.1", + "chokidar": "^3.4.2", + "cookie": "^0.4.2", + "graphql": "^16.3.0", + "headers-polyfill": "^3.0.4", + "inquirer": "^8.2.0", + "is-node-process": "^1.0.1", + "js-levenshtein": "^1.1.6", + "node-fetch": "^2.6.7", + "outvariant": "^1.3.0", + "path-to-regexp": "^6.2.0", + "statuses": "^2.0.0", + "strict-event-emitter": "^0.2.0", + "type-fest": "^1.2.2", + "yargs": "^17.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + } + } + }, "multicast-dns": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", @@ -14956,6 +15770,35 @@ "word-wrap": "^1.2.3" } }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true + }, + "outvariant": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.3.0.tgz", + "integrity": "sha512-yeWM9k6UPfG/nzxdaPlJkB2p08hCg4xP6Lx99F+vP8YF7xyZVfTmJjrrNalkmzudD4WFvNLVudQikqUmF8zhVQ==", + "dev": true + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -15423,6 +16266,16 @@ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -15438,6 +16291,29 @@ "glob": "^7.1.3" } }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + } + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -15632,6 +16508,12 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "set-cookie-parser": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.5.0.tgz", + "integrity": "sha512-cHMAtSXilfyBePduZEBVPTCftTQWz6ehWJD5YNUg4mqvRosrrjKbo4WS8JkB0/RxonMoohHm7cOGH60mDkRQ9w==", + "dev": true + }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -15857,6 +16739,15 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true }, + "strict-event-emitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.2.4.tgz", + "integrity": "sha512-xIqTLS5azUH1djSUsLH9DbP6UnM/nI18vu8d43JigCQEoVsnY+mrlE+qv6kYqs6/1OkMnMIiL6ffedQSZStuoQ==", + "dev": true, + "requires": { + "events": "^3.3.0" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -16105,6 +16996,12 @@ "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -16475,6 +17372,15 @@ "minimalistic-assert": "^1.0.0" } }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/deadlock-plugins/deadlock-extension/package.json b/deadlock-plugins/deadlock-extension/package.json index 9c16b2eca8a08f02100b92d90b1d5c75ede93802..71d9b3fc926b96257ed17d533868f089f0e79214 100644 --- a/deadlock-plugins/deadlock-extension/package.json +++ b/deadlock-plugins/deadlock-extension/package.json @@ -130,6 +130,7 @@ "eslint": "^7.32.0", "glob": "^7.2.0", "jest": "^28.1.0", + "msw": "^0.42.1", "prettier": "2.6.2", "terser-webpack-plugin": "^5.2.5", "ts-jest": "^28.0.4", diff --git a/deadlock-plugins/deadlock-extension/src/core/api.service.ts b/deadlock-plugins/deadlock-extension/src/core/api.service.ts index 5ed61fc54974c2f507a599d65146b6e9679f66ea..4bbdee7322c2b034ca43bc205b5d856071f40fea 100644 --- a/deadlock-plugins/deadlock-extension/src/core/api.service.ts +++ b/deadlock-plugins/deadlock-extension/src/core/api.service.ts @@ -3,6 +3,7 @@ import { API_QUERY_REFERER, API_URL } from '../config'; import { GiteaPublicProperties } from '../model/giteaPublicProperties.model'; import { SshKeyPair } from '../model/sshKeyPair.model'; import { User } from '../model/user.model'; +import { extensionError as error } from '../recorder/utils/log'; import Controller from './controller'; import ExtensionStore from './extensionStore'; import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnection'; @@ -97,7 +98,7 @@ export default class ApiService { return await this.onInvalidRefreshToken(originalConfig); } } else { - console.error(`[DEADLOCK-EXTENSION] - Error not handled: ${_error}`); + error(`Error not handled: ${_error}`); throw _error; } } diff --git a/deadlock-plugins/deadlock-extension/src/core/controller.ts b/deadlock-plugins/deadlock-extension/src/core/controller.ts index 2531da63714624ff9776babf66580bf84bd32b4e..145974603be899716d75a8f23573a9438a25bd52 100644 --- a/deadlock-plugins/deadlock-extension/src/core/controller.ts +++ b/deadlock-plugins/deadlock-extension/src/core/controller.ts @@ -1,4 +1,3 @@ -import * as vscode from 'vscode'; import { KEYCLOAK_DEVICE_AUTH_URL, KEYCLOAK_TOKEN_CREATE_URL, KEYCLOAK_USER_INFO_URL } from '../config'; import BriefingView from '../view/briefingView'; import QuickSetupView from '../view/quickSetupView'; @@ -6,12 +5,13 @@ import { chooseMissionWorkdirCommand, CommandHandler, openUrlInBrowserCommand } import ExtensionStore from './extensionStore'; import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnection'; import ApiService from './api.service'; -import { createSshKeyFiles, isSshKeyPairExist } from './sshKeyManager'; import { GiteaPublicProperties } from '../model/giteaPublicProperties.model'; import { User } from '../model/user.model'; import { Mission } from './mission/mission'; import { MissionDevContainer } from './mission/missionDevContainer'; import { extensionLog as log } from '../recorder/utils/log'; +import { commands, ExtensionContext, Uri, window } from 'vscode'; +import { createSshKeyFiles, isSshKeyPairExist } from './sshKeyManager'; export default class Controller { public connection: KeycloakOAuth2DeviceFlowConnection; @@ -21,7 +21,7 @@ export default class Controller { private extensionStore: ExtensionStore; private apiService: ApiService; - constructor(private context: vscode.ExtensionContext) { + constructor(private context: ExtensionContext) { this.extensionStore = ExtensionStore.getInstance(context); this.briefingView = new BriefingView(); this.quickSetupView = new QuickSetupView(context.extensionUri); @@ -39,8 +39,8 @@ export default class Controller { private async init() { const that = this; - vscode.window.registerUriHandler({ - handleUri(uri: vscode.Uri) { + window.registerUriHandler({ + handleUri(uri: Uri) { const queryParams = new URLSearchParams(uri.query); const action = queryParams.get('action'); // TODO: Should we follow eslint no-case-declarations ? @@ -51,7 +51,7 @@ export default class Controller { switch (action) { case 'open-mission': if (!missionId || !missionVersion) { - vscode.window.showErrorMessage('Identifiant ou version de la mission incorrect'); + window.showErrorMessage('Identifiant ou version de la mission incorrect'); } else { that.launchMission(missionId, missionVersion); } @@ -59,7 +59,7 @@ export default class Controller { break; default: - vscode.window.showInformationMessage('Aucune action trouvée!'); + window.showInformationMessage('Aucune action trouvée!'); } }, }); @@ -70,8 +70,8 @@ export default class Controller { async chooseMissionWorkdir() { const actualMissionWorkDir = this.extensionStore.getMissionWorkdir(); - const folderUri = await vscode.window.showOpenDialog({ - defaultUri: actualMissionWorkDir ? vscode.Uri.file(actualMissionWorkDir) : undefined, + const folderUri = await window.showOpenDialog({ + defaultUri: actualMissionWorkDir ? Uri.file(actualMissionWorkDir) : undefined, canSelectFolders: true, canSelectFiles: false, title: 'Choisis le dossier qui contiendra tes missions', @@ -108,21 +108,21 @@ export default class Controller { } public static openBrowserWithUrl(url: string) { - vscode.commands.executeCommand(openUrlInBrowserCommand.cmd, vscode.Uri.parse(url)); + commands.executeCommand(openUrlInBrowserCommand.cmd, Uri.parse(url)); } public async launchMission(missionId: string, missionVersion: string) { - vscode.window.showInformationMessage(`vous lancez la mission ${missionId}`); + window.showInformationMessage(`vous lancez la mission ${missionId}`); const hadMissionWorkdir = this.extensionStore.getMissionWorkdir() !== undefined; if (!hadMissionWorkdir) { - await vscode.commands.executeCommand(chooseMissionWorkdirCommand.cmd); + await commands.executeCommand(chooseMissionWorkdirCommand.cmd); } const hadBeenConnected = (await this.extensionStore.getAccessToken()) !== undefined; if (!hadBeenConnected) { await this.authenticate(); - vscode.window.showInformationMessage('Connexion validée'); + window.showInformationMessage('Connexion validée'); } const mission = new Mission(missionId, missionVersion); @@ -133,7 +133,7 @@ export default class Controller { const missionDevcontainer = new MissionDevContainer(missionsWorkdir, user, mission, giteaPublicProperties); - vscode.window.showInformationMessage( + window.showInformationMessage( 'opening inside folder ' + this.extensionStore.getMissionWorkdir()! + '/' + missionId, ); diff --git a/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.test.ts b/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.test.ts index 98f98ec24c58f3f0ae012f13b319f086d0e1f207..3d97d9aaaf128e86afed34ff20533a39992a95ad 100644 --- a/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.test.ts +++ b/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.test.ts @@ -1,50 +1,60 @@ +import { Response } from 'node-fetch'; +import { KEYCLOAK_DEVICE_AUTH_URL, KEYCLOAK_TOKEN_CREATE_URL, KEYCLOAK_USER_INFO_URL } from '../config'; import KeycloakOAuth2DeviceFlowConnection from '../core/keycloakOAuth2DeviceFlowConnection'; +import { setConnected, setPending, setRefused, test_token } from '../test/service/mocks/handlers'; describe('KeycloakOAuth2DeviceFlowConnection', () => { let connection: KeycloakOAuth2DeviceFlowConnection; - let tokens: { - accessToken: string; - refreshToken: string; - }; - let refreshedTokens: { - accessToken: string; - refreshToken: string; - }; - const openLinkPlaceholder = (message: string) => console.log(message); + const log = (message: string) => console.log(`[DEADLOCK TEST] [KEYCLOAK AUTH]: ## ${message} ##`); - beforeEach(async () => { - connection = new KeycloakOAuth2DeviceFlowConnection( - 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/auth/device', - 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/token', - 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/userinfo', - ); + it('should be pending', async () => { + setPending(); + let response: Response | undefined = undefined; + await connection.getToken({ openLink: log }, true).catch(async (e) => { + response = e; + expect(response?.status).toStrictEqual(400); - tokens = await connection.getToken({ openLink: openLinkPlaceholder }); - - refreshedTokens = await connection.getToken({ - refreshToken: tokens.refreshToken, - openLink: openLinkPlaceholder, + expect(await response?.json()).toStrictEqual({ + error: 'authorization_pending', + error_description: 'The authorization request is still pending', + }); }); + expect(response).toBeInstanceOf(Response); }); - it('"12345" is not a valid token', async () => { - const isValid = await connection.tokenIsValid('12345'); - expect(isValid).toBe(false); - }); + it('should succeed', async () => { + setConnected(); + let response: Response | undefined = undefined; + await connection.getToken({ openLink: log }, true).catch(async (e) => { + response = e; + expect(response?.status).toStrictEqual(200); - it('"" is not a valid token', async () => { - const isValid = await connection.tokenIsValid(''); - expect(isValid).toBe(false); + expect(await response?.json()).toStrictEqual(test_token); + }); + expect(response).toBeInstanceOf(Response); }); - it('"accessToken" is a valid token', async () => { - const isValid = await connection.tokenIsValid(tokens.accessToken); - expect(isValid).toBe(true); + it('should failed with device not valid', async () => { + setRefused(); + let response: Response | undefined = undefined; + await connection.getToken({ openLink: log }, true).catch(async (e) => { + response = e; + expect(response?.status).toStrictEqual(400); + + expect(await response?.json()).toStrictEqual({ + error: 'invalid_grant', + error_description: 'Device code not valid', + }); + }); + expect(response).toBeInstanceOf(Response); }); - it('"refreshedAccessToken" is a valid token', async () => { - const isValid = await connection.tokenIsValid(refreshedTokens.accessToken); - expect(isValid).toBe(true); + beforeEach(async () => { + connection = new KeycloakOAuth2DeviceFlowConnection( + KEYCLOAK_DEVICE_AUTH_URL, + KEYCLOAK_TOKEN_CREATE_URL, + KEYCLOAK_USER_INFO_URL, + ); }); }); diff --git a/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.ts b/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.ts index 88d6d20f51a92ac4f5ec44445acd2f58054ac0a2..a28b7197e5a8830e73ebbec88b73e008ba59a327 100644 --- a/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.ts +++ b/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.ts @@ -66,20 +66,23 @@ export default class KeycloakOAuth2DeviceFlowConnection { } } - public async getToken(args: { refreshToken?: string; openLink?: (link: string) => void }) { + public async getToken(args: { refreshToken?: string; openLink?: (link: string) => void }, enableTest = false) { const { refreshToken, openLink } = args; if (refreshToken !== undefined) { - await this.createUserAuthentication({ - url: this.tokenUrl, - body: (() => { - const params = new URLSearchParams(); - params.append('response_type', 'token'); - params.append('client_id', 'deadlock-desktop'); - params.append('grant_type', 'refresh_token'); - params.append('refresh_token', refreshToken); - return params.toString(); - })(), - }); + await this.createUserAuthentication( + { + url: this.tokenUrl, + body: (() => { + const params = new URLSearchParams(); + params.append('response_type', 'token'); + params.append('client_id', 'deadlock-desktop'); + params.append('grant_type', 'refresh_token'); + params.append('refresh_token', refreshToken); + return params.toString(); + })(), + }, + enableTest, + ); return Promise.resolve({ accessToken: this.accessToken, refreshToken: this.refreshToken }); } if (!this.deviceIsRegistered()) { @@ -88,17 +91,20 @@ export default class KeycloakOAuth2DeviceFlowConnection { try { if (!openLink) throw new Error('You neeed to provide a way to open a link for oauth device flow protocol'); openLink(this.deviceAuthorizationRequestResponse.verification_uri_complete!); - await this.createUserAuthentication({ - url: this.tokenUrl, - body: (() => { - const params = new URLSearchParams(); - params.append('response_type', 'token'); - params.append('device_code', this.deviceAuthorizationRequestResponse.device_code ?? ''); - params.append('grant_type', 'urn:ietf:params:oauth:grant-type:device_code'); - params.append('client_id', 'deadlock-desktop'); - return params.toString(); - })(), - }); + await this.createUserAuthentication( + { + url: this.tokenUrl, + body: (() => { + const params = new URLSearchParams(); + params.append('response_type', 'token'); + params.append('device_code', this.deviceAuthorizationRequestResponse.device_code ?? ''); + params.append('grant_type', 'urn:ietf:params:oauth:grant-type:device_code'); + params.append('client_id', 'deadlock-desktop'); + return params.toString(); + })(), + }, + enableTest, + ); return Promise.resolve({ accessToken: this.accessToken, refreshToken: this.refreshToken }); } catch (error) { return Promise.reject(error); @@ -141,11 +147,13 @@ export default class KeycloakOAuth2DeviceFlowConnection { * @param args API URL endpoint to ask for a new token & request form parameters * @throw Error containing Keycloak API `error_code` */ - private async createUserAuthentication(args: { url: string; body: string }) { + private async createUserAuthentication(args: { url: string; body: string }, enableTest = false) { const { url, body } = args; let userAuthenticationRequestResponseCode = HttpStatusCode.I_AM_A_TEAPOT; while (userAuthenticationRequestResponseCode !== HttpStatusCode.OK) { log(`[POST] ${url} \n ${body}`); + console.log(body); + const userAuthenticationRequestResponse: Response = await fetch(url, { method: 'POST', headers: { @@ -156,6 +164,7 @@ export default class KeycloakOAuth2DeviceFlowConnection { }); userAuthenticationRequestResponseCode = userAuthenticationRequestResponse.status; log(` Status ${userAuthenticationRequestResponseCode}`); + if (enableTest) throw userAuthenticationRequestResponse; switch (userAuthenticationRequestResponseCode) { case HttpStatusCode.BAD_REQUEST: { await this.onUserAuthenticationBadRequest(userAuthenticationRequestResponse); diff --git a/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts b/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts index 65340b05dfd080e13a5b30b3df033b928fe15a3e..c3fdbb764f09ffa71ca1db5313e6cd09becb886a 100644 --- a/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts +++ b/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts @@ -1,32 +1,30 @@ import { existsSync, promises } from 'fs'; import { userSshKeyFolderPath } from './config'; -export default class SshKeyManager { - public isSshKeyPairExist(): boolean { - return this.isPrivateKeyExist() && this.isPublicKeyExist(); + export function isSshKeyPairExist(): boolean { + return isPrivateKeyExist() && isPublicKeyExist(); } - private isPublicKeyExist(): boolean { + function isPublicKeyExist(): boolean { return existsSync(`${userSshKeyFolderPath}/id_rsa.pub`); } - private isPrivateKeyExist(): boolean { + function isPrivateKeyExist(): boolean { return existsSync(`${userSshKeyFolderPath}/id_rsa`); } - public async createSshKeyFiles(publicKey: string, privateKey: string) { - await this.createSshKeyFolderIfNotExist(userSshKeyFolderPath); + export async function createSshKeyFiles(publicKey: string, privateKey: string) { + await createSshKeyFolderIfNotExist(userSshKeyFolderPath); await promises.writeFile(`${userSshKeyFolderPath}/id_rsa.pub`, publicKey); await promises.writeFile(`${userSshKeyFolderPath}/id_rsa`, privateKey, { mode: 0o600 }); } - private async createSshKeyFolderIfNotExist(sshKeyFolderPath) { - if (!this.isSshKeyFolderExist(sshKeyFolderPath)) { + async function createSshKeyFolderIfNotExist(sshKeyFolderPath) { + if (!isSshKeyFolderExist(sshKeyFolderPath)) { await promises.mkdir(sshKeyFolderPath, { recursive: true }); } } - private isSshKeyFolderExist(sshKeyFolderPath: string) { + export function isSshKeyFolderExist(sshKeyFolderPath: string) { return existsSync(sshKeyFolderPath); } -} diff --git a/deadlock-plugins/deadlock-extension/src/extension.ts b/deadlock-plugins/deadlock-extension/src/extension.ts index 4a921731800436360ea2b309e4bc610b57398999..15a2cf75af6c192e1a7b833f1c6a3d3919276fcc 100644 --- a/deadlock-plugins/deadlock-extension/src/extension.ts +++ b/deadlock-plugins/deadlock-extension/src/extension.ts @@ -1,4 +1,4 @@ -import * as vscode from 'vscode'; +import { window, ExtensionContext, workspace } from 'vscode'; import Controller from './core/controller'; import { extensionError as error } from './recorder/utils/log'; import { DepNodeProvider } from './theia/deadlockPanel'; @@ -6,15 +6,15 @@ import UserConfigTheia from './theia/userConfigTheia'; export const userConfig = new UserConfigTheia(); -export async function activate(context: vscode.ExtensionContext) { - vscode.window.showInformationMessage('Bienvenue sur Deadlock!'); +export async function activate(context: ExtensionContext) { + window.showInformationMessage('Bienvenue sur Deadlock!'); new Controller(context); - const workspaceFolders = vscode.workspace.workspaceFolders?.toString() ?? ''; - if (!workspaceFolders) vscode.window.showInformationMessage('Pas de répertoires ouverts'); + const workspaceFolders = workspace.workspaceFolders?.toString() ?? ''; + if (!workspaceFolders) window.showInformationMessage('Pas de répertoires ouverts'); const deadlockPanelProvider = new DepNodeProvider(workspaceFolders); - vscode.window.registerTreeDataProvider('deadlockPanel', deadlockPanelProvider); + window.registerTreeDataProvider('deadlockPanel', deadlockPanelProvider); try { await userConfig.init(); diff --git a/deadlock-plugins/deadlock-extension/src/test/service/mocks/handlers.ts b/deadlock-plugins/deadlock-extension/src/test/service/mocks/handlers.ts new file mode 100644 index 0000000000000000000000000000000000000000..906b8a0d2753f10415bcbc2a5432c8e4c07135f3 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/test/service/mocks/handlers.ts @@ -0,0 +1,113 @@ +import { rest } from 'msw'; + +export const test_token = { + access_token: + 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ4MjdZYW5fWllISElSclJiUDlnenFFSHhMbm5RMUNUaUNqenZTY19hUFpRIn0.eyJleHAiOjE2NTQ3OTg0MzQsImlhdCI6MTY1NDc2MjkwNCwiYXV0aF90aW1lIjoxNjU0NzYyNDM0LCJqdGkiOiJiNmM3MDJhOS0wYzgzLTQwYTUtODRlNS05ZGY4YmIxMzBhNjEiLCJpc3MiOiJodHRwczovL2F1dGguZGV2LmRlYWRsb2NrLmlvL2F1dGgvcmVhbG1zL0RlYWRsb2NrIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6ImEzOTRiM2IxLTQxZmEtNGNiZS1iZGVkLTExNTcyNDBmOTI0ZSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImRlYWRsb2NrLWRlc2t0b3AiLCJzZXNzaW9uX3N0YXRlIjoiYTkwMWZlOGUtZTY2Yy00NTQxLWI1MDEtM2YzM2EwNDhlYjg1IiwiYWNyIjoiMCIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLWRlYWRsb2NrIiwicHJvZmVzc29yIiwiY2FuZGlkYXRlIiwibWFuYWdlciIsIm9mZmxpbmVfYWNjZXNzIiwiYWRtaW4iLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6ImE5MDFmZThlLWU2NmMtNDU0MS1iNTAxLTNmMzNhMDQ4ZWI4NSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6Ik1vaGFtZWQgQVpJS0lPVSIsInByZWZlcnJlZF91c2VybmFtZSI6Im1hemlraW91QHRha2ltYS5mciIsImdpdmVuX25hbWUiOiJNb2hhbWVkIiwiZmFtaWx5X25hbWUiOiJBWklLSU9VIiwiZW1haWwiOiJtYXppa2lvdUB0YWtpbWEuZnIifQ.UZDq12D6HVkseSotAC_kCEBpx7jqyndHO7-WEd3MslJKz_O1F8phrZO_zvEhYaZ_DO2yWQJFPeHYyMcNMFXsM1COfvpT-KZV3a4LXQNstDP7Eyqw-VzGpOUIaY4NZDI-2HgkclB3o5lnwdmzn9TBTE0LGZ2Pkz4j0_giC7R161RP2w4vqhL-VwC19OBlwqvqiIT-Rhj7IeQabj1MCJyQR-ocWwh8ensSdd1_sptz4J7YKxqzpw2eFVEWIaWcxKu7mSD5uU7teNRTlRoDOuJKXBTqzsjYV4A3CB0_m6cRkRj7zgxPfxJtdL0jFAKvZEykS6DINVvZSz-QS_3ROdO1uA', + expires_in: 35530, + refresh_expires_in: 1800, + refresh_token: + 'eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjNzc3MGE3Yy01NTg0LTQxOWUtYWU3OS05ZjgxNGE2NWEwMWIifQ.eyJleHAiOjE2NTQ3NjQ3MDQsImlhdCI6MTY1NDc2MjkwNCwianRpIjoiNWUwZjk2NWYtZGFlNy00ZGZmLWJmMjctMWFiY2IyN2YzNGRhIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLmRldi5kZWFkbG9jay5pby9hdXRoL3JlYWxtcy9EZWFkbG9jayIsImF1ZCI6Imh0dHBzOi8vYXV0aC5kZXYuZGVhZGxvY2suaW8vYXV0aC9yZWFsbXMvRGVhZGxvY2siLCJzdWIiOiJhMzk0YjNiMS00MWZhLTRjYmUtYmRlZC0xMTU3MjQwZjkyNGUiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiZGVhZGxvY2stZGVza3RvcCIsInNlc3Npb25fc3RhdGUiOiJhOTAxZmU4ZS1lNjZjLTQ1NDEtYjUwMS0zZjMzYTA0OGViODUiLCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJzaWQiOiJhOTAxZmU4ZS1lNjZjLTQ1NDEtYjUwMS0zZjMzYTA0OGViODUifQ.01pGEulqMn3VIvOFAAj2AJn7uJGhf586cWRz0dzHb9w', + token_type: 'Bearer', + 'not-before-policy': 0, + session_state: 'a901fe8e-e66c-4541-b501-3f33a048eb85', + scope: 'profile email', +}; + +const device_codes = { + pending_device_code: 'ePutZ5EuR2zdrUwsBvp6b7hHb_qXK_F82N-bQPo4Q28', + connected_device_code: 'ePutZ5EuR2zdrUwsBvp6b7hHb_qXK_F82N-bQPo4Q29', + refused_device_code: 'ePutZ5EuR2zdrUwsBvp6b7hHb_qXK_F82N-bQPo4Q30', +}; + +enum State { + Pending, + Connected, + Refused, +} + +let state = State.Pending; + +function getDeviceCode() { + switch (state) { + case State.Pending: + return device_codes.pending_device_code; + case State.Connected: + return device_codes.connected_device_code; + case State.Refused: + return device_codes.refused_device_code; + } +} + +export function setPending() { + state = State.Pending; +} + +export function setConnected() { + state = State.Connected; +} + +export function setRefused() { + state = State.Refused; +} + +function mockCreateDeviceAuthorization() { + return rest.post( + 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/auth/device', + (req, res, ctx) => { + if (req.body === 'client_id=deadlock-desktop') + return res( + ctx.status(200), + ctx.json({ + device_code: getDeviceCode(), + user_code: 'DHTJ-BJBF', + verification_uri: 'https://auth.dev.deadlock.io/auth/realms/Deadlock/device', + verification_uri_complete: 'https://auth.dev.deadlock.io/auth/realms/Deadlock/device?user_code=DHTJ-BJBF', + expires_in: 2592000, + interval: 1, + }), + ); + }, + ); +} + +function createUrlSearchParams(device_code: string) { + const params = new URLSearchParams(); + params.append('response_type', 'token'); + params.append('device_code', device_code); + params.append('grant_type', 'urn:ietf:params:oauth:grant-type:device_code'); + params.append('client_id', 'deadlock-desktop'); + return params; +} + +function mockCreateUserAuthenticationPending() { + const pending = createUrlSearchParams(device_codes.pending_device_code).toString(); + const connected = createUrlSearchParams(device_codes.connected_device_code).toString(); + const refused = createUrlSearchParams(device_codes.refused_device_code).toString(); + return rest.post( + 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/token', + (req, res, ctx) => { + switch (req.body) { + case pending: + return res( + ctx.status(400), + ctx.json({ + error: 'authorization_pending', + error_description: 'The authorization request is still pending', + }), + ); + case connected: + return res(ctx.status(200), ctx.json(test_token)); + case refused: + return res( + ctx.status(400), + ctx.json({ + error: 'invalid_grant', + error_description: 'Device code not valid', + }), + ); + } + }, + ); +} + +export const handlers = [mockCreateDeviceAuthorization(), mockCreateUserAuthenticationPending()]; diff --git a/deadlock-plugins/deadlock-extension/src/test/service/mocks/server.ts b/deadlock-plugins/deadlock-extension/src/test/service/mocks/server.ts new file mode 100644 index 0000000000000000000000000000000000000000..e52fee0a675d45a7f1764f35fa95905f9b32a09d --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/test/service/mocks/server.ts @@ -0,0 +1,4 @@ +import { setupServer } from 'msw/node'; +import { handlers } from './handlers'; + +export const server = setupServer(...handlers); diff --git a/deadlock-plugins/deadlock-extension/src/test/setupTests.ts b/deadlock-plugins/deadlock-extension/src/test/setupTests.ts new file mode 100644 index 0000000000000000000000000000000000000000..b4874d6d20ddfc0a1b36231f9336ede8e434fba7 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/test/setupTests.ts @@ -0,0 +1,5 @@ +import { server } from './service/mocks/server'; + +beforeAll(() => server.listen()); +afterEach(() => server.resetHandlers()); +afterAll(() => server.close()); diff --git a/deadlock-plugins/deadlock-extension/src/theia/deadlockPanel.ts b/deadlock-plugins/deadlock-extension/src/theia/deadlockPanel.ts index b687e753ad290ba5b8c448b0ac70e388535d1273..3c81acd897012f29e75361013e32d6264755d3ae 100644 --- a/deadlock-plugins/deadlock-extension/src/theia/deadlockPanel.ts +++ b/deadlock-plugins/deadlock-extension/src/theia/deadlockPanel.ts @@ -1,16 +1,13 @@ -import * as path from 'path'; -import * as vscode from 'vscode'; -import { TreeItemCollapsibleState } from 'vscode'; +import { join } from 'path'; +import { Command, Event, EventEmitter, TreeDataProvider, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { openBriefingCommand } from './command'; const documentationLabel = 'Documentation'; -export class DepNodeProvider implements vscode.TreeDataProvider<Action> { - private _onDidChangeTreeData: vscode.EventEmitter<Action | undefined | void> = new vscode.EventEmitter< - Action | undefined | void - >(); +export class DepNodeProvider implements TreeDataProvider<Action> { + private _onDidChangeTreeData: EventEmitter<Action | undefined | void> = new EventEmitter<Action | undefined | void>(); - readonly onDidChangeTreeData: vscode.Event<Action | undefined | void> = this._onDidChangeTreeData.event; + readonly onDidChangeTreeData: Event<Action | undefined | void> = this._onDidChangeTreeData.event; constructor(private workspaceRoot: string) {} @@ -22,7 +19,7 @@ export class DepNodeProvider implements vscode.TreeDataProvider<Action> { return [new Action(documentationLabel, TreeItemCollapsibleState.Collapsed, 'folder')]; } - getTreeItem(element: Action): vscode.TreeItem { + getTreeItem(element: Action): TreeItem { return element; } @@ -39,12 +36,12 @@ export class DepNodeProvider implements vscode.TreeDataProvider<Action> { } } -export class Action extends vscode.TreeItem { +export class Action extends TreeItem { constructor( public readonly label: string, - public readonly collapsibleState: vscode.TreeItemCollapsibleState, + public readonly collapsibleState: TreeItemCollapsibleState, public readonly iconName: string, - public readonly command?: vscode.Command, + public readonly command?: Command, ) { super(label, collapsibleState); this.tooltip = label; @@ -52,8 +49,8 @@ export class Action extends vscode.TreeItem { } iconPath = { - light: path.join(__filename, '..', '..', 'resources', 'light', `${this.iconName}.svg`), - dark: path.join(__filename, '..', '..', 'resources', 'dark', `${this.iconName}.svg`), + light: join(__filename, '..', '..', 'resources', 'light', `${this.iconName}.svg`), + dark: join(__filename, '..', '..', 'resources', 'dark', `${this.iconName}.svg`), }; contextValue = 'dependency'; diff --git a/deadlock-plugins/deadlock-extension/src/theia/userConfigTheia.ts b/deadlock-plugins/deadlock-extension/src/theia/userConfigTheia.ts index 387a808962c71036b199aac2b2e63ce5d078eeee..7bdeb915facb96639e2e930c77673648772f627d 100644 --- a/deadlock-plugins/deadlock-extension/src/theia/userConfigTheia.ts +++ b/deadlock-plugins/deadlock-extension/src/theia/userConfigTheia.ts @@ -1,11 +1,11 @@ import UserConfig from '../core/userConfig'; -import * as vscode from 'vscode'; import { USER_CHALLENGE_PATH } from '../core/config'; +import { Uri, workspace } from 'vscode'; export default class UserConfigTheia extends UserConfig { async loadText(): Promise<string> { - const textDocument = await vscode.workspace.openTextDocument(vscode.Uri.parse(USER_CHALLENGE_PATH)); + const textDocument = await workspace.openTextDocument(Uri.parse(USER_CHALLENGE_PATH)); return Promise.resolve(textDocument.getText()); } } diff --git a/deadlock-plugins/deadlock-extension/src/view/quickSetupView.ts b/deadlock-plugins/deadlock-extension/src/view/quickSetupView.ts index f0e004b58dea0fe22fd8736c4116af8dc5d84763..a87f244bd0578fcadd44a99c1c3d1471b2763a3e 100644 --- a/deadlock-plugins/deadlock-extension/src/view/quickSetupView.ts +++ b/deadlock-plugins/deadlock-extension/src/view/quickSetupView.ts @@ -1,4 +1,4 @@ -import * as vscode from 'vscode'; +import { commands, Uri } from 'vscode'; import { authenticateCommand, chooseMissionWorkdirCommand } from '../core/commandHandler'; import ExtensionStore from '../core/extensionStore'; import { extensionLog as log } from '../recorder/utils/log'; @@ -8,11 +8,11 @@ import { WebviewBase } from './webviewBase'; export const quickSetupId = 'quickSetup'; export default class QuickSetupView extends WebviewBase { - private extensionUri: vscode.Uri; + private extensionUri: Uri; private extensionStore: ExtensionStore; private _isAlreadyConnected: boolean; - constructor(extensionUri: vscode.Uri) { + constructor(extensionUri: Uri) { super(quickSetupId, 'QuickSetup', openQuickSetupCommand); this.extensionUri = extensionUri; this.extensionStore = ExtensionStore.getInstance(); @@ -121,10 +121,10 @@ export default class QuickSetupView extends WebviewBase { onMessageReceive(message: any): void { switch (message.command) { case 'launchChooseMissionWorkdirAction': - vscode.commands.executeCommand(chooseMissionWorkdirCommand.cmd).then(() => this.reload()); + commands.executeCommand(chooseMissionWorkdirCommand.cmd).then(() => this.reload()); return; case 'openAuthenticationPageAction': - vscode.commands.executeCommand(authenticateCommand.cmd); + commands.executeCommand(authenticateCommand.cmd); return; } } diff --git a/deadlock-plugins/deadlock-extension/src/view/view.ts b/deadlock-plugins/deadlock-extension/src/view/view.ts index f4851a03f018bea847f8ad9a58369fd65f29bd5b..53c17be43fd9580319de633d2b5662c9cd38e2e6 100644 --- a/deadlock-plugins/deadlock-extension/src/view/view.ts +++ b/deadlock-plugins/deadlock-extension/src/view/view.ts @@ -1,4 +1,4 @@ -import * as vscode from 'vscode'; +import { Disposable, ExtensionContext, ViewColumn, WebviewPanel, window } from 'vscode'; /** * @deprecated use #webviewBase instead of @@ -6,13 +6,13 @@ import * as vscode from 'vscode'; export default abstract class View { private static views: Map<string, View> = new Map(); - public currentWebviewPanel: vscode.WebviewPanel | undefined; - private _disposables: vscode.Disposable[] = []; + public currentWebviewPanel: WebviewPanel | undefined; + private _disposables: Disposable[] = []; private isRegisteredOnWebviewPanelSerializer: boolean; constructor( id: string, - private readonly context: vscode.ExtensionContext, + private readonly context: ExtensionContext, public readonly panelName: string, public readonly title: string, ) { @@ -59,7 +59,7 @@ export default abstract class View { (message) => { switch (message.command) { case 'alert': - vscode.window.showErrorMessage(message.text); + window.showErrorMessage(message.text); return; } }, @@ -73,7 +73,7 @@ export default abstract class View { } public createOrShow() { - const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined; + const column = window.activeTextEditor ? window.activeTextEditor.viewColumn : undefined; // If we already have a panel, show it. if (this.currentWebviewPanel) { @@ -82,21 +82,16 @@ export default abstract class View { } // Otherwise, create a new panel. - this.currentWebviewPanel = vscode.window.createWebviewPanel( - this.panelName, - this.title, - column || vscode.ViewColumn.One, - { - // Enable javascript in the webview - enableScripts: true, - - // And restrict the webview to only loading content from our extension's `media` directory. - // for now we don't need to include the media folder, because React bundle is not used - // localResourceRoots: [ - // vscode.Uri.file(path.join(this.extensionPath, 'media')), - // ], - }, - ); + this.currentWebviewPanel = window.createWebviewPanel(this.panelName, this.title, column || ViewColumn.One, { + // Enable javascript in the webview + enableScripts: true, + + // And restrict the webview to only loading content from our extension's `media` directory. + // for now we don't need to include the media folder, because React bundle is not used + // localResourceRoots: [ + // Uri.file(path.join(this.extensionPath, 'media')), + // ], + }); // update first time to force render of webviewPanel this.update(); this.init(this.currentWebviewPanel); @@ -136,10 +131,10 @@ export default abstract class View { private _getHtmlForWebview() { // /!\ EXPERIMENTAL /!\ // Local path to main script run in the webview - // const scriptPathOnDisk = vscode.Uri.file( + // const scriptPathOnDisk = Uri.file( // path.join(this.extensionPath, 'media', 'static/bundle.js') // ); - // const cssPathOnDisk = vscode.Uri.file( + // const cssPathOnDisk = Uri.file( // path.join(this.extensionPath, 'media', 'static/bundle.css') // ); diff --git a/deadlock-plugins/deadlock-extension/tsconfig.json b/deadlock-plugins/deadlock-extension/tsconfig.json index 966fc64063ec02c63101db508a26c4422718980c..c55dd0732ba4570efc8b0e17db5fd373fecb7745 100644 --- a/deadlock-plugins/deadlock-extension/tsconfig.json +++ b/deadlock-plugins/deadlock-extension/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es2019", - "lib": ["ES2019"], + "lib": ["ES2019", "dom"], "sourceMap": true, "outDir": "dist", "strict": true,