diff --git a/package-lock.json b/package-lock.json index 2cb5caed..d908b443 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,12 +13,12 @@ "@vscode/debugadapter": "^1.61.0", "@vscode/debugprotocol": "^1.61.0", "@xmldom/xmldom": "^0.8.8", + "axios": "^1.7.7", "core-js": "^3.6.5", "iconv-lite": "^0.6.0", "istextorbinary": "^6.0.0", "minimatch": "^9.0.3", "node-cmd": "^5.0.0", - "node-fetch-cjs": "^3.3.2", "vscode-cache": "^0.3.0", "vscode-extension-telemetry": "^0.1.6", "ws": "^8.14.2" @@ -27,7 +27,7 @@ "@types/istextorbinary": "2.3.1", "@types/minimatch": "5.1.2", "@types/mocha": "^7.0.2", - "@types/node": "^14.18.0", + "@types/node": "20.16.5", "@types/semver": "7.5.4", "@types/vscode": "1.91.0", "@types/ws": "8.5.4", @@ -49,7 +49,7 @@ "path-browserify": "^1.0.1", "prettier": "^2.0.5", "ts-loader": "^7.0.5", - "typescript": "^4.4.3", + "typescript": "^5.5.4", "vscode-debugadapter-testsupport": "^1.41.0", "webpack": "^5.94.0", "webpack-cli": "^4.5.0" @@ -410,10 +410,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "14.18.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.0.tgz", - "integrity": "sha512-0GeIl2kmVMXEnx8tg1SlG6Gg8vkqirrW752KqolYo1PHevhhZN3bhJ67qHj+bQaINhX0Ra3TlWwRvMCd9iEfNQ==", - "dev": true + "version": "20.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", + "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@types/semver": { "version": "7.5.4", @@ -1140,6 +1143,11 @@ "semver": "bin/semver" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/axe-core": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz", @@ -1149,6 +1157,16 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -1431,6 +1449,17 @@ "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -1552,6 +1581,14 @@ "node": ">= 0.4" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/diagnostic-channel": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", @@ -2406,6 +2443,38 @@ "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3454,7 +3523,6 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -3463,7 +3531,6 @@ "version": "2.1.34", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, "dependencies": { "mime-db": "1.51.0" }, @@ -3745,19 +3812,6 @@ "node": ">=6.4.0" } }, - "node_modules/node-fetch-cjs": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch-cjs/-/node-fetch-cjs-3.3.2.tgz", - "integrity": "sha512-JvvyTiDcLnHvPmbxj6uxj4LaamCfZLlzlRNBZp+H82ECMLz4OQjI9Jc6YjjjycipeMk1Aq4xo90ejEUMKJeTjw==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", @@ -4083,6 +4137,11 @@ "node": ">= 6" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -4919,16 +4978,16 @@ } }, "node_modules/typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { @@ -4946,6 +5005,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, "node_modules/update-browserslist-db": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", @@ -5662,10 +5727,13 @@ "dev": true }, "@types/node": { - "version": "14.18.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.0.tgz", - "integrity": "sha512-0GeIl2kmVMXEnx8tg1SlG6Gg8vkqirrW752KqolYo1PHevhhZN3bhJ67qHj+bQaINhX0Ra3TlWwRvMCd9iEfNQ==", - "dev": true + "version": "20.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", + "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", + "dev": true, + "requires": { + "undici-types": "~6.19.2" + } }, "@types/semver": { "version": "7.5.4", @@ -6214,12 +6282,27 @@ } } }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "axe-core": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz", "integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==", "dev": true }, + "axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -6411,6 +6494,14 @@ "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -6502,6 +6593,11 @@ "object-keys": "^1.0.12" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, "diagnostic-channel": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", @@ -7164,6 +7260,21 @@ "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", "dev": true }, + "follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7922,14 +8033,12 @@ "mime-db": { "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" }, "mime-types": { "version": "2.1.34", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, "requires": { "mime-db": "1.51.0" } @@ -8134,11 +8243,6 @@ "resolved": "https://registry.npmjs.org/node-cmd/-/node-cmd-5.0.0.tgz", "integrity": "sha512-4sQTJmsS5uZKAPz/Df9fnIbmvOySfGdW+UreH4X5NcAOOpKjaE+K5wf4ehNBbZVPo0vQ36RkRnhhsXXJAT+Syw==" }, - "node-fetch-cjs": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch-cjs/-/node-fetch-cjs-3.3.2.tgz", - "integrity": "sha512-JvvyTiDcLnHvPmbxj6uxj4LaamCfZLlzlRNBZp+H82ECMLz4OQjI9Jc6YjjjycipeMk1Aq4xo90ejEUMKJeTjw==" - }, "node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", @@ -8377,6 +8481,11 @@ "sisteransi": "^1.0.5" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -8989,9 +9098,9 @@ "dev": true }, "typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true }, "unbox-primitive": { @@ -9006,6 +9115,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, "update-browserslist-db": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", diff --git a/package.json b/package.json index 0f02a80a..08705da5 100644 --- a/package.json +++ b/package.json @@ -1822,7 +1822,7 @@ "@types/istextorbinary": "2.3.1", "@types/minimatch": "5.1.2", "@types/mocha": "^7.0.2", - "@types/node": "^14.18.0", + "@types/node": "20.16.5", "@types/semver": "7.5.4", "@types/vscode": "1.91.0", "@types/ws": "8.5.4", @@ -1844,22 +1844,22 @@ "path-browserify": "^1.0.1", "prettier": "^2.0.5", "ts-loader": "^7.0.5", - "typescript": "^4.4.3", + "typescript": "^5.5.4", "vscode-debugadapter-testsupport": "^1.41.0", "webpack": "^5.94.0", "webpack-cli": "^4.5.0" }, "dependencies": { + "@vscode/debugadapter": "^1.61.0", + "@vscode/debugprotocol": "^1.61.0", "@xmldom/xmldom": "^0.8.8", + "axios": "^1.7.7", "core-js": "^3.6.5", "iconv-lite": "^0.6.0", "istextorbinary": "^6.0.0", "minimatch": "^9.0.3", "node-cmd": "^5.0.0", - "node-fetch-cjs": "^3.3.2", "vscode-cache": "^0.3.0", - "@vscode/debugadapter": "^1.61.0", - "@vscode/debugprotocol": "^1.61.0", "vscode-extension-telemetry": "^0.1.6", "ws": "^8.14.2" }, diff --git a/src/api/index.ts b/src/api/index.ts index cc56c3ee..ebd55406 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,7 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { default: fetch } = require("node-fetch-cjs"); - -import * as httpModule from "http"; +import axios from "axios"; import * as httpsModule from "https"; import * as vscode from "vscode"; import * as Cache from "vscode-cache"; @@ -41,9 +38,16 @@ export interface ConnectionSettings { dockerService?: string; } +// Needed to fix a TS error +declare let AbortSignal: { + prototype: AbortSignal; + new (): AbortSignal; + abort(reason?: any): AbortSignal; + timeout(milliseconds: number): AbortSignal; +}; + export class AtelierAPI { private _config: ConnectionSettings; - private _agent?: httpModule.Agent | httpsModule.Agent; private namespace: string; public configName: string; @@ -302,20 +306,10 @@ export class AtelierAPI { } headers["Cache-Control"] = "no-cache"; - const proto = this._config.https ? "https" : "http"; - const http = this._config.https ? httpsModule : httpModule; - if (!this._agent) { - this._agent = new http.Agent({ - /* VS Code 1.93 adopted a version of vscode-proxy-agent that fixed a failure to pass-through the keepAlive option (see https://github.com/microsoft/vscode/issues/173861 and https://github.com/microsoft/vscode-proxy-agent/commit/4eddc930d4fbc6b88ca5557ea7af07d623d390d6) - * This caused poor performance on some operations by our extension (see https://github.com/intersystems-community/vscode-objectscript/issues/1428) - * Short term solution adopted by PR https://github.com/intersystems-community/vscode-objectscript/pull/1432 is not to enable keepAlive - * We should revisit this in the future - TODO - */ - //keepAlive: true, - //maxSockets: 10, - rejectUnauthorized: https && vscode.workspace.getConfiguration("http").get("proxyStrictSSL"), - }); - } + const proto = https ? "https" : "http"; + const httpsAgent = new httpsModule.Agent({ + rejectUnauthorized: vscode.workspace.getConfiguration("http").get("proxyStrictSSL"), + }); let pathPrefix = this._config.pathPrefix || ""; if (pathPrefix.length && !pathPrefix.startsWith("/")) { @@ -346,14 +340,19 @@ export class AtelierAPI { try { const cookie = await auth; - const response = await fetch(`${proto}://${host}:${port}${path}`, { + const response = await axios.request({ method, - agent: this._agent, - body: body ? (typeof body !== "string" ? JSON.stringify(body) : body) : null, + url: `${proto}://${host}:${port}${path}`, headers: { ...headers, Cookie: cookie, }, + data: body, + withCredentials: true, + httpsAgent, + timeout: options?.timeout ? options.timeout : 0, + signal: options?.timeout ? AbortSignal.timeout(options.timeout) : undefined, + validateStatus: (status) => status < 504, }); if (response.status === 503) { // User likely ran out of licenses @@ -376,7 +375,7 @@ export class AtelierAPI { } throw { statusCode: response.status, message: response.statusText }; } - await this.updateCookies(response.headers.raw()["set-cookie"] || []); + await this.updateCookies(response.headers["set-cookie"] || []); if (method === "HEAD") { if (!originalPath) { authRequestMap.delete(target); @@ -386,7 +385,7 @@ export class AtelierAPI { throw { statusCode: response.status, message: response.statusText, errorText: "" }; } else { // The HEAD /doc request succeeded - return response.headers.get("ETAG"); + return response.headers["etag"]; } } @@ -395,17 +394,14 @@ export class AtelierAPI { throw { statusCode: response.status, message: response.statusText }; } - const responseString = new TextDecoder().decode(await response.arrayBuffer()); - let data: Atelier.Response; - try { - data = JSON.parse(responseString); - } catch { + if (typeof response.data != "object") { throw { statusCode: response.status, message: response.statusText, errorText: `Non-JSON response to ${path} request. Is the web server suppressing detailed errors?`, }; } + const data: Atelier.Response = response.data; // Decode encoded content if (data.result && data.result.enc && data.result.content) { @@ -444,11 +440,11 @@ export class AtelierAPI { // Handle headers for the /work endpoints by storing the header values in the result object if (originalPath && originalPath.endsWith("/work") && method == "POST") { // This is a POST /work request, so we need to get the Location header - data.result.location = response.headers.get("Location"); + data.result.location = response.headers["location"]; } else if (originalPath && /^[^/]+\/work\/[^/]+$/.test(originalPath)) { // This is a GET or DELETE /work request, so we need to check the Retry-After header - if (response.headers.has("Retry-After")) { - data.retryafter = response.headers.get("Retry-After"); + if (response.headers["retry-after"]) { + data.retryafter = response.headers["retry-after"]; } } @@ -459,7 +455,7 @@ export class AtelierAPI { // In some cases schedule an automatic retry. // ENOTFOUND occurs if, say, the VPN to the server's network goes down. - if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") { + if (["ECONNREFUSED", "ENOTFOUND", "ECONNABORTED", "ERR_CANCELED"].includes(error.code)) { panel.text = `${this.connInfo} $(debug-disconnect)`; panel.tooltip = "Disconnected"; workspaceState.update(this.configName.toLowerCase() + ":host", undefined); @@ -472,8 +468,8 @@ export class AtelierAPI { } } - public serverInfo(checkNs = true): Promise>> { - return this.request(0, "GET").then((info) => { + public serverInfo(checkNs = true, timeout?: number): Promise>> { + return this.request(0, "GET", undefined, undefined, undefined, undefined, { timeout }).then((info) => { if (info && info.result && info.result.content && info.result.content.api > 0) { const data = info.result.content; const apiVersion = data.api; diff --git a/src/commands/restDebugPanel.ts b/src/commands/restDebugPanel.ts index e8e6a510..045af2ee 100644 --- a/src/commands/restDebugPanel.ts +++ b/src/commands/restDebugPanel.ts @@ -1,6 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { default: fetch } = require("node-fetch-cjs"); -import * as httpModule from "http"; +import axios from "axios"; import * as httpsModule from "https"; import * as vscode from "vscode"; @@ -423,28 +421,31 @@ export class RESTDebugPanel { break; } } - const agent = new (api.config.https ? httpsModule : httpModule).Agent({ - keepAlive: true, - maxSockets: 10, - rejectUnauthorized: api.config.https && vscode.workspace.getConfiguration("http").get("proxyStrictSSL"), + const httpsAgent = new httpsModule.Agent({ + rejectUnauthorized: vscode.workspace.getConfiguration("http").get("proxyStrictSSL"), }); // Send the request - fetch(`${encodeURI(`${serverInfo}${message.webApp}${path}`)}?${urlParams.toString()}`, { - method: message.method, - agent, - body: hasBody ? message.bodyContent : undefined, - headers, - }).catch((error) => { - outputChannel.appendLine( - typeof error == "string" ? error : error instanceof Error ? error.message : JSON.stringify(error) - ); - vscode.window.showErrorMessage( - "Failed to send debuggee REST request. Check 'ObjectScript' Output channel for details.", - "Dismiss" - ); - vscode.debug.stopDebugging(vscode.debug.activeDebugSession); - }); + axios + .request({ + method: message.method, + url: `${encodeURI(`${serverInfo}${message.webApp}${path}`)}?${urlParams.toString()}`, + headers, + data: hasBody ? message.bodyContent : undefined, + withCredentials: true, + httpsAgent, + validateStatus: undefined, // Only reject if we didn't get a response + }) + .catch((error) => { + outputChannel.appendLine( + typeof error == "string" ? error : error instanceof Error ? error.message : JSON.stringify(error) + ); + vscode.window.showErrorMessage( + "Failed to send debuggee REST request. Check 'ObjectScript' Output channel for details.", + "Dismiss" + ); + vscode.debug.stopDebugging(vscode.debug.activeDebugSession); + }); // Wait 500ms to allow the server to associate this request with the CSDPDEBUG id await new Promise((resolve) => setTimeout(resolve, 500)); diff --git a/src/extension.ts b/src/extension.ts index 282ee401..bbcf17a4 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -381,8 +381,9 @@ export async function checkConnection( }; // Do the check + const serverInfoTimeout = 5000; return api - .serverInfo() + .serverInfo(true, serverInfoTimeout) .then(gotServerInfo) .catch(async (error) => { let message = error.message; @@ -416,7 +417,7 @@ export async function checkConnection( }); api = new AtelierAPI(apiTarget, false); await api - .serverInfo() + .serverInfo(true, serverInfoTimeout) .then(async (info) => { await gotServerInfo(info); _onDidChangeConnection.fire(); @@ -450,7 +451,7 @@ export async function checkConnection( await workspaceState.update(wsKey + ":password", password); resolve( api - .serverInfo() + .serverInfo(true, serverInfoTimeout) .then(async (info): Promise => { await gotServerInfo(info); _onDidChangeConnection.fire(); diff --git a/src/providers/FileSystemProvider/FileSystemProvider.ts b/src/providers/FileSystemProvider/FileSystemProvider.ts index a9a8ed55..935d4d74 100644 --- a/src/providers/FileSystemProvider/FileSystemProvider.ts +++ b/src/providers/FileSystemProvider/FileSystemProvider.ts @@ -25,8 +25,6 @@ import { addIsfsFileToProject, modifyProject } from "../../commands/project"; import { DocumentContentProvider } from "../DocumentContentProvider"; import { Document, UserAction } from "../../api/atelier"; -declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timeout; - export type Entry = File | Directory; export function generateFileContent( @@ -174,7 +172,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider { private _emitter = new vscode.EventEmitter(); private _bufferedEvents: vscode.FileChangeEvent[] = []; - private _fireSoonHandle?: NodeJS.Timer; + private _fireSoonHandle?: NodeJS.Timeout; public constructor() { this.onDidChangeFile = this._emitter.event; diff --git a/src/providers/FileSystemProvider/TextSearchProvider.ts b/src/providers/FileSystemProvider/TextSearchProvider.ts index ff61554b..71785176 100644 --- a/src/providers/FileSystemProvider/TextSearchProvider.ts +++ b/src/providers/FileSystemProvider/TextSearchProvider.ts @@ -89,7 +89,7 @@ function searchMatchToLine( line = memend + (match.attrline ?? 1); } else { // This is a keyword with a multiline value - line = i + (match.attrline - 1 ?? 0); + line = i + (match.attrline - 1 || 0); } } else { // This is in the class member definition