diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 84b03d1e..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - root: true, - env: { - node: true, - }, - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], - rules: { - semi: ['error', 'always'], - quotes: ['error', 'single', {'avoidEscape': true, 'allowTemplateLiterals': true}], - 'no-empty': ['error', { 'allowEmptyCatch': true }], - 'comma-dangle': ['error', 'always-multiline'], - 'max-len': ['error', {'code': 180, 'tabWidth': 2}], - '@typescript-eslint/ban-ts-comment': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-namespace': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - }, -}; diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 29c809ec..00ee9916 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -24,7 +24,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v3 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java @@ -32,7 +32,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v3 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -46,4 +46,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v3 diff --git a/.npmignore b/.npmignore index ef11d88c..0a36a68f 100644 --- a/.npmignore +++ b/.npmignore @@ -16,3 +16,4 @@ build_server.sh diff.mjs esbuild.mjs justfile +biome.json diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..4afd7c0a --- /dev/null +++ b/biome.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json", + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 120 + }, + "javascript": { + "formatter": { + "quoteStyle": "single" + } + }, + "organizeImports": { + "enabled": false + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "complexity": { + "useLiteralKeys": "off" + }, + "style": { + "useNumberNamespace": "off", + "noNonNullAssertion": "off" + }, + "suspicious": { + "noExplicitAny": "off" + } + } + } +} diff --git a/package-lock.json b/package-lock.json index 56992d9d..881c205f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,18 +12,16 @@ "pyright": "^1.1.365" }, "devDependencies": { + "@biomejs/biome": "^1.8.1", "@types/diff-match-patch": "^1.0.36", "@types/md5": "^2.3.5", "@types/minimatch": "^5.1.2", "@types/node": "16", "@types/which": "^3.0.3", - "@typescript-eslint/eslint-plugin": "^7.1.0", - "@typescript-eslint/parser": "^7.1.0", "@zzzen/pyright-internal": "^1.2.0-dev.20240526", "coc.nvim": "^0.0.83-next.18", "diff-match-patch": "^1.0.5", "esbuild": "^0.21.4", - "eslint": "^8.55.0", "get-port": "^6.1.2", "iconv-lite": "^0.6.3", "md5": "^2.3.0", @@ -37,13 +35,168 @@ "coc": "^0.0.80" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "node_modules/@biomejs/biome": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.8.1.tgz", + "integrity": "sha512-fQXGfvq6DIXem12dGQCM2tNF+vsNHH1qs3C7WeOu75Pd0trduoTmoO7G4ntLJ2qDs5wuw981H+cxQhi1uHnAtA==", "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.8.1", + "@biomejs/cli-darwin-x64": "1.8.1", + "@biomejs/cli-linux-arm64": "1.8.1", + "@biomejs/cli-linux-arm64-musl": "1.8.1", + "@biomejs/cli-linux-x64": "1.8.1", + "@biomejs/cli-linux-x64-musl": "1.8.1", + "@biomejs/cli-win32-arm64": "1.8.1", + "@biomejs/cli-win32-x64": "1.8.1" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.8.1.tgz", + "integrity": "sha512-XLiB7Uu6GALIOBWzQ2aMD0ru4Ly5/qSeQF7kk3AabzJ/kwsEWSe33iVySBP/SS2qv25cgqNiLksjGcw2bHT3mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.8.1.tgz", + "integrity": "sha512-uMTSxVLMfqkBVqyc25hSn83jBbp+wtWjzM/pHFlKXt3htJuw7FErVGW0nmQ9Sxa9vJ7GcqoltLMl28VQRIMYzg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.8.1.tgz", + "integrity": "sha512-3SzZRuC/9Oi2P2IBNPsEj0KXxSXUEYRR2kfRF/Ve8QAfGgrt4qnwuWd6QQKKN5R+oYH691qjm+cXBKEcrP1v/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.8.1.tgz", + "integrity": "sha512-UQ8Wc01J0wQL+5AYOc7qkJn20B4PZmQL1KrmDZh7ot0DvD6aX4+8mmfd/dG5b6Zjo/44QvCKcvkFGCMRYuhWZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.8.1.tgz", + "integrity": "sha512-AeBycVdNrTzsyYKEOtR2R0Ph0hCD0sCshcp2aOnfGP0hCZbtFg09D0SdKLbyzKntisY41HxKVrydYiaApp+2uw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.8.1.tgz", + "integrity": "sha512-fYbP/kNu/rtZ4kKzWVocIdqZOtBSUEg9qUhZaao3dy3CRzafR6u6KDtBeSCnt47O+iLnks1eOR1TUxzr5+QuqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.8.1.tgz", + "integrity": "sha512-6tEd1H/iFKpgpE3OIB7oNgW5XkjiVMzMRPL8zYoZ036YfuJ5nMYm9eB9H/y81+8Z76vL48fiYzMPotJwukGPqQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.8.1.tgz", + "integrity": "sha512-g2H31jJzYmS4jkvl6TiyEjEX+Nv79a5km/xn+5DARTp5MBFzC9gwceusSSB2AkJKqZzY131AiACAWjKrVt5Ijw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" } }, "node_modules/@esbuild/aix-ppc64": { @@ -414,136 +567,12 @@ "node": ">=12" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true - }, "node_modules/@iarna/toml": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", "dev": true }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@types/diff-match-patch": { "version": "1.0.36", "resolved": "https://registry.npmjs.org/@types/diff-match-patch/-/diff-match-patch-1.0.36.tgz", @@ -580,221 +609,6 @@ "integrity": "sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==", "dev": true }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz", - "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.11.0", - "@typescript-eslint/type-utils": "7.11.0", - "@typescript-eslint/utils": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", - "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.11.0", - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/typescript-estree": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", - "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz", - "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.11.0", - "@typescript-eslint/utils": "7.11.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", - "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", - "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz", - "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.11.0", - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/typescript-estree": "7.11.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", - "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.11.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/@yarnpkg/fslib": { "version": "2.10.4", "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.10.4.tgz", @@ -845,56 +659,10 @@ "vscode-uri": "^3.0.8" } }, - "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/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" @@ -919,12 +687,6 @@ "node": ">= 8" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "node_modules/array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", @@ -934,15 +696,6 @@ "node": ">=6" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -986,15 +739,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1099,35 +843,6 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", @@ -1137,59 +852,12 @@ "node": "*" } }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==", - "dev": true - }, "node_modules/diff-match-patch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", "dev": true }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/esbuild": { "version": "0.21.4", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.4.tgz", @@ -1228,227 +896,6 @@ "@esbuild/win32-x64": "0.21.4" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.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", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1473,41 +920,6 @@ "node": ">=4.0.0" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", - "dev": true - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1571,47 +983,6 @@ "node": ">= 6" } }, - "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1633,40 +1004,6 @@ "node": ">=0.10.0" } }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o= sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1731,45 +1068,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, "node_modules/jsonc-parser": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", @@ -1785,58 +1083,12 @@ "node": ">=6" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -1848,28 +1100,6 @@ "is-buffer": "~1.1.6" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1882,24 +1112,12 @@ "node": "*" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/named-js-regexp": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/named-js-regexp/-/named-js-regexp-1.3.5.tgz", "integrity": "sha512-XO0DPujDP9IWpkt690iWLreKztb/VB811DGl5N3z7BfhkMJuiVZXOi6YN/fEB9qkvtMVTgSZDW8pzdVt8vj/FA==", "dev": true }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1918,74 +1136,6 @@ "wrappy": "1" } }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1995,24 +1145,6 @@ "node": ">=0.10.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2025,24 +1157,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/pyright": { "version": "1.1.365", "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.365.tgz", @@ -2071,25 +1185,6 @@ "node": ">=8.10.0" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2105,12 +1200,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -2132,51 +1221,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2196,30 +1240,6 @@ "source-map": "^0.6.0" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2232,12 +1252,6 @@ "node": ">=8" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -2271,48 +1285,12 @@ "tree-kill": "cli.js" } }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typescript": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", @@ -2335,15 +1313,6 @@ "node": ">=8" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/vscode-jsonrpc": { "version": "9.0.0-next.2", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.0-next.2.tgz", @@ -2422,24 +1391,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } } } diff --git a/package.json b/package.json index ff95b898..1777e277 100644 --- a/package.json +++ b/package.json @@ -29,23 +29,21 @@ ], "scripts": { "schema": "node diff.mjs", - "lint": "eslint src --ext ts", + "lint": "biome check src", "build": "node esbuild.mjs", "prepare": "node esbuild.mjs" }, "devDependencies": { + "@biomejs/biome": "^1.8.1", "@types/diff-match-patch": "^1.0.36", "@types/md5": "^2.3.5", "@types/minimatch": "^5.1.2", "@types/node": "16", "@types/which": "^3.0.3", - "@typescript-eslint/eslint-plugin": "^7.1.0", - "@typescript-eslint/parser": "^7.1.0", "@zzzen/pyright-internal": "^1.2.0-dev.20240526", "coc.nvim": "^0.0.83-next.18", "diff-match-patch": "^1.0.5", "esbuild": "^0.21.4", - "eslint": "^8.55.0", "get-port": "^6.1.2", "iconv-lite": "^0.6.3", "md5": "^2.3.0", diff --git a/src/async.ts b/src/async.ts index 78791143..fd227c60 100644 --- a/src/async.ts +++ b/src/async.ts @@ -3,8 +3,6 @@ /* eslint-disable prefer-rest-params */ /* eslint-disable @typescript-eslint/no-unused-vars */ -'use strict'; - //====================== // Deferred @@ -31,10 +29,12 @@ class DeferredImpl implements Deferred { }); } public resolve(_value?: T | PromiseLike) { + // biome-ignore lint/style/noArguments: this._resolve.apply(this.scope ? this.scope : this, arguments as any); this._resolved = true; } public reject(_reason?: any) { + // biome-ignore lint/style/noArguments: this._reject.apply(this.scope ? this.scope : this, arguments as any); this._rejected = true; } @@ -54,4 +54,3 @@ class DeferredImpl implements Deferred { export function createDeferred(scope: any = null): Deferred { return new DeferredImpl(scope); } - diff --git a/src/commands.ts b/src/commands.ts index 081240c9..1bd8aaf8 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1,9 +1,9 @@ -import * as child_process from 'child_process'; -import { Terminal, Uri, window, workspace } from 'coc.nvim'; -import path from 'path'; +import * as child_process from 'node:child_process'; +import { type Terminal, Uri, window, workspace } from 'coc.nvim'; +import path from 'node:path'; import { PythonSettings } from './configSettings'; import * as parser from './parsers'; -import { TestingFramework } from './types'; +import type { TestingFramework } from './types'; let terminal: Terminal | undefined; @@ -21,7 +21,7 @@ function validPythonModule(pythonPath: string, moduleName: string) { async function runTest(uri: string, testFunction?: string) { const workspaceUri = Uri.parse(workspace.root).toString(); - const relativeFileUri = uri.replace(workspaceUri + '/', ''); + const relativeFileUri = uri.replace(`${workspaceUri}/`, ''); let testFile = ''; if (framework === 'pytest') { testFile = relativeFileUri.split('/').join(path.sep); diff --git a/src/configSettings.ts b/src/configSettings.ts index 8be347de..3601e002 100644 --- a/src/configSettings.ts +++ b/src/configSettings.ts @@ -1,10 +1,10 @@ -import * as child_process from 'child_process'; -import { ConfigurationChangeEvent, Disposable, workspace, WorkspaceConfiguration } from 'coc.nvim'; -import fs from 'fs'; -import path from 'path'; +import * as child_process from 'node:child_process'; +import { type ConfigurationChangeEvent, type Disposable, workspace, type WorkspaceConfiguration } from 'coc.nvim'; +import fs from 'node:fs'; +import path from 'node:path'; import which from 'which'; import { SystemVariables } from './systemVariables'; -import { IFormattingSettings, ILintingSettings, IPythonSettings, ISortImportSettings } from './types'; +import type { IFormattingSettings, ILintingSettings, IPythonSettings, ISortImportSettings } from './types'; export class PythonSettings implements IPythonSettings { private workspaceRoot: string; @@ -35,18 +35,23 @@ export class PythonSettings implements IPythonSettings { } public static dispose() { - PythonSettings.pythonSettings.forEach((item) => item && item.dispose()); + for (const item of PythonSettings.pythonSettings) { + item[1].dispose(); + } PythonSettings.pythonSettings.clear(); } public dispose() { - this.disposables.forEach((disposable) => disposable && disposable.dispose()); + for (const disposable of this.disposables) { + disposable.dispose(); + } this.disposables = []; } private resolvePythonFromVENV(): string | undefined { function pythonBinFromPath(p: string): string | undefined { - const fullPath = process.platform === 'win32' ? path.join(p, 'Scripts', 'python.exe') : path.join(p, 'bin', 'python'); + const fullPath = + process.platform === 'win32' ? path.join(p, 'Scripts', 'python.exe') : path.join(p, 'bin', 'python'); return fs.existsSync(fullPath) ? fullPath : undefined; } @@ -80,7 +85,12 @@ export class PythonSettings implements IPythonSettings { // poetry p = path.join(this.workspaceRoot, 'poetry.lock'); if (fs.existsSync(p)) { - const list = child_process.spawnSync('poetry', ['env', 'list', '--full-path', '--no-ansi'], { encoding: 'utf8', cwd: this.workspaceRoot }).stdout.trim(); + const list = child_process + .spawnSync('poetry', ['env', 'list', '--full-path', '--no-ansi'], { + encoding: 'utf8', + cwd: this.workspaceRoot, + }) + .stdout.trim(); let info = ''; for (const item of list.split('\n')) { if (item.includes('(Activated)')) { @@ -179,14 +189,12 @@ export class PythonSettings implements IPythonSettings { } private getAbsolutePath(pathToCheck: string, rootDir?: string): string { - if (!rootDir) { - rootDir = this.workspaceRoot; - } - pathToCheck = workspace.expand(pathToCheck); - if (pathToCheck.indexOf(path.sep) === -1) { - return pathToCheck; + const realPath = workspace.expand(pathToCheck); + if (realPath.indexOf(path.sep) === -1) { + return realPath; } - return path.isAbsolute(pathToCheck) ? pathToCheck : path.resolve(rootDir, pathToCheck); + const root = rootDir ? rootDir : this.workspaceRoot; + return path.isAbsolute(realPath) ? realPath : path.resolve(root, realPath); } protected initialize(): void { @@ -196,7 +204,7 @@ export class PythonSettings implements IPythonSettings { const currentConfig = workspace.getConfiguration('python', workspace.root); this.update(currentConfig); } - }) + }), ); const initialConfig = workspace.getConfiguration('python', workspace.root); @@ -206,22 +214,16 @@ export class PythonSettings implements IPythonSettings { } } -function getPythonExecutable(pythonPath: string): string { - pythonPath = workspace.expand(pythonPath); - +function getPythonExecutable(value: string): string { // If only 'python'. - if (pythonPath === 'python' || pythonPath.indexOf(path.sep) === -1 || path.basename(pythonPath) === path.dirname(pythonPath)) { - const bin = which.sync(pythonPath, { nothrow: true }); + if (value === 'python' || value.indexOf(path.sep) === -1 || path.basename(value) === path.dirname(value)) { + const bin = which.sync(value, { nothrow: true }); if (bin) { - pythonPath = bin; + return bin; } } - if (isValidPythonPath(pythonPath)) { - return pythonPath; - } - - return pythonPath; + return workspace.expand(value); } function getStdLibs(pythonPath: string): string[] { @@ -237,11 +239,3 @@ function getStdLibs(pythonPath: string): string[] { return []; } } - -function isValidPythonPath(pythonPath: string): boolean { - try { - return child_process.spawnSync(pythonPath, ['-c', 'print(1234)'], { encoding: 'utf8' }).stdout.startsWith('1234'); - } catch (ex) { - return false; - } -} diff --git a/src/features/codeAction.ts b/src/features/codeAction.ts index f3954261..2792168e 100644 --- a/src/features/codeAction.ts +++ b/src/features/codeAction.ts @@ -1,16 +1,16 @@ import { CancellationTokenSource, - CodeAction, - CodeActionContext, + type CodeAction, + type CodeActionContext, CodeActionKind, - CodeActionProvider, - CompleteOption, - Diagnostic, + type CodeActionProvider, + type CompleteOption, + type Diagnostic, Position, Range, - TextDocument, + type TextDocument, TextEdit, - VimCompleteItem, + type VimCompleteItem, sources, workspace, } from 'coc.nvim'; @@ -19,7 +19,10 @@ export class PythonCodeActionProvider implements CodeActionProvider { private wholeRange(doc: TextDocument, range: Range): boolean { const whole = Range.create(0, 0, doc.lineCount - 1, 0); return ( - whole.start.line === range.start.line && whole.start.character === range.start.character && whole.end.line === range.end.line && whole.end.character === whole.end.character + whole.start.line === range.start.line && + whole.start.character === range.start.character && + whole.end.line === range.end.line && + whole.end.character === range.end.character ); } @@ -28,7 +31,10 @@ export class PythonCodeActionProvider implements CodeActionProvider { } private lineRange(r: Range): boolean { - return (r.start.line + 1 === r.end.line && r.start.character === 0 && r.end.character === 0) || (r.start.line === r.end.line && r.start.character === 0); + return ( + (r.start.line + 1 === r.end.line && r.start.character === 0 && r.end.character === 0) || + (r.start.line === r.end.line && r.start.character === 0) + ); } private sortImportsAction(): CodeAction { @@ -59,7 +65,7 @@ export class PythonCodeActionProvider implements CodeActionProvider { kind: CodeActionKind.Empty, edit: { changes: { - [doc.uri]: [TextEdit.insert(pos, ignoreTxt + '\n')], + [doc.uri]: [TextEdit.insert(pos, `${ignoreTxt}\n`)], }, }, }; @@ -69,8 +75,11 @@ export class PythonCodeActionProvider implements CodeActionProvider { // ignore action for current line if (this.lineRange(range)) { const line = doc.getline(range.start.line); - if (line && line.length && !line.startsWith('#') && !line.includes(ignoreTxt)) { - const edit = TextEdit.replace(range, `${line} ${ignoreTxt}${range.start.line + 1 === range.end.line ? '\n' : ''}`); + if (line.length && !line.startsWith('#') && !line.includes(ignoreTxt)) { + const edit = TextEdit.replace( + range, + `${line} ${ignoreTxt}${range.start.line + 1 === range.end.line ? '\n' : ''}`, + ); return { title: 'Ignore Pyright typing check for current line', kind: CodeActionKind.Empty, @@ -110,7 +119,10 @@ export class PythonCodeActionProvider implements CodeActionProvider { ]; } - private async fetchImportsByDiagnostic(document: TextDocument, diag: Diagnostic): Promise> { + private async fetchImportsByDiagnostic( + document: TextDocument, + diag: Diagnostic, + ): Promise> { const match = diag.message.match(/"(.*)" is not defined/); if (!match) return []; @@ -124,7 +136,7 @@ export class PythonCodeActionProvider implements CodeActionProvider { tokenSource.cancel(); // @ts-ignore - return result ? result.items.filter(x => x.label === match[1]) : []; + return result ? result.items.filter((x) => x.label === match[1]) : []; } private async fixAction(document: TextDocument, diag: Diagnostic): Promise { @@ -162,12 +174,16 @@ export class PythonCodeActionProvider implements CodeActionProvider { return actions; } - public async provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext): Promise { + public async provideCodeActions( + document: TextDocument, + range: Range, + context: CodeActionContext, + ): Promise { const actions: CodeAction[] = []; if (context.diagnostics.length) { for (const diag of context.diagnostics) { - actions.push(...await this.fixAction(document, diag)); + actions.push(...(await this.fixAction(document, diag))); } } diff --git a/src/features/formatters/autopep8.ts b/src/features/formatters/autopep8.ts index a17dce8a..ac84f0ce 100644 --- a/src/features/formatters/autopep8.ts +++ b/src/features/formatters/autopep8.ts @@ -1,13 +1,29 @@ -import { TextDocument, FormattingOptions, CancellationToken, Range, Thenable, TextEdit, OutputChannel } from 'coc.nvim'; -import { IPythonSettings } from '../../types'; +import type { + TextDocument, + FormattingOptions, + CancellationToken, + Range, + Thenable, + TextEdit, + OutputChannel, +} from 'coc.nvim'; +import type { IPythonSettings } from '../../types'; import { BaseFormatter } from './baseFormatter'; export class AutoPep8Formatter extends BaseFormatter { - constructor(public readonly pythonSettings: IPythonSettings, public readonly outputChannel: OutputChannel) { + constructor( + public readonly pythonSettings: IPythonSettings, + public readonly outputChannel: OutputChannel, + ) { super('autopep8', pythonSettings, outputChannel); } - public formatDocument(document: TextDocument, options: FormattingOptions, token: CancellationToken, range?: Range): Thenable { + public formatDocument( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + range?: Range, + ): Thenable { const autoPep8Args = ['--diff']; if (this.pythonSettings.formatting.autopep8Args.length > 0) { autoPep8Args.push(...this.pythonSettings.formatting.autopep8Args); diff --git a/src/features/formatters/baseFormatter.ts b/src/features/formatters/baseFormatter.ts index 00338b6c..55f29975 100644 --- a/src/features/formatters/baseFormatter.ts +++ b/src/features/formatters/baseFormatter.ts @@ -1,10 +1,21 @@ -import { CancellationToken, FormattingOptions, OutputChannel, Range, TextDocument, TextEdit, Thenable, Uri, window, workspace } from 'coc.nvim'; -import fs from 'fs'; +import { + type CancellationToken, + type FormattingOptions, + type OutputChannel, + type Range, + type TextDocument, + type TextEdit, + type Thenable, + Uri, + window, + workspace, +} from 'coc.nvim'; +import fs from 'node:fs'; import md5 from 'md5'; -import path from 'path'; +import path from 'node:path'; import which from 'which'; import { isNotInstalledError, PythonExecutionService } from '../../processService'; -import { ExecutionInfo, FormatterId, IPythonSettings } from '../../types'; +import type { ExecutionInfo, FormatterId, IPythonSettings } from '../../types'; import { getTextEditsFromPatch } from '../../utils'; function getTempFileWithDocumentContents(document: TextDocument): Promise { @@ -28,9 +39,18 @@ function getTempFileWithDocumentContents(document: TextDocument): Promise; + public abstract formatDocument( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + range?: Range, + ): Thenable; protected getDocumentPath(document: TextDocument, fallbackPath?: string): string { const filepath = Uri.parse(document.uri).fsPath; if (fallbackPath && path.basename(filepath) === filepath) { @@ -55,14 +75,16 @@ export abstract class BaseFormatter { return { execPath, moduleName, args }; } - protected async provideDocumentFormattingEdits(document: TextDocument, _options: FormattingOptions, token: CancellationToken, args: string[], cwd?: string): Promise { + protected async provideDocumentFormattingEdits( + document: TextDocument, + _options: FormattingOptions, + token: CancellationToken, + args: string[], + root?: string, + ): Promise { if (this.pythonSettings.stdLibs.some((p) => Uri.parse(document.uri).fsPath.startsWith(p))) { return []; } - if (typeof cwd !== 'string' || cwd.length === 0) { - cwd = Uri.file(workspace.root).fsPath; - } - // autopep8 and yapf have the ability to read from the process input stream and return the formatted code out of the output stream. // However they don't support returning the diff of the formatted text when reading data from the input stream. // Yet getting text formatted that way avoids having to create a temporary file, however the diffing will have @@ -79,6 +101,7 @@ export abstract class BaseFormatter { this.outputChannel.appendLine(`moduleName: ${executionInfo.moduleName}`); this.outputChannel.appendLine(`args: ${executionInfo.args}`); + const cwd = root?.length ? root : Uri.file(workspace.root).fsPath; const pythonToolsExecutionService = new PythonExecutionService(); const promise = pythonToolsExecutionService .exec(executionInfo, { cwd, throwOnStdErr: false, token }) @@ -135,7 +158,7 @@ export abstract class BaseFormatter { } private checkCancellation(originalFile: string, tempFile: string, state: string, token?: CancellationToken): boolean { - if (token && token.isCancellationRequested) { + if (token?.isCancellationRequested) { this.outputChannel.appendLine(`${'#'.repeat(10)} ${this.Id} formatting action is canceled on ${state}`); this.deleteTempFile(originalFile, tempFile).catch(() => {}); return true; diff --git a/src/features/formatters/black.ts b/src/features/formatters/black.ts index bae782ae..025ac848 100644 --- a/src/features/formatters/black.ts +++ b/src/features/formatters/black.ts @@ -1,13 +1,29 @@ -import { CancellationToken, FormattingOptions, OutputChannel, Range, TextDocument, TextEdit, Thenable } from 'coc.nvim'; -import { IPythonSettings } from '../../types'; +import type { + CancellationToken, + FormattingOptions, + OutputChannel, + Range, + TextDocument, + TextEdit, + Thenable, +} from 'coc.nvim'; +import type { IPythonSettings } from '../../types'; import { BaseFormatter } from './baseFormatter'; export class BlackFormatter extends BaseFormatter { - constructor(public readonly pythonSettings: IPythonSettings, public readonly outputChannel: OutputChannel) { + constructor( + public readonly pythonSettings: IPythonSettings, + public readonly outputChannel: OutputChannel, + ) { super('black', pythonSettings, outputChannel); } - public formatDocument(document: TextDocument, options: FormattingOptions, token: CancellationToken, range?: Range): Thenable { + public formatDocument( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + range?: Range, + ): Thenable { const blackArgs = ['--diff', '--quiet']; if (range) { blackArgs.push(`--line-ranges=${range.start.line + 1}-${range.end.line}`); diff --git a/src/features/formatters/blackd.ts b/src/features/formatters/blackd.ts index fca5ee19..a3c332ec 100644 --- a/src/features/formatters/blackd.ts +++ b/src/features/formatters/blackd.ts @@ -1,14 +1,28 @@ -import { spawn } from 'child_process'; -import { CancellationToken, fetch, FormattingOptions, OutputChannel, Range, TextDocument, TextEdit, Thenable, Uri, window } from 'coc.nvim'; +import { spawn } from 'node:child_process'; +import { + type CancellationToken, + fetch, + type FormattingOptions, + type OutputChannel, + type Range, + type TextDocument, + type TextEdit, + type Thenable, + Uri, + window, +} from 'coc.nvim'; import getPort from 'get-port'; import { getTextEditsFromPatch } from '../../utils'; -import { IPythonSettings } from '../../types'; +import type { IPythonSettings } from '../../types'; import { BaseFormatter } from './baseFormatter'; export class BlackdFormatter extends BaseFormatter { private blackdHTTPURL = ''; - constructor(public readonly pythonSettings: IPythonSettings, public readonly outputChannel: OutputChannel) { + constructor( + public readonly pythonSettings: IPythonSettings, + public readonly outputChannel: OutputChannel, + ) { super('blackd', pythonSettings, outputChannel); this.blackdHTTPURL = this.pythonSettings.formatting.blackdHTTPURL; @@ -58,14 +72,19 @@ export class BlackdFormatter extends BaseFormatter { } } - public formatDocument(document: TextDocument, _options: FormattingOptions, _token: CancellationToken, range?: Range): Thenable { + public formatDocument( + document: TextDocument, + _options: FormattingOptions, + _token: CancellationToken, + range?: Range, + ): Thenable { if (range) { const msg = 'blackd does not support range formatting'; this.outputChannel.appendLine(msg); window.showErrorMessage(msg); return Promise.resolve([]); } - if (this.pythonSettings.stdLibs.some(p => Uri.parse(document.uri).fsPath.startsWith(p))) { + if (this.pythonSettings.stdLibs.some((p) => Uri.parse(document.uri).fsPath.startsWith(p))) { return Promise.resolve([]); } diff --git a/src/features/formatters/darker.ts b/src/features/formatters/darker.ts index e6e7bbdd..7499c04c 100644 --- a/src/features/formatters/darker.ts +++ b/src/features/formatters/darker.ts @@ -1,9 +1,20 @@ -import { CancellationToken, FormattingOptions, OutputChannel, TextDocument, TextEdit, Thenable, Uri } from 'coc.nvim'; -import { IPythonSettings } from '../../types'; +import { + type CancellationToken, + type FormattingOptions, + type OutputChannel, + type TextDocument, + type TextEdit, + type Thenable, + Uri, +} from 'coc.nvim'; +import type { IPythonSettings } from '../../types'; import { BaseFormatter } from './baseFormatter'; export class DarkerFormatter extends BaseFormatter { - constructor(public readonly pythonSettings: IPythonSettings, public readonly outputChannel: OutputChannel) { + constructor( + public readonly pythonSettings: IPythonSettings, + public readonly outputChannel: OutputChannel, + ) { super('darker', pythonSettings, outputChannel); } @@ -13,7 +24,11 @@ export class DarkerFormatter extends BaseFormatter { }); } - public formatDocument(document: TextDocument, options: FormattingOptions, token: CancellationToken): Thenable { + public formatDocument( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + ): Thenable { const darkerArgs = ['--diff']; if (this.pythonSettings.formatting.darkerArgs.length > 0) { darkerArgs.push(...this.pythonSettings.formatting.darkerArgs); diff --git a/src/features/formatters/pyink.ts b/src/features/formatters/pyink.ts index c0e826dc..4c10d514 100644 --- a/src/features/formatters/pyink.ts +++ b/src/features/formatters/pyink.ts @@ -1,13 +1,29 @@ -import { CancellationToken, FormattingOptions, OutputChannel, Range, TextDocument, TextEdit, Thenable } from 'coc.nvim'; -import { IPythonSettings } from '../../types'; +import type { + CancellationToken, + FormattingOptions, + OutputChannel, + Range, + TextDocument, + TextEdit, + Thenable, +} from 'coc.nvim'; +import type { IPythonSettings } from '../../types'; import { BaseFormatter } from './baseFormatter'; export class PyinkFormatter extends BaseFormatter { - constructor(public readonly pythonSettings: IPythonSettings, public readonly outputChannel: OutputChannel) { + constructor( + public readonly pythonSettings: IPythonSettings, + public readonly outputChannel: OutputChannel, + ) { super('pyink', pythonSettings, outputChannel); } - public formatDocument(document: TextDocument, options: FormattingOptions, token: CancellationToken, range?: Range): Thenable { + public formatDocument( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + range?: Range, + ): Thenable { const args = ['--diff', '--quiet']; if (this.pythonSettings.formatting.pyinkArgs.length > 0) { args.push(...this.pythonSettings.formatting.pyinkArgs); diff --git a/src/features/formatters/ruff.ts b/src/features/formatters/ruff.ts index 21160838..5d157fbb 100644 --- a/src/features/formatters/ruff.ts +++ b/src/features/formatters/ruff.ts @@ -1,13 +1,30 @@ -import { CancellationToken, FormattingOptions, OutputChannel, Range, TextDocument, TextEdit, Thenable, window } from 'coc.nvim'; -import { IPythonSettings } from '../../types'; +import { + type CancellationToken, + type FormattingOptions, + type OutputChannel, + type Range, + type TextDocument, + type TextEdit, + type Thenable, + window, +} from 'coc.nvim'; +import type { IPythonSettings } from '../../types'; import { BaseFormatter } from './baseFormatter'; export class RuffFormatter extends BaseFormatter { - constructor(public readonly pythonSettings: IPythonSettings, public readonly outputChannel: OutputChannel) { + constructor( + public readonly pythonSettings: IPythonSettings, + public readonly outputChannel: OutputChannel, + ) { super('ruff', pythonSettings, outputChannel); } - public formatDocument(document: TextDocument, options: FormattingOptions, token: CancellationToken, range?: Range): Thenable { + public formatDocument( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + range?: Range, + ): Thenable { if (range) { const errorMessage = async () => { this.outputChannel.appendLine('Ruff does not support the "Format Selection" command'); diff --git a/src/features/formatters/yapf.ts b/src/features/formatters/yapf.ts index 70a6d3cf..02bd2cb8 100644 --- a/src/features/formatters/yapf.ts +++ b/src/features/formatters/yapf.ts @@ -1,13 +1,29 @@ -import { TextDocument, FormattingOptions, CancellationToken, Range, Thenable, TextEdit, OutputChannel } from 'coc.nvim'; -import { IPythonSettings } from '../../types'; +import type { + TextDocument, + FormattingOptions, + CancellationToken, + Range, + Thenable, + TextEdit, + OutputChannel, +} from 'coc.nvim'; +import type { IPythonSettings } from '../../types'; import { BaseFormatter } from './baseFormatter'; export class YapfFormatter extends BaseFormatter { - constructor(public readonly pythonSettings: IPythonSettings, public readonly outputChannel: OutputChannel) { + constructor( + public readonly pythonSettings: IPythonSettings, + public readonly outputChannel: OutputChannel, + ) { super('yapf', pythonSettings, outputChannel); } - public formatDocument(document: TextDocument, options: FormattingOptions, token: CancellationToken, range?: Range): Thenable { + public formatDocument( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + range?: Range, + ): Thenable { const yapfArgs = ['--diff']; if (this.pythonSettings.formatting.yapfArgs.length > 0) { yapfArgs.push(...this.pythonSettings.formatting.yapfArgs); diff --git a/src/features/formatting.ts b/src/features/formatting.ts index 350630cb..42fc673b 100644 --- a/src/features/formatting.ts +++ b/src/features/formatting.ts @@ -1,20 +1,20 @@ import { - CancellationToken, - Disposable, - DocumentFormattingEditProvider, - DocumentRangeFormattingEditProvider, - FormattingOptions, - OutputChannel, - ProviderResult, - Range, - TextDocument, - TextEdit, + type CancellationToken, + type Disposable, + type DocumentFormattingEditProvider, + type DocumentRangeFormattingEditProvider, + type FormattingOptions, + type OutputChannel, + type ProviderResult, + type Range, + type TextDocument, + type TextEdit, window, } from 'coc.nvim'; import { PythonSettings } from '../configSettings'; -import { FormatterId } from '../types'; +import type { FormatterId } from '../types'; import { AutoPep8Formatter } from './formatters/autopep8'; -import { BaseFormatter } from './formatters/baseFormatter'; +import type { BaseFormatter } from './formatters/baseFormatter'; import { BlackFormatter } from './formatters/black'; import { BlackdFormatter } from './formatters/blackd'; import { DarkerFormatter } from './formatters/darker'; @@ -22,7 +22,9 @@ import { PyinkFormatter } from './formatters/pyink'; import { RuffFormatter } from './formatters/ruff'; import { YapfFormatter } from './formatters/yapf'; -export class PythonFormattingEditProvider implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider { +export class PythonFormattingEditProvider + implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider +{ private formatters = new Map(); private disposables: Disposable[] = []; private pythonSettings: PythonSettings; @@ -60,11 +62,18 @@ export class PythonFormattingEditProvider implements DocumentFormattingEditProvi } } - private async _provideEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken, range?: Range): Promise { + private async _provideEdits( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + range?: Range, + ): Promise { const provider = this.pythonSettings.formatting.provider; const formatter = this.formatters.get(provider); if (!formatter) { - this.outputChannel.appendLine(`${'#'.repeat(10)} Error: python.formatting.provider is ${provider}, which is not supported`); + this.outputChannel.appendLine( + `${'#'.repeat(10)} Error: python.formatting.provider is ${provider}, which is not supported`, + ); return []; } @@ -73,15 +82,26 @@ export class PythonFormattingEditProvider implements DocumentFormattingEditProvi return formatter.formatDocument(document, options, token, range); } - provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken): ProviderResult { + provideDocumentFormattingEdits( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken, + ): ProviderResult { return this._provideEdits(document, options, token); } - provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult { + provideDocumentRangeFormattingEdits( + document: TextDocument, + range: Range, + options: FormattingOptions, + token: CancellationToken, + ): ProviderResult { return this._provideEdits(document, options, token, range); } public dispose() { - this.disposables.forEach((d) => d.dispose()); + for (const d of this.disposables) { + d.dispose(); + } } } diff --git a/src/features/importCompletion.ts b/src/features/importCompletion.ts index 2e85be7c..d282b385 100644 --- a/src/features/importCompletion.ts +++ b/src/features/importCompletion.ts @@ -1,7 +1,22 @@ -import { CancellationToken, CompletionContext, CompletionItem, CompletionItemKind, CompletionItemProvider, LinesTextDocument, Position, Range, sources } from 'coc.nvim'; +import { + type CancellationToken, + type CompletionContext, + type CompletionItem, + CompletionItemKind, + type CompletionItemProvider, + type LinesTextDocument, + type Position, + Range, + sources, +} from 'coc.nvim'; export class ImportCompletionProvider implements CompletionItemProvider { - async provideCompletionItems(document: LinesTextDocument, position: Position, token: CancellationToken, context: CompletionContext): Promise { + async provideCompletionItems( + document: LinesTextDocument, + position: Position, + token: CancellationToken, + context: CompletionContext, + ): Promise { if (context.triggerCharacter !== ' ') return []; const line = document.getText(Range.create(position.line, 0, position.line, position.character)).trim(); if (!line.includes('from') && !line.includes('import')) return []; @@ -18,8 +33,13 @@ export class ImportCompletionProvider implements CompletionItemProvider { if (!result) return []; const items: CompletionItem[] = []; for (const o of result.items) { - // @ts-ignore - items.push({ label: o.label || o.word, sortText: o.sortText, kind: CompletionItemKind.Module, filterText: o.filterText }); + items.push({ + // @ts-ignore + label: o.label || o.word, + sortText: o.sortText, + kind: CompletionItemKind.Module, + filterText: o.filterText, + }); } return items; } diff --git a/src/features/inlayHints.ts b/src/features/inlayHints.ts index 866c40d9..c73a03ee 100644 --- a/src/features/inlayHints.ts +++ b/src/features/inlayHints.ts @@ -1,17 +1,17 @@ import { - CancellationToken, + type CancellationToken, Emitter, - Event, - Hover, - InlayHint, - InlayHintLabelPart, - InlayHintsProvider, - LanguageClient, - LinesTextDocument, - MarkupContent, + type Event, + type Hover, + type InlayHint, + type InlayHintLabelPart, + type InlayHintsProvider, + type LanguageClient, + type LinesTextDocument, + type MarkupContent, Position, - Range, - SignatureHelp, + type Range, + type SignatureHelp, workspace, } from 'coc.nvim'; @@ -60,7 +60,8 @@ export class TypeInlayHintsProvider implements InlayHintsProvider { const startPosition = document.positionAt(item.startOffset); const endPosition = document.positionAt(item.endOffset); const hover = item.inlayHintType === 'parameter' ? null : await this.getHoverAtOffset(document, startPosition); - const signatureInfo = item.inlayHintType === 'parameter' ? await this.getSignatureHelpAtOffset(document, startPosition) : null; + const signatureInfo = + item.inlayHintType === 'parameter' ? await this.getSignatureHelpAtOffset(document, startPosition) : null; let inlayHintLabelValue: string | undefined = undefined; switch (item.inlayHintType) { @@ -126,7 +127,7 @@ export class TypeInlayHintsProvider implements InlayHintsProvider { private getVariableHintFromHover(hover: Hover | null): string | undefined { if (!hover) return; const contents = hover.contents as MarkupContent; - if (contents && contents.value.includes('(variable)')) { + if (contents.value.includes('(variable)')) { if (contents.value.includes('(variable) def')) { return; } @@ -139,7 +140,7 @@ export class TypeInlayHintsProvider implements InlayHintsProvider { if (text === 'Any' || text.startsWith('Literal[')) { return; } - return ': ' + text; + return `: ${text}`; } } } @@ -150,7 +151,7 @@ export class TypeInlayHintsProvider implements InlayHintsProvider { if (contents && (contents.value.includes('(function)') || contents.value.includes('(method)'))) { const retvalIdx = contents.value.indexOf('->') + 2; const text = contents.value.substring(retvalIdx).split('\n')[0].trim(); - return '-> ' + text; + return `-> ${text}`; } } @@ -180,7 +181,7 @@ export class TypeInlayHintsProvider implements InlayHintsProvider { if (label.startsWith('__')) { return; } - return label + ': '; + return `${label}: `; } private enableForType(inlayHintType: string) { diff --git a/src/features/linters/bandit.ts b/src/features/linters/bandit.ts index 30e04ba7..3f691aa8 100644 --- a/src/features/linters/bandit.ts +++ b/src/features/linters/bandit.ts @@ -1,10 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -'use strict'; - -import { CancellationToken, OutputChannel, TextDocument, Uri } from 'coc.nvim'; -import { LintMessageSeverity, ILinterInfo, ILintMessage } from '../../types'; +import { Uri, type CancellationToken, type TextDocument } from 'coc.nvim'; +import { type ILintMessage, LintMessageSeverity } from '../../types'; import { BaseLinter } from './baseLinter'; const severityMapping: Record = { @@ -14,17 +12,25 @@ const severityMapping: Record = { }; export class Bandit extends BaseLinter { - constructor(info: ILinterInfo, outputChannel: OutputChannel) { - super(info, outputChannel); - } - protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { // View all errors in bandit <= 1.5.1 (https://github.com/PyCQA/bandit/issues/371) - const messages = await this.run(['-f', 'custom', '--msg-template', '{line},0,{severity},{test_id}:{msg}', '-n', '-1', Uri.parse(document.uri).fsPath], document, cancellation); + const messages = await this.run( + [ + '-f', + 'custom', + '--msg-template', + '{line},0,{severity},{test_id}:{msg}', + '-n', + '-1', + Uri.parse(document.uri).fsPath, + ], + document, + cancellation, + ); - messages.forEach((msg) => { + for (const msg of messages) { msg.severity = severityMapping[msg.type]; - }); + } return messages; } } diff --git a/src/features/linters/baseLinter.ts b/src/features/linters/baseLinter.ts index 3cd1f861..ab3e57e9 100644 --- a/src/features/linters/baseLinter.ts +++ b/src/features/linters/baseLinter.ts @@ -1,13 +1,20 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -'use strict'; -import { spawn } from 'child_process'; -import { CancellationToken, OutputChannel, TextDocument, Uri, workspace } from 'coc.nvim'; +import { spawn } from 'node:child_process'; +import { type CancellationToken, type OutputChannel, type TextDocument, Uri, workspace } from 'coc.nvim'; import namedRegexp from 'named-js-regexp'; import { PythonSettings } from '../../configSettings'; import { PythonExecutionService } from '../../processService'; -import { ExecutionInfo, ILinter, ILinterInfo, ILintMessage, IPythonSettings, LinterId, LintMessageSeverity } from '../../types'; +import { + type ExecutionInfo, + type ILinter, + type ILinterInfo, + type ILintMessage, + type IPythonSettings, + type LinterId, + LintMessageSeverity, +} from '../../types'; import { splitLines } from '../../utils'; // Allow negative column numbers (https://github.com/PyCQA/pylint/issues/1822) @@ -45,7 +52,7 @@ function parseLine(line: string, regex: string, linterID: LinterId, colOffset = return { code: match.code, message: match.message, - column: isNaN(match.column) || match.column <= 0 ? 0 : match.column - colOffset, + column: Number.isNaN(match.column) || match.column <= 0 ? 0 : match.column - colOffset, line: match.line, type: match.type, provider: linterID, @@ -63,7 +70,11 @@ export abstract class BaseLinter implements ILinter { return this._pythonSettings; } - constructor(info: ILinterInfo, protected readonly outputChannel: OutputChannel, protected readonly columnOffset = 0) { + constructor( + info: ILinterInfo, + protected readonly outputChannel: OutputChannel, + protected readonly columnOffset = 0, + ) { this._info = info; this._pythonSettings = PythonSettings.getInstance(); } @@ -114,7 +125,7 @@ export abstract class BaseLinter implements ILinter { child.stdin.end(); let result = ''; - child.stdout.on('data', data => { + child.stdout.on('data', (data) => { result += data.toString('utf-8').trim(); }); child.on('close', () => { @@ -123,7 +134,12 @@ export abstract class BaseLinter implements ILinter { }); } - protected async run(args: string[], document: TextDocument, token: CancellationToken, regEx = REGEX): Promise { + protected async run( + args: string[], + document: TextDocument, + token: CancellationToken, + regEx = REGEX, + ): Promise { if (!this.info.isEnabled(Uri.parse(document.uri))) { return []; } @@ -138,8 +154,8 @@ export abstract class BaseLinter implements ILinter { if (this.info.stdinSupport) { result = await this.stdinRun(executionInfo, document); } else { - const pythonToolsExecutionService = new PythonExecutionService(); - result = (await pythonToolsExecutionService.exec(executionInfo, { cwd: workspace.root, token, mergeStdOutErr: false })).stdout; + const service = new PythonExecutionService(); + result = (await service.exec(executionInfo, { cwd: workspace.root, token, mergeStdOutErr: false })).stdout; } this.outputChannel.append(`${'#'.repeat(10)} Linting Output - ${this.info.id} ${'#'.repeat(10)}\n`); diff --git a/src/features/linters/flake8.ts b/src/features/linters/flake8.ts index ec849e45..ecee1eda 100644 --- a/src/features/linters/flake8.ts +++ b/src/features/linters/flake8.ts @@ -1,5 +1,5 @@ -import { CancellationToken, OutputChannel, TextDocument, Uri } from 'coc.nvim'; -import { ILinterInfo, ILintMessage } from '../../types'; +import { type CancellationToken, type OutputChannel, type TextDocument, Uri } from 'coc.nvim'; +import type { ILinterInfo, ILintMessage } from '../../types'; import { BaseLinter } from './baseLinter'; const COLUMN_OFF_SET = 1; @@ -18,9 +18,9 @@ export class Flake8 extends BaseLinter { args.push(fsPath); } const messages = await this.run(args, document, cancellation); - messages.forEach((msg) => { + for (const msg of messages) { msg.severity = this.parseMessagesSeverity(msg.type, this.pythonSettings.linting.flake8CategorySeverity); - }); + } return messages; } } diff --git a/src/features/linters/linterInfo.ts b/src/features/linters/linterInfo.ts index 66f58096..a605cef4 100644 --- a/src/features/linters/linterInfo.ts +++ b/src/features/linters/linterInfo.ts @@ -1,18 +1,23 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { Uri, workspace } from 'coc.nvim'; -import * as path from 'path'; +import { type Uri, workspace } from 'coc.nvim'; +import * as path from 'node:path'; import which from 'which'; -import { PythonSettings } from '../../configSettings'; -import { ExecutionInfo, ILinterInfo, LinterId, Product } from '../../types'; +import type { PythonSettings } from '../../configSettings'; +import type { ExecutionInfo, ILinterInfo, LinterId, Product } from '../../types'; export class LinterInfo implements ILinterInfo { private _id: LinterId; private _product: Product; private _configFileNames: string[]; - constructor(product: Product, id: LinterId, protected configService: PythonSettings, configFileNames: string[] = []) { + constructor( + product: Product, + id: LinterId, + protected configService: PythonSettings, + configFileNames: string[] = [], + ) { this._product = product; this._id = id; this._configFileNames = configFileNames; @@ -47,7 +52,8 @@ export class LinterInfo implements ILinterInfo { return Array.isArray(args) ? (args as string[]) : []; } public getExecutionInfo(customArgs: string[], resource?: Uri): ExecutionInfo { - const execPath = which.sync(workspace.expand(this.pathName(resource)), { nothrow: true }) || this.pathName(resource); + const cmd = workspace.expand(this.pathName(resource)); + const execPath = which.sync(cmd, { nothrow: true }) || this.pathName(resource); const args = this.linterArgs(resource).concat(customArgs); let moduleName: string | undefined; diff --git a/src/features/linters/lintingEngine.ts b/src/features/linters/lintingEngine.ts index 026d5224..89f0147b 100644 --- a/src/features/linters/lintingEngine.ts +++ b/src/features/linters/lintingEngine.ts @@ -1,28 +1,33 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -'use strict'; - import { CancellationTokenSource, Diagnostic, - DiagnosticCollection, + type DiagnosticCollection, DiagnosticSeverity, - DocumentFilter, + type DocumentFilter, languages, - OutputChannel, + type OutputChannel, Position, Range, - TextDocument, + type TextDocument, Uri, window, workspace, } from 'coc.nvim'; -import fs from 'fs'; +import fs from 'node:fs'; import { Minimatch } from 'minimatch'; -import path from 'path'; +import path from 'node:path'; import { PythonSettings } from '../../configSettings'; -import { LintMessageSeverity, ILinter, Product, ILintMessage, ILinterInfo, LinterErrors } from '../../types'; +import { + LintMessageSeverity, + type ILinter, + Product, + type ILintMessage, + type ILinterInfo, + LinterErrors, +} from '../../types'; import { Bandit } from './bandit'; import { Flake8 } from './flake8'; import { LinterInfo } from './linterInfo'; @@ -120,7 +125,7 @@ export class LintingEngine { this.pendingLintings.set(fsPath, cancelToken); - const activeLinters = this.getActiveLinters().filter(l => onChange ? l.stdinSupport : true); + const activeLinters = this.getActiveLinters().filter((l) => (onChange ? l.stdinSupport : true)); const promises: Promise[] = activeLinters.map(async (info: ILinterInfo) => { this.outputChannel.appendLine(`Using python from ${this.configService.pythonPath}\n`); this.outputChannel.appendLine(`${'#'.repeat(10)} active linter: ${info.id}`); @@ -149,7 +154,9 @@ export class LintingEngine { .getline(m.line - 1) .trim() .startsWith('%') && - (m.code === LinterErrors.pylint.InvalidSyntax || m.code === LinterErrors.prospector.InvalidSyntax || m.code === LinterErrors.flake8.InvalidSyntax) + (m.code === LinterErrors.pylint.InvalidSyntax || + m.code === LinterErrors.prospector.InvalidSyntax || + m.code === LinterErrors.flake8.InvalidSyntax) ) { continue; } @@ -205,14 +212,14 @@ export class LintingEngine { } const fsPath = Uri.parse(document.uri).fsPath; - if (settings.stdLibs.some(p => fsPath.startsWith(p))) { + if (settings.stdLibs.some((p) => fsPath.startsWith(p))) { return false; } const relativeFileName = path.relative(workspace.root, fsPath); // { dot: true } is important so dirs like `.venv` will be matched by globs const ignoreMinmatches = settings.linting.ignorePatterns.map((pattern) => new Minimatch(pattern, { dot: true })); - if (ignoreMinmatches.some((matcher) => matcher.match(Uri.parse(document.uri).fsPath) || matcher.match(relativeFileName))) { + if (ignoreMinmatches.some((matcher) => matcher.match(fsPath) || matcher.match(relativeFileName))) { this.outputChannel.appendLine(`${'#'.repeat(5)} linting is ignored by python.linting.ignorePatterns`); return false; } diff --git a/src/features/linters/mypy.ts b/src/features/linters/mypy.ts index d3ce7632..d330a989 100644 --- a/src/features/linters/mypy.ts +++ b/src/features/linters/mypy.ts @@ -1,5 +1,5 @@ -import { CancellationToken, OutputChannel, TextDocument, Uri } from 'coc.nvim'; -import { ILinterInfo, ILintMessage } from '../../types'; +import { type CancellationToken, type OutputChannel, type TextDocument, Uri } from 'coc.nvim'; +import type { ILinterInfo, ILintMessage } from '../../types'; import { BaseLinter } from './baseLinter'; const COLUMN_OFF_SET = 1; @@ -13,10 +13,10 @@ export class MyPy extends BaseLinter { protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { const args = ['--python-executable', this.pythonSettings.pythonPath, Uri.parse(document.uri).fsPath]; const messages = await this.run(args, document, cancellation, REGEX); - messages.forEach((msg) => { + for (const msg of messages) { msg.severity = this.parseMessagesSeverity(msg.type, this.pythonSettings.linting.mypyCategorySeverity); msg.code = msg.type; - }); + } return messages; } } diff --git a/src/features/linters/prospector.ts b/src/features/linters/prospector.ts index d4196927..193398f7 100644 --- a/src/features/linters/prospector.ts +++ b/src/features/linters/prospector.ts @@ -1,6 +1,6 @@ -import { CancellationToken, OutputChannel, TextDocument, Uri, workspace } from 'coc.nvim'; -import path from 'path'; -import { ILinterInfo, ILintMessage } from '../../types'; +import { type CancellationToken, OutputChannel, type TextDocument, Uri, workspace } from 'coc.nvim'; +import path from 'node:path'; +import { ILinterInfo, type ILintMessage } from '../../types'; import { BaseLinter } from './baseLinter'; interface IProspectorResponse { @@ -21,10 +21,6 @@ interface IProspectorLocation { } export class Prospector extends BaseLinter { - constructor(info: ILinterInfo, outputChannel: OutputChannel) { - super(info, outputChannel); - } - protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { const relativePath = path.relative(workspace.root, Uri.parse(document.uri).fsPath); return this.run(['--absolute-paths', '--output-format=json', relativePath], document, cancellation); @@ -42,7 +38,7 @@ export class Prospector extends BaseLinter { return parsedData.messages .filter((_value, index) => index <= this.pythonSettings.linting.maxNumberOfProblems) .map((msg) => { - const lineNumber = msg.location.line === null || isNaN(msg.location.line) ? 1 : msg.location.line; + const lineNumber = msg.location.line === null || Number.isNaN(msg.location.line) ? 1 : msg.location.line; return { code: msg.code, diff --git a/src/features/linters/pycodestyle.ts b/src/features/linters/pycodestyle.ts index c04aa14b..c26835bb 100644 --- a/src/features/linters/pycodestyle.ts +++ b/src/features/linters/pycodestyle.ts @@ -1,5 +1,5 @@ -import { CancellationToken, OutputChannel, TextDocument, Uri } from 'coc.nvim'; -import { ILinterInfo, ILintMessage } from '../../types'; +import { type CancellationToken, type OutputChannel, type TextDocument, Uri } from 'coc.nvim'; +import type { ILinterInfo, ILintMessage } from '../../types'; import { BaseLinter } from './baseLinter'; const COLUMN_OFF_SET = 1; @@ -10,10 +10,14 @@ export class PyCodeStyle extends BaseLinter { } protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { - const messages = await this.run(['--format=%(row)d,%(col)d,%(code).1s,%(code)s:%(text)s', Uri.parse(document.uri).fsPath], document, cancellation); - messages.forEach((msg) => { + const messages = await this.run( + ['--format=%(row)d,%(col)d,%(code).1s,%(code)s:%(text)s', Uri.parse(document.uri).fsPath], + document, + cancellation, + ); + for (const msg of messages) { msg.severity = this.parseMessagesSeverity(msg.type, this.pythonSettings.linting.pycodestyleCategorySeverity); - }); + } return messages; } } diff --git a/src/features/linters/pydocstyle.ts b/src/features/linters/pydocstyle.ts index 5fc8d31b..43a50dfa 100644 --- a/src/features/linters/pydocstyle.ts +++ b/src/features/linters/pydocstyle.ts @@ -1,21 +1,17 @@ -import { CancellationToken, OutputChannel, TextDocument, Uri, workspace } from 'coc.nvim'; -import * as path from 'path'; -import { ILinterInfo, ILintMessage, LintMessageSeverity } from '../../types'; +import { Uri, workspace, type CancellationToken, type TextDocument } from 'coc.nvim'; +import * as path from 'node:path'; +import { LintMessageSeverity, type ILintMessage } from '../../types'; import { BaseLinter } from './baseLinter'; export class PyDocStyle extends BaseLinter { - constructor(info: ILinterInfo, outputChannel: OutputChannel) { - super(info, outputChannel); - } - protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { const baseFileName = path.basename(Uri.parse(document.uri).fsPath); if (/^test_.*\.py$/.test(baseFileName)) return []; const messages = await this.run([Uri.parse(document.uri).fsPath], document, cancellation); // All messages in pep8 are treated as warnings for now. - messages.forEach((msg) => { + for (const msg of messages) { msg.severity = LintMessageSeverity.Warning; - }); + } return messages; } diff --git a/src/features/linters/pyflakes.ts b/src/features/linters/pyflakes.ts index 5e089712..f163f1f6 100644 --- a/src/features/linters/pyflakes.ts +++ b/src/features/linters/pyflakes.ts @@ -1,19 +1,15 @@ -import { CancellationToken, OutputChannel, TextDocument, Uri } from 'coc.nvim'; -import { ILinterInfo, ILintMessage, LintMessageSeverity } from '../../types'; +import { Uri, type CancellationToken, type TextDocument } from 'coc.nvim'; +import { LintMessageSeverity, type ILintMessage } from '../../types'; import { BaseLinter } from './baseLinter'; const REGEX = '(?.*.py):(?\\d+):(?\\d+): (?.*)\\r?(\\n|$)'; export class Pyflakes extends BaseLinter { - constructor(info: ILinterInfo, outputChannel: OutputChannel) { - super(info, outputChannel); - } - protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { const messages = await this.run([Uri.parse(document.uri).fsPath], document, cancellation, REGEX); - messages.forEach((msg) => { + for (const msg of messages) { msg.severity = LintMessageSeverity.Warning; - }); + } return messages; } diff --git a/src/features/linters/pylama.ts b/src/features/linters/pylama.ts index 1a524051..49620a20 100644 --- a/src/features/linters/pylama.ts +++ b/src/features/linters/pylama.ts @@ -1,8 +1,9 @@ -import { CancellationToken, OutputChannel, TextDocument, Uri } from 'coc.nvim'; -import { ILinterInfo, ILintMessage, LintMessageSeverity } from '../../types'; +import { type CancellationToken, type OutputChannel, type TextDocument, Uri } from 'coc.nvim'; +import { type ILinterInfo, type ILintMessage, LintMessageSeverity } from '../../types'; import { BaseLinter } from './baseLinter'; -const REGEX = '(?.py):(?\\d+):(?\\d+): \\[(?\\w+)\\] (?\\w\\d+):? (?.*)\\r?(\\n|$)'; +const REGEX = + '(?.py):(?\\d+):(?\\d+): \\[(?\\w+)\\] (?\\w\\d+):? (?.*)\\r?(\\n|$)'; const COLUMN_OFF_SET = 1; export class Pylama extends BaseLinter { @@ -11,11 +12,16 @@ export class Pylama extends BaseLinter { } protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { - const messages = await this.run(['--format=parsable', Uri.parse(document.uri).fsPath], document, cancellation, REGEX); + const messages = await this.run( + ['--format=parsable', Uri.parse(document.uri).fsPath], + document, + cancellation, + REGEX, + ); // All messages in pylama are treated as warnings for now. - messages.forEach((msg) => { + for (const msg of messages) { msg.severity = LintMessageSeverity.Warning; - }); + } return messages; } diff --git a/src/features/linters/pylint.ts b/src/features/linters/pylint.ts index deb19c49..a4ea2c66 100644 --- a/src/features/linters/pylint.ts +++ b/src/features/linters/pylint.ts @@ -1,27 +1,28 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { CancellationToken, OutputChannel, TextDocument, Uri } from 'coc.nvim'; -import { ILinterInfo, ILintMessage } from '../../types'; +import { Uri, type CancellationToken, type TextDocument } from 'coc.nvim'; +import type { ILintMessage } from '../../types'; import { BaseLinter } from './baseLinter'; const REGEX = '(?\\d+),(?-?\\d+),(?\\w+),(?[\\w-]+):(?.*)\\r?(\\n|$)'; export class Pylint extends BaseLinter { - constructor(info: ILinterInfo, outputChannel: OutputChannel) { - super(info, outputChannel); - } - protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { - const args = ["--msg-template='{line},{column},{category},{symbol}:{msg}'", '--exit-zero', '--reports=n', '--output-format=text']; + const args = [ + "--msg-template='{line},{column},{category},{symbol}:{msg}'", + '--exit-zero', + '--reports=n', + '--output-format=text', + ]; if (this.info.stdinSupport) { args.push('--from-stdin'); } args.push(Uri.parse(document.uri).fsPath); const messages = await this.run(args, document, cancellation, REGEX); - messages.forEach((msg) => { + for (const msg of messages) { msg.severity = this.parseMessagesSeverity(msg.type, this.pythonSettings.linting.pylintCategorySeverity); - }); + } return messages; } diff --git a/src/features/linters/pytype.ts b/src/features/linters/pytype.ts index 42072266..fd42b54f 100644 --- a/src/features/linters/pytype.ts +++ b/src/features/linters/pytype.ts @@ -1,7 +1,7 @@ -import { CancellationToken, OutputChannel, TextDocument, Uri, workspace } from 'coc.nvim'; -import fs from 'fs'; -import * as path from 'path'; -import { ILinterInfo, ILintMessage, LintMessageSeverity } from '../../types'; +import { Uri, workspace, type CancellationToken, type TextDocument } from 'coc.nvim'; +import fs from 'node:fs'; +import * as path from 'node:path'; +import { LintMessageSeverity, type ILintMessage } from '../../types'; import { BaseLinter } from './baseLinter'; const pytypecfg = 'pytype.cfg'; @@ -62,10 +62,6 @@ async function pathExists(p: string) { } export class Pytype extends BaseLinter { - constructor(info: ILinterInfo, outputChannel: OutputChannel) { - super(info, outputChannel); - } - protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise { const args: string[] = []; if (await this.hasConfigurationFile(workspace.root)) { @@ -117,13 +113,12 @@ export class Pytype extends BaseLinter { return false; } - private arePathsSame(path1: string, path2: string): boolean { - path1 = path.normalize(path1); - path2 = path.normalize(path2); + private arePathsSame(p1: string, p2: string): boolean { + const path1 = path.normalize(p1); + const path2 = path.normalize(p2); if (this.isWindows) { return path1.toUpperCase() === path2.toUpperCase(); - } else { - return path1 === path2; } + return path1 === path2; } } diff --git a/src/features/linters/ruff.ts b/src/features/linters/ruff.ts index de1203b9..e3f80dcb 100644 --- a/src/features/linters/ruff.ts +++ b/src/features/linters/ruff.ts @@ -1,5 +1,14 @@ -import { CancellationToken, DiagnosticTag, OutputChannel, Range, TextDocument, TextEdit, Uri, WorkspaceEdit } from 'coc.nvim'; -import { ILinterInfo, ILintMessage, LintMessageSeverity } from '../../types'; +import { + type CancellationToken, + DiagnosticTag, + type OutputChannel, + Range, + type TextDocument, + TextEdit, + Uri, + type WorkspaceEdit, +} from 'coc.nvim'; +import { type ILinterInfo, type ILintMessage, LintMessageSeverity } from '../../types'; import { BaseLinter } from './baseLinter'; const COLUMN_OFF_SET = 1; @@ -66,13 +75,18 @@ export class Ruff extends BaseLinter { super(info, outputChannel, COLUMN_OFF_SET); } - private fixToWorkspaceEdit(filename: string, fix: IRuffFix): { title: string, edit: WorkspaceEdit } | null { + private fixToWorkspaceEdit(filename: string, fix: IRuffFix): { title: string; edit: WorkspaceEdit } | null { if (!fix) return null; const u = Uri.parse(filename).toString(); - if (fix.edits && fix.edits.length) { + if (fix.edits?.length) { const changes = fix.edits.map((edit) => { - const range = Range.create(edit.location.row - 1, edit.location.column - 1, edit.end_location.row - 1, edit.end_location.column - 1); + const range = Range.create( + edit.location.row - 1, + edit.location.column - 1, + edit.end_location.row - 1, + edit.end_location.column - 1, + ); return TextEdit.replace(range, edit.content); }); return { @@ -81,11 +95,16 @@ export class Ruff extends BaseLinter { changes: { [u]: changes, }, - }, }; - } else if (fix.location && fix.end_location) { - const range = Range.create(fix.location.row - 1, fix.location.column, fix.end_location.row - 1, fix.end_location.column); + } + if (fix.location && fix.end_location) { + const range = Range.create( + fix.location.row - 1, + fix.location.column, + fix.end_location.row - 1, + fix.end_location.column, + ); return { title: `Ruff: ${fix.message}`, edit: { diff --git a/src/features/lintting.ts b/src/features/lintting.ts index fdc6ec82..ff85f7c8 100644 --- a/src/features/lintting.ts +++ b/src/features/lintting.ts @@ -1,4 +1,14 @@ -import { commands, ConfigurationChangeEvent, DiagnosticCollection, DidChangeTextDocumentParams, Disposable, ExtensionContext, TextDocument, Uri, workspace } from 'coc.nvim'; +import { + commands, + type ConfigurationChangeEvent, + type DiagnosticCollection, + type DidChangeTextDocumentParams, + type Disposable, + type ExtensionContext, + type TextDocument, + Uri, + workspace, +} from 'coc.nvim'; import { PythonSettings } from '../configSettings'; import { LintingEngine } from './linters/lintingEngine'; @@ -18,7 +28,7 @@ export class LinterProvider implements Disposable { workspace.onDidOpenTextDocument((e) => this.onDocumentOpened(e), this.context.subscriptions); workspace.onDidCloseTextDocument((e) => this.onDocumentClosed(e), this.context.subscriptions); workspace.onDidSaveTextDocument((e) => this.onDocumentSaved(e), this.context.subscriptions); - workspace.onDidChangeTextDocument(e => this.onDocumentChanged(e), this.context.subscriptions); + workspace.onDidChangeTextDocument((e) => this.onDocumentChanged(e), this.context.subscriptions); const disposable = workspace.onDidChangeConfiguration(this.lintSettingsChangedHandler.bind(this)); this.disposables.push(disposable); @@ -29,7 +39,9 @@ export class LinterProvider implements Disposable { } public dispose() { - this.disposables.forEach((d) => d.dispose()); + for (const d of this.disposables) { + d.dispose(); + } } private runLinting(): Promise { @@ -38,11 +50,11 @@ export class LinterProvider implements Disposable { private lintSettingsChangedHandler(e: ConfigurationChangeEvent) { // Look for python files that belong to the specified workspace folder. - workspace.textDocuments.forEach((document) => { + for (const document of workspace.textDocuments) { if (e.affectsConfiguration('python.linting', document.uri)) { this.engine.lintDocument(document).catch(() => {}); } - }); + } } private onDocumentOpened(document: TextDocument): void { diff --git a/src/features/refactor.ts b/src/features/refactor.ts index c983881c..54bdc41a 100644 --- a/src/features/refactor.ts +++ b/src/features/refactor.ts @@ -1,26 +1,40 @@ -import { ChildProcess } from 'child_process'; -import { Disposable, Document, OutputChannel, Position, Range, TextDocument, Uri, window, workspace } from 'coc.nvim'; -import * as path from 'path'; -import fs from 'fs'; -import { createDeferred, Deferred } from '../async'; +import type { ChildProcess } from 'node:child_process'; +import { + type Disposable, + type Document, + type OutputChannel, + Position, + type Range, + type TextDocument, + Uri, + window, + workspace, +} from 'coc.nvim'; +import * as path from 'node:path'; +import fs from 'node:fs'; +import { createDeferred, type Deferred } from '../async'; import { PythonSettings } from '../configSettings'; import { PythonExecutionService } from '../processService'; -import { IPythonSettings } from '../types'; -import { getTextEditsFromPatch, getWindowsLineEndingCount, splitLines, getTempFileWithDocumentContents } from '../utils'; +import type { IPythonSettings } from '../types'; +import { + getTextEditsFromPatch, + getWindowsLineEndingCount, + splitLines, + getTempFileWithDocumentContents, +} from '../utils'; class RefactorProxy implements Disposable { protected readonly isWindows = process.platform === 'win32'; private _process?: ChildProcess; - private _extensionDir: string; - private _previousOutData = ''; - private _previousStdErrData = ''; private _startedSuccessfully = false; private _commandResolve?: (value?: any | PromiseLike) => void; private _commandReject!: (reason?: any) => void; private initialized!: Deferred; - constructor(extensionDir: string, readonly pythonSettings: IPythonSettings, private workspaceRoot: string) { - this._extensionDir = extensionDir; - } + constructor( + private extensionDir: string, + readonly pythonSettings: IPythonSettings, + private workspaceRoot: string, + ) {} public dispose() { try { @@ -95,13 +109,13 @@ class RefactorProxy implements Disposable { return await new Promise((resolve, reject) => { this._commandResolve = resolve; this._commandReject = reject; - this._process!.stdin!.write(command + '\n'); + this._process!.stdin!.write(`${command}\n`); }); } private async initialize(): Promise { this.initialized = createDeferred(); - const cwd = path.join(this._extensionDir, 'pythonFiles'); + const cwd = path.join(this.extensionDir, 'pythonFiles'); const args = ['refactor.py', this.workspaceRoot]; const pythonToolsExecutionService = new PythonExecutionService(); const result = pythonToolsExecutionService.execObservable(this.pythonSettings.pythonPath, args, { cwd }); @@ -127,23 +141,24 @@ class RefactorProxy implements Disposable { private handleStdError(data: string) { // Possible there was an exception in parsing the data returned // So append the data then parse it - const dataStr = (this._previousStdErrData = this._previousStdErrData + data + ''); let errorResponse: { message: string; traceback: string; type: string }[]; try { - errorResponse = dataStr + errorResponse = data .split(/\r?\n/g) .filter((line) => line.length > 0) .map((resp) => JSON.parse(resp)); - this._previousStdErrData = ''; } catch (ex) { console.error(ex); // Possible we've only received part of the data, hence don't clear previousData return; } if (errorResponse[0].message.length === 0) { - errorResponse[0].message = splitLines(errorResponse[0].traceback, { trim: false, removeEmptyEntries: false }).pop()!; + errorResponse[0].message = splitLines(errorResponse[0].traceback, { + trim: false, + removeEmptyEntries: false, + }).pop()!; } - const errorMessage = errorResponse[0].message + '\n' + errorResponse[0].traceback; + const errorMessage = `${errorResponse[0].message}\n${errorResponse[0].traceback}`; if (this._startedSuccessfully) { this._commandReject(`Refactor failed. ${errorMessage}`); @@ -171,14 +186,12 @@ class RefactorProxy implements Disposable { // Possible there was an exception in parsing the data returned // So append the data then parse it - const dataStr = (this._previousOutData = this._previousOutData + data + ''); let response: any; try { - response = dataStr + response = data .split(/\r?\n/g) .filter((line) => line.length > 0) .map((resp) => JSON.parse(resp)); - this._previousOutData = ''; } catch (ex) { // Possible we've only received part of the data, hence don't clear previousData return; @@ -205,11 +218,16 @@ function validateDocumentForRefactor(doc: Document): Promise { }); } -export async function extractVariable(root: string, document: TextDocument, range: Range, outputChannel: OutputChannel): Promise { +export async function extractVariable( + root: string, + document: TextDocument, + range: Range, + outputChannel: OutputChannel, +): Promise { const pythonToolsExecutionService = new PythonExecutionService(); const rope = await pythonToolsExecutionService.isModuleInstalled('rope'); if (!rope) { - window.showWarningMessage(`Module rope not installed`); + window.showWarningMessage('Module rope not installed'); return; } @@ -222,19 +240,26 @@ export async function extractVariable(root: string, document: TextDocument, rang return validateDocumentForRefactor(doc).then(() => { const newName = `newvariable${new Date().getMilliseconds().toString()}`; const proxy = new RefactorProxy(root, pythonSettings, workspaceRoot); - const rename = proxy.extractVariable(doc.textDocument, newName, tempFile, range).then((response) => { - return response.results[0].diff; - }); + const rename = proxy + .extractVariable(doc.textDocument, newName, tempFile, range) + .then((response) => { + return response.results[0].diff; + }); return extractName(doc, newName, rename, outputChannel, tempFile); }); } -export async function extractMethod(root: string, document: TextDocument, range: Range, outputChannel: OutputChannel): Promise { +export async function extractMethod( + root: string, + document: TextDocument, + range: Range, + outputChannel: OutputChannel, +): Promise { const pythonToolsExecutionService = new PythonExecutionService(); const rope = await pythonToolsExecutionService.isModuleInstalled('rope'); if (!rope) { - window.showWarningMessage(`Module rope not installed`); + window.showWarningMessage('Module rope not installed'); return; } @@ -255,7 +280,13 @@ export async function extractMethod(root: string, document: TextDocument, range: }); } -async function extractName(textEditor: Document, newName: string, renameResponse: Promise, outputChannel: OutputChannel, tempFile: string): Promise { +async function extractName( + textEditor: Document, + newName: string, + renameResponse: Promise, + outputChannel: OutputChannel, + tempFile: string, +): Promise { let changeStartsAtLine = -1; try { const diff = await renameResponse; @@ -263,11 +294,11 @@ async function extractName(textEditor: Document, newName: string, renameResponse return []; } const edits = getTextEditsFromPatch(textEditor.getDocumentContent(), diff); - edits.forEach((edit) => { + for (const edit of edits) { if (changeStartsAtLine === -1 || changeStartsAtLine > edit.range.start.line) { changeStartsAtLine = edit.range.start.line; } - }); + } await textEditor.applyEdits(edits); await fs.promises.unlink(tempFile); @@ -296,7 +327,7 @@ async function extractName(textEditor: Document, newName: string, renameResponse outputChannel.appendLine(`${'#'.repeat(10)}Refactor Output${'#'.repeat(10)}`); outputChannel.appendLine(`Error in refactoring:\n${errorMessage}`); outputChannel.appendLine(''); - window.showErrorMessage(`Cannot perform refactoring using selected element(s).`); + window.showErrorMessage('Cannot perform refactoring using selected element(s).'); return await Promise.reject(error); } } diff --git a/src/features/semanticTokens.ts b/src/features/semanticTokens.ts index 6ceb3858..0b78053b 100644 --- a/src/features/semanticTokens.ts +++ b/src/features/semanticTokens.ts @@ -1,14 +1,14 @@ import { convertOffsetsToRange, convertTextRangeToRange } from '@zzzen/pyright-internal/dist/common/positionUtils'; import { - CancellationToken, - DocumentSemanticTokensProvider, - LinesTextDocument, - ProviderResult, + type CancellationToken, + type DocumentSemanticTokensProvider, + type LinesTextDocument, + type ProviderResult, SemanticTokenModifiers, SemanticTokenTypes, - SemanticTokens, + type SemanticTokens, SemanticTokensBuilder, - SemanticTokensLegend, + type SemanticTokensLegend, } from 'coc.nvim'; import * as parser from '../parsers'; import { SemanticTokensWalker } from '../parsers'; @@ -28,7 +28,11 @@ const tokenTypes: string[] = [ SemanticTokenTypes.variable, ]; -const tokenModifiers: string[] = [SemanticTokenModifiers.definition, SemanticTokenModifiers.declaration, SemanticTokenModifiers.async]; +const tokenModifiers: string[] = [ + SemanticTokenModifiers.definition, + SemanticTokenModifiers.declaration, + SemanticTokenModifiers.async, +]; function encodeTokenType(type: string): number { const idx = tokenTypes.indexOf(type); @@ -53,10 +57,13 @@ function encodeTokenModifiers(modifiers: string[]): number { export class PythonSemanticTokensProvider implements DocumentSemanticTokensProvider { public readonly legend: SemanticTokensLegend = { tokenTypes, tokenModifiers }; - public provideDocumentSemanticTokens(document: LinesTextDocument, token: CancellationToken): ProviderResult { + public provideDocumentSemanticTokens( + document: LinesTextDocument, + token: CancellationToken, + ): ProviderResult { const parsed = parser.parse(document.getText()); if (!parsed) return null; - if (token && token.isCancellationRequested) return null; + if (token?.isCancellationRequested) return null; const builder = new SemanticTokensBuilder(this.legend); // @ts-ignore @@ -72,7 +79,13 @@ export class PythonSemanticTokensProvider implements DocumentSemanticTokensProvi for (const item of walker.semanticItems) { const range = convertOffsetsToRange(item.start, item.start + item.length, parsed.tokenizerOutput.lines); - builder.push(range.start.line, range.start.character, item.length, encodeTokenType(item.type), encodeTokenModifiers(item.modifiers)); + builder.push( + range.start.line, + range.start.character, + item.length, + encodeTokenType(item.type), + encodeTokenModifiers(item.modifiers), + ); } return builder.build(); diff --git a/src/features/sortImports.ts b/src/features/sortImports.ts index ef157bef..f12ac836 100644 --- a/src/features/sortImports.ts +++ b/src/features/sortImports.ts @@ -1,9 +1,9 @@ -import { OutputChannel, TextDocument, commands, window, workspace } from 'coc.nvim'; -import fs from 'fs'; +import { type OutputChannel, type TextDocument, commands, window, workspace } from 'coc.nvim'; +import fs from 'node:fs'; import which from 'which'; import { PythonSettings } from '../configSettings'; import { PythonExecutionService } from '../processService'; -import { ExecutionInfo } from '../types'; +import type { ExecutionInfo } from '../types'; import { getTempFileWithDocumentContents, getTextEditsFromPatch } from '../utils'; type SortProvider = 'pyright' | 'isort' | 'ruff'; @@ -23,7 +23,11 @@ function getSortProviderInfo(provider: SortProvider): ExecutionInfo { return { execPath, args }; } -async function generateImportsDiff(provider: SortProvider, document: TextDocument, outputChannel: OutputChannel): Promise { +async function generateImportsDiff( + provider: SortProvider, + document: TextDocument, + outputChannel: OutputChannel, +): Promise { const tempFile = await getTempFileWithDocumentContents(document); const executionInfo = getSortProviderInfo(provider); @@ -70,6 +74,6 @@ export async function sortImports(outputChannel: OutputChannel): Promise { } outputChannel.appendLine(`${'#'.repeat(10)} sortImports Error ${'#'.repeat(10)}`); outputChannel.appendLine(message); - window.showErrorMessage(`Failed to sort imports`); + window.showErrorMessage('Failed to sort imports'); } } diff --git a/src/features/testing.ts b/src/features/testing.ts index 54763fed..8fa20d08 100644 --- a/src/features/testing.ts +++ b/src/features/testing.ts @@ -1,7 +1,19 @@ -import { CodeAction, CodeActionKind, CodeActionProvider, CodeLens, CodeLensProvider, events, LinesTextDocument, Position, Range, Uri, workspace } from 'coc.nvim'; -import path from 'path'; +import { + type CodeAction, + CodeActionKind, + type CodeActionProvider, + type CodeLens, + type CodeLensProvider, + events, + type LinesTextDocument, + Position, + Range, + Uri, + workspace, +} from 'coc.nvim'; +import path from 'node:path'; import * as parser from '../parsers'; -import { TestingFramework } from '../types'; +import type { TestingFramework } from '../types'; import { rangeInRange } from '../utils'; export class TestFrameworkProvider implements CodeLensProvider, CodeActionProvider { diff --git a/src/index.ts b/src/index.ts index e3ac8d17..bc179363 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,23 +1,23 @@ import { commands, - DocumentSelector, - ExtensionContext, + type DocumentSelector, + type ExtensionContext, extensions, LanguageClient, - LanguageClientOptions, + type LanguageClientOptions, languages, - Range, - ServerOptions, + type Range, + type ServerOptions, services, - StaticFeature, - TextDocument, + type StaticFeature, + type TextDocument, TransportKind, Uri, window, workspace, } from 'coc.nvim'; -import { existsSync, readFileSync } from 'fs'; -import { join } from 'path'; +import { existsSync, readFileSync } from 'node:fs'; +import { join } from 'node:path'; import which from 'which'; import { runFileTest, runSingleTest } from './commands'; import { PythonSettings } from './configSettings'; @@ -30,7 +30,14 @@ import { sortImports } from './features/sortImports'; import { LinterProvider } from './features/lintting'; import { extractMethod, extractVariable } from './features/refactor'; import { TestFrameworkProvider } from './features/testing'; -import { configuration, handleDiagnostics, provideCompletionItem, provideHover, provideSignatureHelp, resolveCompletionItem } from './middleware'; +import { + configuration, + handleDiagnostics, + provideCompletionItem, + provideHover, + provideSignatureHelp, + resolveCompletionItem, +} from './middleware'; const defaultHeapSize = 3072; @@ -43,7 +50,6 @@ const documentSelector: DocumentSelector = [ ]; class PyrightExtensionFeature implements StaticFeature { - constructor() {} dispose(): void {} initialize() {} fillClientCapabilities(capabilities: any) { @@ -60,7 +66,7 @@ export async function activate(context: ExtensionContext): Promise { const state = extensions.getExtensionState('coc-python'); if (state.toString() === 'activated') { - window.showWarningMessage(`coc-python is installed and activated, coc-pyright will be disabled`); + window.showWarningMessage('coc-python is installed and activated, coc-pyright will be disabled'); return; } let module = pyrightCfg.get('server'); @@ -136,7 +142,9 @@ export async function activate(context: ExtensionContext): Promise { const importSupport = pyrightCfg.get('completion.importSupport'); if (importSupport) { const provider = new ImportCompletionProvider(); - context.subscriptions.push(languages.registerCompletionItemProvider('python-import', 'PY', ['python'], provider, [' '])); + context.subscriptions.push( + languages.registerCompletionItemProvider('python-import', 'PY', ['python'], provider, [' ']), + ); } const inlayHintEnable = workspace.getConfiguration('inlayHint').get('enable', true); if (inlayHintEnable && typeof languages.registerInlayHintsProvider === 'function') { @@ -146,7 +154,9 @@ export async function activate(context: ExtensionContext): Promise { const semanticTokensEnable = workspace.getConfiguration('semanticTokens').get('enable', true); if (semanticTokensEnable && typeof languages.registerDocumentSemanticTokensProvider === 'function') { const provider = new PythonSemanticTokensProvider(); - context.subscriptions.push(languages.registerDocumentSemanticTokensProvider(documentSelector, provider, provider.legend)); + context.subscriptions.push( + languages.registerDocumentSemanticTokensProvider(documentSelector, provider, provider.legend), + ); } const testProvider = new TestFrameworkProvider(); context.subscriptions.push(languages.registerCodeActionProvider(documentSelector, testProvider, 'Pyright')); @@ -154,7 +164,7 @@ export async function activate(context: ExtensionContext): Promise { if (codeLens) context.subscriptions.push(languages.registerCodeLensProvider(documentSelector, testProvider)); const textEditorCommands = ['pyright.organizeimports', 'pyright.addoptionalforparam']; - textEditorCommands.forEach((commandName: string) => { + for (const commandName of textEditorCommands) { context.subscriptions.push( commands.registerCommand(commandName, async (offset: number) => { const doc = await workspace.document; @@ -164,9 +174,9 @@ export async function activate(context: ExtensionContext): Promise { }; await client.sendRequest(method, cmd); - }) + }), ); - }); + } let command = 'pyright.restartserver'; let disposable = commands.registerCommand(command, async () => { @@ -177,7 +187,7 @@ export async function activate(context: ExtensionContext): Promise { command = 'pyright.createtypestub'; disposable = commands.registerCommand(command, async (...args: any[]) => { if (!args.length) { - window.showWarningMessage(`Module name is missing`); + window.showWarningMessage('Module name is missing'); return; } const doc = await workspace.document; @@ -203,7 +213,7 @@ export async function activate(context: ExtensionContext): Promise { await extractVariable(context.extensionPath, document, range, outputChannel).catch(() => {}); }, null, - true + true, ); context.subscriptions.push(disposable); @@ -213,7 +223,7 @@ export async function activate(context: ExtensionContext): Promise { await extractMethod(context.extensionPath, document, range, outputChannel).catch(() => {}); }, null, - true + true, ); context.subscriptions.push(disposable); diff --git a/src/middleware.ts b/src/middleware.ts index f8769381..c40d08e3 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,19 +1,19 @@ import { - CancellationToken, - CompletionContext, - CompletionItem, + type CancellationToken, + type CompletionContext, + type CompletionItem, CompletionItemKind, - ConfigurationParams, - Diagnostic, - HandleDiagnosticsSignature, + type ConfigurationParams, + type Diagnostic, + type HandleDiagnosticsSignature, InsertTextFormat, - LinesTextDocument, - Position, - ProvideCompletionItemsSignature, - ProvideHoverSignature, - ProvideSignatureHelpSignature, - ResolveCompletionItemSignature, - SignatureHelpContext, + type LinesTextDocument, + type Position, + type ProvideCompletionItemsSignature, + type ProvideHoverSignature, + type ProvideSignatureHelpSignature, + type ResolveCompletionItemSignature, + type SignatureHelpContext, workspace, } from 'coc.nvim'; import { PythonSettings } from './configSettings'; @@ -22,7 +22,8 @@ function toJSONObject(obj: any): any { if (obj) { if (Array.isArray(obj)) { return obj.map(toJSONObject); - } else if (typeof obj === 'object') { + } + if (typeof obj === 'object') { const res = Object.create(null); for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { @@ -46,8 +47,13 @@ export function configuration(params: ConfigurationParams, token: CancellationTo const analysis = config['analysis']; analysis['stubPath'] = workspace.expand(analysis['stubPath'] as string); const inspect = workspace.getConfiguration('python.analysis').inspect('stubPath'); - if (inspect && (inspect.globalValue === undefined || inspect.workspaceValue === undefined || inspect.workspaceFolderValue === undefined)) { - delete analysis['stubPath']; + if ( + inspect && + (inspect.globalValue === undefined || + inspect.workspaceValue === undefined || + inspect.workspaceFolderValue === undefined) + ) { + analysis['stubPath'] = undefined; } const extraPaths = analysis['extraPaths'] as string[]; if (extraPaths?.length) { @@ -68,8 +74,13 @@ export function configuration(params: ConfigurationParams, token: CancellationTo const analysis = toJSONObject(workspace.getConfiguration(analysisItem.section, analysisItem.scopeUri)); analysis['stubPath'] = workspace.expand(analysis['stubPath'] as string); const inspect = workspace.getConfiguration('python.analysis').inspect('stubPath'); - if (inspect && (inspect.globalValue === undefined || inspect.workspaceValue === undefined || inspect.workspaceFolderValue === undefined)) { - delete analysis['stubPath']; + if ( + inspect && + (inspect.globalValue === undefined || + inspect.workspaceValue === undefined || + inspect.workspaceFolderValue === undefined) + ) { + analysis['stubPath'] = undefined; } const extraPaths = analysis['extraPaths'] as string[]; if (extraPaths?.length) { @@ -93,12 +104,13 @@ export async function provideCompletionItem( position: Position, context: CompletionContext, token: CancellationToken, - next: ProvideCompletionItemsSignature + next: ProvideCompletionItemsSignature, ) { const result = await next(document, position, context, token); if (!result) return; const items = Array.isArray(result) ? result : result.items; + // biome-ignore lint/suspicious/noAssignInExpressions: ignore items.map((x) => (x.sortText ? (x.sortText = x.sortText.toLowerCase()) : (x.sortText = x.label.toLowerCase()))); const snippetSupport = workspace.getConfiguration('pyright').get('completion.snippetSupport'); @@ -115,15 +127,29 @@ export async function provideCompletionItem( return Array.isArray(result) ? items : { items, isIncomplete: result.isIncomplete }; } -export async function resolveCompletionItem(item: CompletionItem, token: CancellationToken, next: ResolveCompletionItemSignature) { +export async function resolveCompletionItem( + item: CompletionItem, + token: CancellationToken, + next: ResolveCompletionItemSignature, +) { const result = await next(item, token); - if (result && typeof result.documentation === 'object' && 'kind' in result.documentation && result.documentation.kind === 'markdown') { + if ( + result && + typeof result.documentation === 'object' && + 'kind' in result.documentation && + result.documentation.kind === 'markdown' + ) { result.documentation.value = result.documentation.value.replace(/ /g, ' '); } return result; } -export async function provideHover(document: LinesTextDocument, position: Position, token: CancellationToken, next: ProvideHoverSignature) { +export async function provideHover( + document: LinesTextDocument, + position: Position, + token: CancellationToken, + next: ProvideHoverSignature, +) { const hover = await next(document, position, token); if (hover && typeof hover.contents === 'object' && 'kind' in hover.contents && hover.contents.kind === 'markdown') { hover.contents.value = hover.contents.value.replace(/ /g, ' '); @@ -136,15 +162,15 @@ export async function provideSignatureHelp( position: Position, context: SignatureHelpContext, token: CancellationToken, - next: ProvideSignatureHelpSignature + next: ProvideSignatureHelpSignature, ) { const sign = await next(document, position, context, token); - if (sign && sign.signatures.length) { - sign.signatures.forEach((info) => { + if (sign?.signatures.length) { + for (const info of sign.signatures) { if (info.documentation && typeof info.documentation === 'object' && info.documentation.kind === 'markdown') { info.documentation.value = info.documentation.value.replace(/ /g, ' '); } - }); + } } return sign; @@ -153,6 +179,6 @@ export async function provideSignatureHelp( export async function handleDiagnostics(uri: string, diagnostics: Diagnostic[], next: HandleDiagnosticsSignature) { next( uri, - diagnostics.filter((d) => d.message !== '"__" is not accessed') + diagnostics.filter((d) => d.message !== '"__" is not accessed'), ); } diff --git a/src/parsers/index.ts b/src/parsers/index.ts index e3208187..8058e816 100644 --- a/src/parsers/index.ts +++ b/src/parsers/index.ts @@ -1,5 +1,5 @@ import { DiagnosticSink } from '@zzzen/pyright-internal/dist/common/diagnosticSink'; -import { ParseOptions, ParseFileResults, Parser } from '@zzzen/pyright-internal/dist/parser/parser'; +import { ParseOptions, type ParseFileResults, Parser } from '@zzzen/pyright-internal/dist/parser/parser'; import { TypeInlayHintsWalker } from './inlayHints'; import { SemanticTokensWalker } from './semanticTokens'; import { FunctionFormatItemType, TestFrameworkWalker } from './testFramework'; diff --git a/src/parsers/inlayHints.ts b/src/parsers/inlayHints.ts index 73774b48..9f52bf47 100644 --- a/src/parsers/inlayHints.ts +++ b/src/parsers/inlayHints.ts @@ -1,7 +1,15 @@ import { getCallNodeAndActiveParameterIndex } from '@zzzen/pyright-internal/dist/analyzer/parseTreeUtils'; import { ParseTreeWalker } from '@zzzen/pyright-internal/dist/analyzer/parseTreeWalker'; -import { ArgumentNode, AssignmentNode, FunctionNode, MemberAccessNode, NameNode, ParseNode, ParseNodeType } from '@zzzen/pyright-internal/dist/parser/parseNodes'; -import { ParseFileResults } from '@zzzen/pyright-internal/dist/parser/parser'; +import { + type ArgumentNode, + type AssignmentNode, + type FunctionNode, + type MemberAccessNode, + type NameNode, + type ParseNode, + ParseNodeType, +} from '@zzzen/pyright-internal/dist/parser/parseNodes'; +import type { ParseFileResults } from '@zzzen/pyright-internal/dist/parser/parser'; type TypeInlayHintsItemType = { inlayHintType: 'variable' | 'functionReturn' | 'parameter'; diff --git a/src/parsers/semanticTokens.ts b/src/parsers/semanticTokens.ts index fabd957a..13ef18a1 100644 --- a/src/parsers/semanticTokens.ts +++ b/src/parsers/semanticTokens.ts @@ -1,23 +1,23 @@ import { ParseTreeWalker } from '@zzzen/pyright-internal/dist/analyzer/parseTreeWalker'; import { - CallNode, - ClassNode, - DecoratorNode, - ForNode, - FormatStringNode, - FunctionNode, - ImportAsNode, - ImportFromAsNode, - ImportFromNode, - ImportNode, - MemberAccessNode, - NameNode, - ParameterNode, - ParseNode, - ParseNodeBase, + type CallNode, + type ClassNode, + type DecoratorNode, + type ForNode, + type FormatStringNode, + type FunctionNode, + type ImportAsNode, + type ImportFromAsNode, + type ImportFromNode, + type ImportNode, + type MemberAccessNode, + type NameNode, + type ParameterNode, + type ParseNode, + type ParseNodeBase, ParseNodeType, - TypeAnnotationNode, - TypeParameterNode, + type TypeAnnotationNode, + type TypeParameterNode, } from '@zzzen/pyright-internal/dist/parser/parseNodes'; import { SemanticTokenModifiers, SemanticTokenTypes } from 'coc.nvim'; @@ -127,7 +127,7 @@ export class SemanticTokensWalker extends ParseTreeWalker { } visitImportAs(node: ImportAsNode): boolean { - if (node.alias && node.alias.value.length) { + if (node.alias?.value.length) { this.addItem(node.alias, SemanticTokenTypes.namespace); } node.module.nameParts.map((x) => this.addItem(x, SemanticTokenTypes.namespace)); @@ -142,7 +142,7 @@ export class SemanticTokensWalker extends ParseTreeWalker { } visitImportFromAs(node: ImportFromAsNode): boolean { - if (node.alias && node.alias.value.length) { + if (node.alias?.value.length) { this.addItem(node.alias, SemanticTokenTypes.namespace); } return super.visitImportFromAs(node); diff --git a/src/parsers/testFramework.ts b/src/parsers/testFramework.ts index 43ce6e1a..b9bc20cc 100644 --- a/src/parsers/testFramework.ts +++ b/src/parsers/testFramework.ts @@ -1,7 +1,7 @@ import { printParseNodeType } from '@zzzen/pyright-internal/dist/analyzer/parseTreeUtils'; import { ParseTreeWalker } from '@zzzen/pyright-internal/dist/analyzer/parseTreeWalker'; -import { ClassNode, FunctionNode, SuiteNode } from '@zzzen/pyright-internal/dist/parser/parseNodes'; -import { TestingFramework } from '../types'; +import type { ClassNode, FunctionNode, SuiteNode } from '@zzzen/pyright-internal/dist/parser/parseNodes'; +import type { TestingFramework } from '../types'; export type FunctionFormatItemType = { value: string; diff --git a/src/processService.ts b/src/processService.ts index 8502ddb8..bcc64ce6 100644 --- a/src/processService.ts +++ b/src/processService.ts @@ -1,12 +1,12 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -import { ExecOptions, spawn, SpawnOptions as ChildProcessSpawnOptions } from 'child_process'; -import { CancellationToken } from 'coc.nvim'; +import { type ExecOptions, spawn, type SpawnOptions as ChildProcessSpawnOptions } from 'node:child_process'; +import type { CancellationToken } from 'coc.nvim'; import * as iconv from 'iconv-lite'; -import { homedir } from 'os'; +import { homedir } from 'node:os'; import { Observable } from 'rxjs'; import { createDeferred } from './async'; import { PythonSettings } from './configSettings'; -import { ExecutionInfo, ExecutionResult, ObservableExecutionResult, Output } from './types'; +import type { ExecutionInfo, ExecutionResult, ObservableExecutionResult, Output } from './types'; const DEFAULT_ENCODING = 'utf8'; @@ -19,24 +19,12 @@ type SpawnOptions = ChildProcessSpawnOptions & { }; class BufferDecoder { - public decode(buffers: Buffer[], encoding: string = DEFAULT_ENCODING): string { - encoding = iconv.encodingExists(encoding) ? encoding : DEFAULT_ENCODING; + public decode(buffers: Buffer[], value: string = DEFAULT_ENCODING): string { + const encoding = iconv.encodingExists(value) ? value : DEFAULT_ENCODING; return iconv.decode(Buffer.concat(buffers), encoding); } } -class StdErrError extends Error { - constructor(message: string) { - super(message); - } -} - -class ErrorUtils { - public static outputHasModuleNotInstalledError(moduleName: string, content?: string): boolean { - return content && (content!.indexOf(`No module named ${moduleName}`) > 0 || content!.indexOf(`No module named '${moduleName}'`) > 0) ? true : false; - } -} - class ModuleNotInstalledError extends Error { constructor(moduleName: string) { super(`Module '${moduleName}' not installed.`); @@ -58,7 +46,6 @@ export function isNotInstalledError(error: Error): boolean { } class ProcessService { - constructor() {} private readonly decoder = new BufferDecoder(); public static isAlive(pid: number): boolean { @@ -80,7 +67,7 @@ class ProcessService { public execObservable(file: string, args: string[], options: SpawnOptions = {}): ObservableExecutionResult { const spawnOptions = this.getDefaultOptions(options); - const encoding = spawnOptions.encoding ? spawnOptions.encoding : 'utf8'; + const encoding = spawnOptions.encoding ? spawnOptions.encoding : DEFAULT_ENCODING; const proc = spawn(file, args, spawnOptions); let procExited = false; @@ -97,7 +84,7 @@ class ProcessService { const sendOutput = (source: 'stdout' | 'stderr', data: Buffer) => { const out = this.decoder.decode([data], encoding); if (source === 'stderr' && options.throwOnStdErr) { - subscriber.error(new StdErrError(out)); + subscriber.error(new Error(out)); } else { subscriber.next({ source, out }); } @@ -130,12 +117,10 @@ class ProcessService { } public exec(file: string, args: string[], options: SpawnOptions = {}): Promise> { - if (file.startsWith('~/')) { - file = file.replace('~', homedir()); - } + const cmd = file.startsWith('~/') ? file.replace('~', homedir()) : file; const spawnOptions = this.getDefaultOptions(options); const encoding = spawnOptions.encoding ? spawnOptions.encoding : DEFAULT_ENCODING; - const proc = spawn(file, args, spawnOptions); + const proc = spawn(cmd, args, spawnOptions); const deferred = createDeferred>(); if (options.token) { @@ -162,9 +147,9 @@ class ProcessService { if (deferred.completed) { return; } - const stderr: string | undefined = stderrBuffers.length === 0 ? undefined : this.decoder.decode(stderrBuffers, encoding); + const stderr = stderrBuffers.length === 0 ? undefined : this.decoder.decode(stderrBuffers, encoding); if (stderr && stderr.length > 0 && options.throwOnStdErr) { - deferred.reject(new StdErrError(stderr)); + deferred.reject(new Error(stderr)); } else { const stdout = this.decoder.decode(stdoutBuffers, encoding); deferred.resolve({ stdout, stderr }); @@ -180,12 +165,6 @@ class ProcessService { private getDefaultOptions(options: T): T { const defaultOptions = { ...options }; - const execOptions = defaultOptions as SpawnOptions; - if (execOptions) { - const encoding = (execOptions.encoding = typeof execOptions.encoding === 'string' && execOptions.encoding.length > 0 ? execOptions.encoding : DEFAULT_ENCODING); - delete execOptions.encoding; - execOptions.encoding = encoding; - } if (!defaultOptions.env || Object.keys(defaultOptions.env).length === 0) { defaultOptions.env = { ...process.env }; } else { @@ -206,8 +185,6 @@ export class PythonExecutionService { private readonly procService = new ProcessService(); private readonly pythonSettings = PythonSettings.getInstance(); - constructor() {} - public async isModuleInstalled(moduleName: string): Promise { return this.procService .exec(this.pythonSettings.pythonPath, ['-c', `import ${moduleName}`], { throwOnStdErr: true }) @@ -228,7 +205,11 @@ export class PythonExecutionService { const result = await this.procService.exec(this.pythonSettings.pythonPath, ['-m', moduleName, ...args], opts); // If a module is not installed we'll have something in stderr. - if (ErrorUtils.outputHasModuleNotInstalledError(moduleName, result.stderr)) { + if ( + result.stderr && + (result.stderr.indexOf(`No module named ${moduleName}`) > 0 || + result.stderr.indexOf(`No module named '${moduleName}'`) > 0) + ) { throw new ModuleNotInstalledError(moduleName!); } diff --git a/src/systemVariables.ts b/src/systemVariables.ts index 03ae4e1f..99bf8c09 100644 --- a/src/systemVariables.ts +++ b/src/systemVariables.ts @@ -3,18 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import * as Path from 'path'; -import { IStringDictionary, ISystemVariables } from './types'; - -const _typeof = { - number: 'number', - string: 'string', - undefined: 'undefined', - object: 'object', - function: 'function', -}; +import * as Path from 'node:path'; +import type { IStringDictionary, ISystemVariables } from './types'; /** * @returns whether the provided parameter is a JavaScript Array or not. @@ -24,7 +14,7 @@ function isArray(array: any): array is any[] { return Array.isArray(array); } - if (array && typeof array.length === _typeof.number && array.constructor === Array) { + if (array && typeof array.length === 'number' && array.constructor === Array) { return true; } @@ -35,7 +25,7 @@ function isArray(array: any): array is any[] { * @returns whether the provided parameter is a JavaScript String or not. */ function isString(str: any): str is string { - if (typeof str === _typeof.string || str instanceof String) { + if (typeof str === 'string' || str instanceof String) { return true; } @@ -48,7 +38,9 @@ function isString(str: any): str is string { * `null`, an `array`, a `regexp`, nor a `date`. */ function isObject(obj: any): obj is any { - return typeof obj === _typeof.object && obj !== null && !Array.isArray(obj) && !(obj instanceof RegExp) && !(obj instanceof Date); + return ( + typeof obj === 'object' && obj !== null && !Array.isArray(obj) && !(obj instanceof RegExp) && !(obj instanceof Date) + ); } abstract class AbstractSystemVariables implements ISystemVariables { @@ -60,9 +52,11 @@ abstract class AbstractSystemVariables implements ISystemVariables { public resolve(value: any): any { if (isString(value)) { return this.__resolveString(value); - } else if (isArray(value)) { + } + if (isArray(value)) { return this.__resolveArray(value); - } else if (isObject(value)) { + } + if (isObject(value)) { return this.__resolveLiteral(value); } @@ -73,9 +67,11 @@ abstract class AbstractSystemVariables implements ISystemVariables { public resolveAny(value: any): any { if (isString(value)) { return this.__resolveString(value); - } else if (isArray(value)) { + } + if (isArray(value)) { return this.__resolveAnyArray(value); - } else if (isObject(value)) { + } + if (isObject(value)) { return this.__resolveAnyLiteral(value); } @@ -88,28 +84,29 @@ abstract class AbstractSystemVariables implements ISystemVariables { const newValue = (this)[name]; if (isString(newValue)) { return newValue; - } else { - return match && (match.indexOf('env.') > 0 || match.indexOf('env:') > 0) ? '' : match; } + return match && (match.indexOf('env.') > 0 || match.indexOf('env:') > 0) ? '' : match; }); } - private __resolveLiteral(values: IStringDictionary | string[]>): IStringDictionary | string[]> { + private __resolveLiteral( + values: IStringDictionary | string[]>, + ): IStringDictionary | string[]> { const result: IStringDictionary | string[]> = Object.create(null); - Object.keys(values).forEach((key) => { + for (const key of Object.keys(values)) { const value = values[key]; result[key] = this.resolve(value); - }); + } return result; } private __resolveAnyLiteral(values: T): T; private __resolveAnyLiteral(values: any): any { const result: IStringDictionary | string[]> = Object.create(null); - Object.keys(values).forEach((key) => { + for (const key of Object.keys(values)) { const value = values[key]; result[key] = this.resolveAny(value); - }); + } return result; } @@ -131,9 +128,11 @@ export class SystemVariables extends AbstractSystemVariables { super(); this._workspaceFolder = typeof workspaceFolder === 'string' ? workspaceFolder : __dirname; this._workspaceFolderName = Path.basename(this._workspaceFolder); - Object.keys(process.env).forEach((key) => { - ((this as any) as Record)[`env:${key}`] = ((this as any) as Record)[`env.${key}`] = process.env[key]; - }); + for (const key of Object.keys(process.env)) { + (this as any as Record)[`env:${key}`] = ( + this as any as Record + )[`env.${key}`] = process.env[key]; + } } public get cwd(): string { diff --git a/src/types.ts b/src/types.ts index c50c8e37..37435159 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,6 @@ -import { ChildProcess } from 'child_process'; -import { CancellationToken, DiagnosticSeverity, DiagnosticTag, TextDocument, Uri } from 'coc.nvim'; -import { Observable } from 'rxjs'; +import type { ChildProcess } from 'node:child_process'; +import type { CancellationToken, DiagnosticSeverity, DiagnosticTag, TextDocument, Uri } from 'coc.nvim'; +import type { Observable } from 'rxjs'; export interface ExecutionInfo { execPath: string; @@ -46,7 +46,18 @@ export enum Product { pyink = 18, } -export type LinterId = 'bandit' | 'flake8' | 'mypy' | 'ruff' | 'pycodestyle' | 'prospector' | 'pydocstyle' | 'pyflakes' | 'pylama' | 'pylint' | 'pytype'; +export type LinterId = + | 'bandit' + | 'flake8' + | 'mypy' + | 'ruff' + | 'pycodestyle' + | 'prospector' + | 'pydocstyle' + | 'pyflakes' + | 'pylama' + | 'pylint' + | 'pytype'; export type FormatterId = 'yapf' | 'black' | 'autopep8' | 'darker' | 'blackd' | 'pyink' | 'ruff'; export type TestingFramework = 'unittest' | 'pytest'; @@ -61,10 +72,10 @@ export interface ILinterInfo { } export enum LintMessageSeverity { - Hint, - Error, - Warning, - Information, + Hint = 0, + Error = 1, + Warning = 2, + Information = 3, } export interface ILintMessage { diff --git a/src/utils.ts b/src/utils.ts index 806abda7..080a5ea7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,16 +1,16 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -import { Position, Range, TextDocument, TextEdit, Uri } from 'coc.nvim'; -import { Diff, diff_match_patch } from 'diff-match-patch'; -import fs from 'fs'; +import { type Position, Range, type TextDocument, TextEdit, Uri } from 'coc.nvim'; +import { type Diff, diff_match_patch } from 'diff-match-patch'; +import fs from 'node:fs'; import md5 from 'md5'; -import { EOL } from 'os'; -import * as path from 'path'; +import { EOL } from 'node:os'; +import * as path from 'node:path'; const NEW_LINE_LENGTH = EOL.length; enum EditAction { - Delete, - Insert, - Replace, + Delete = 0, + Insert = 1, + Replace = 2, } class Patch { @@ -54,8 +54,10 @@ function getTextEditsInternal(before: string, diffs: [number, string][], startLi let line = startLine; let character = 0; if (line > 0) { - const beforeLines = before.split(/\r?\n/g); - beforeLines.filter((_l, i) => i < line).forEach((l) => (character += l.length + NEW_LINE_LENGTH)); + const beforeLines = before.split(/\r?\n/g).filter((_l, i) => i < line); + for (const l of beforeLines) { + character += l.length + NEW_LINE_LENGTH; + } } const edits: Edit[] = []; let edit: Edit | null = null; @@ -199,7 +201,9 @@ function patch_fromText(textline: string): Patch[] { return patches; } -export function getTextEditsFromPatch(before: string, patch: string): TextEdit[] { +export function getTextEditsFromPatch(before: string, input: string): TextEdit[] { + let patch = input; + if (patch.startsWith('---')) { // Strip the first two lines patch = patch.substring(patch.indexOf('@@')); @@ -220,12 +224,14 @@ export function getTextEditsFromPatch(before: string, patch: string): TextEdit[] const textEdits: TextEdit[] = []; // Add line feeds and build the text edits - patches.forEach((p) => { - p.diffs.forEach((diff) => { + for (const p of patches) { + for (const diff of p.diffs) { diff[1] += EOL; - }); - getTextEditsInternal(before, p.diffs, p.start1).forEach((edit) => textEdits.push(edit.apply())); - }); + } + for (const edit of getTextEditsInternal(before, p.diffs, p.start1)) { + textEdits.push(edit.apply()); + } + } return textEdits; } @@ -282,8 +288,8 @@ export function getTempFileWithDocumentContents(document: TextDocument): Promise function comparePosition(position: Position, other: Position): number { if (position.line > other.line) return 1; - if (other.line == position.line && position.character > other.character) return 1; - if (other.line == position.line && position.character == other.character) return 0; + if (other.line === position.line && position.character > other.character) return 1; + if (other.line === position.line && position.character === other.character) return 0; return -1; } @@ -297,4 +303,3 @@ export function positionInRange(position: Position, range: Range): number { export function rangeInRange(r: Range, range: Range): boolean { return positionInRange(r.start, range) === 0 && positionInRange(r.end, range) === 0; } -