diff --git a/eslint.config.mjs b/eslint.config.mjs index bc30b791311be..7f1edf024f077 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,6 +1,7 @@ // @ts-check import eslint from "@eslint/js"; import * as regexpPlugin from "eslint-plugin-regexp"; +import eslintPluginUnicorn from "eslint-plugin-unicorn"; import fs from "fs"; import globals from "globals"; import { createRequire } from "module"; @@ -38,6 +39,7 @@ export default tseslint.config( ...tseslint.configs.recommended, ...tseslint.configs.stylistic, regexpPlugin.configs["flat/recommended"], + eslintPluginUnicorn.configs["flat/recommended"], { plugins: { local: { @@ -156,6 +158,94 @@ export default tseslint.config( "local/no-keywords": "error", "local/jsdoc-format": "error", "local/js-extensions": "error", + + // eslint-plugin-unicorn + // good + "unicorn/prefer-includes": "error", + "unicorn/new-for-builtins": "error", + "unicorn/prefer-logical-operator-over-ternary": "error", + "unicorn/no-instanceof-array": "error", + "unicorn/prefer-optional-catch-binding": "error", + "unicorn/require-array-join-separator": "error", + "unicorn/throw-new-error": "error", + "unicorn/no-useless-spread": "error", + "unicorn/no-useless-fallback-in-spread": "error", + "unicorn/prefer-modern-math-apis": "error", + "unicorn/prefer-array-find": "error", + "unicorn/prefer-array-some": "error", + "unicorn/prefer-date-now": "error", + "unicorn/prefer-object-from-entries": "error", + "unicorn/no-new-buffer": "error", + "unicorn/prefer-set-has": "error", + "unicorn/prefer-string-trim-start-end": "error", + "unicorn/no-zero-fractions": "error", + "unicorn/prefer-regexp-test": "error", + "unicorn/number-literal-case": "error", + + // likely yes + "unicorn/error-message": "off", // https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2265 + "unicorn/prefer-math-min-max": "off", + "unicorn/prefer-global-this": "off", + + // likely no + "unicorn/prefer-string-raw": "off", + "unicorn/consistent-existence-index-check": "off", + + // no + "unicorn/filename-case": "off", + "unicorn/prevent-abbreviations": "off", + "unicorn/empty-brace-spaces": "off", + "unicorn/catch-error-name": "off", + "unicorn/prefer-module": "off", + "unicorn/switch-case-braces": "off", + "unicorn/numeric-separators-style": "off", + "unicorn/import-style": "off", + "unicorn/consistent-function-scoping": "off", + "unicorn/text-encoding-identifier-case": "off", + "unicorn/no-process-exit": "off", + "unicorn/prefer-export-from": "off", + "unicorn/prefer-ternary": "off", + "unicorn/template-indent": "off", + "unicorn/no-array-callback-reference": "off", + "unicorn/no-array-method-this-argument": "off", // false positives + "unicorn/no-nested-ternary": "off", + "unicorn/consistent-destructuring": "off", // false positives + "unicorn/no-hex-escape": "off", + "unicorn/no-object-as-default-parameter": "off", + "unicorn/escape-case": "off", + "unicorn/prefer-type-error": "off", + "unicorn/no-await-expression-member": "off", + "unicorn/no-useless-undefined": "off", + "unicorn/no-negated-condition": "off", + "unicorn/no-lonely-if": "off", + "unicorn/prefer-math-trunc": "off", // Treats `1 << 0` as invalid + "unicorn/no-array-for-each": "off", // false positives + "unicorn/no-for-loop": "off", // quick fix produces slower `.entries()` + "unicorn/prefer-at": "off", // perf + "unicorn/prefer-switch": "off", // quick fix produces non-idiomatic code for this repo + "unicorn/no-typeof-undefined": "off", // False positive when checking for a global without throwing + "unicorn/no-null": "off", // if we remove the other plugin + "unicorn/prefer-number-properties": "off", + "unicorn/prefer-string-replace-all": "off", // not available in node 14 + "unicorn/no-array-push-push": "off", + "unicorn/no-new-array": "off", // I like it, but we have a few canonical use cases + "unicorn/explicit-length-check": "off", // I like it, but it's a lot of changes + "unicorn/prefer-node-protocol": "off", // I like it, but it's pure style + "unicorn/prefer-code-point": "off", // I suspect this is correct, but it's a lot of changes in fiddly bits of the code + "unicorn/no-array-reduce": "off", + "unicorn/no-useless-switch-case": "off", + "unicorn/prefer-native-coercion-functions": "off", + "unicorn/prefer-spread": "off", + "unicorn/prefer-event-target": "off", + "unicorn/better-regex": "off", // doesn't always produce a good alternative + "unicorn/prefer-string-slice": "off", // Probably good, but most are not fixed + "unicorn/prefer-reflect-apply": "off", // tbh don't understand the difference + "unicorn/prefer-top-level-await": "off", + "unicorn/prefer-negative-index": "off", + "unicorn/no-unreadable-array-destructuring": "off", + "unicorn/no-negation-in-equality-check": "off", // inaccurate + "unicorn/prefer-structured-clone": "off", // Unavailable until Node 17 + "unicorn/consistent-assert": "off", // Noisy style "local/no-array-mutating-method-expressions": "error", }, }, diff --git a/package-lock.json b/package-lock.json index d4d2c055ccfff..d6c34394c5f8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "eslint": "^9.20.1", "eslint-formatter-autolinkable-stylish": "^1.4.0", "eslint-plugin-regexp": "^2.7.0", + "eslint-plugin-unicorn": "^58.0.0", "fast-xml-parser": "^4.5.2", "glob": "^10.4.5", "globals": "^15.15.0", @@ -62,6 +63,29 @@ "node": ">=14.17" } }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", @@ -627,9 +651,9 @@ "dev": true }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", + "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -689,10 +713,19 @@ "node": "*" } }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", + "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/core": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", - "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.15" @@ -702,9 +735,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", - "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -759,9 +792,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.20.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", - "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", + "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -777,18 +810,30 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.6.tgz", - "integrity": "sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", + "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", "dev": true, "dependencies": { - "@eslint/core": "^0.11.0", + "@eslint/core": "^0.13.0", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", + "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1174,6 +1219,12 @@ "undici-types": "~6.20.0" } }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, "node_modules/@types/source-map-support": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@types/source-map-support/-/source-map-support-0.5.10.tgz", @@ -1617,12 +1668,56 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/builtin-modules": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", + "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==", + "dev": true, + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/c8": { "version": "10.1.3", "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz", @@ -1706,6 +1801,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001707", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", + "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", @@ -1767,6 +1882,42 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/ci-info": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", + "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -1989,6 +2140,19 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/core-js-compat": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz", + "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==", + "dev": true, + "dependencies": { + "browserslist": "^4.24.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2165,6 +2329,12 @@ "integrity": "sha512-7nXPYDeKh6DgJDR/mpt2G7N/hCNSGwwoPVmoI3+4TEwOb07VFN1WMPG0DFf6nMEjrkgdj8Og7l7IaEEk3VE6Zg==", "dev": true }, + "node_modules/electron-to-chromium": { + "version": "1.5.129", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.129.tgz", + "integrity": "sha512-JlXUemX4s0+9f8mLqib/bHH8gOHf5elKS6KeWG3sk3xozb/JTq/RLXIv8OKUWiK4Ah00Wm88EFj5PYkFr4RUPA==", + "dev": true + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -2276,21 +2446,22 @@ } }, "node_modules/eslint": { - "version": "9.20.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.1.tgz", - "integrity": "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", + "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.11.0", - "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.20.0", - "@eslint/plugin-kit": "^0.2.5", + "@eslint/config-array": "^0.19.2", + "@eslint/config-helpers": "^0.2.0", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.23.0", + "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.1", + "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -2298,7 +2469,7 @@ "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.2.0", + "eslint-scope": "^8.3.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", @@ -2368,10 +2539,68 @@ "eslint": ">=8.44.0" } }, + "node_modules/eslint-plugin-unicorn": { + "version": "58.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-58.0.0.tgz", + "integrity": "sha512-fc3iaxCm9chBWOHPVjn+Czb/wHS0D2Mko7wkOdobqo9R2bbFObc4LyZaLTNy0mhZOP84nKkLhTUQxlLOZ7EjKw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "@eslint-community/eslint-utils": "^4.5.1", + "@eslint/plugin-kit": "^0.2.7", + "ci-info": "^4.2.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.41.0", + "esquery": "^1.6.0", + "globals": "^16.0.0", + "indent-string": "^5.0.0", + "is-builtin-module": "^5.0.0", + "jsesc": "^3.1.0", + "pluralize": "^8.0.0", + "read-package-up": "^11.0.0", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.12.0", + "semver": "^7.7.1", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": "^18.20.0 || ^20.10.0 || >=21.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=9.22.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/globals": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", + "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-scope": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", - "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -2639,6 +2868,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -2896,6 +3137,18 @@ "node": ">= 12.20" } }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -2945,6 +3198,18 @@ "node": ">=8" } }, + "node_modules/index-to-position": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.0.0.tgz", + "integrity": "sha512-sCO7uaLVhRJ25vz1o8s9IFM3nVS4DkuQnyjMwiQPKvQuBYBDmb8H7zx8ki7nVh4HJQOdVWebyvLE0qt+clruxA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2983,6 +3248,21 @@ "node": ">=8" } }, + "node_modules/is-builtin-module": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", + "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==", + "dev": true, + "dependencies": { + "builtin-modules": "^5.0.0" + }, + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3115,6 +3395,12 @@ "integrity": "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==", "dev": true }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -3136,6 +3422,18 @@ "node": ">=12.0.0" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -3421,6 +3719,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -3754,6 +4061,26 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3864,6 +4191,23 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.2.0.tgz", + "integrity": "sha512-eONBZy4hm2AgxjNFd8a4nyDJnzUAH0g34xSQAwWEVGCjdZ4ZL7dKZBfq267GWP/JaS9zW62Xs2FeAdDvpHHJGQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.0.0", + "type-fest": "^4.37.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse-ms": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", @@ -3982,6 +4326,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4059,6 +4412,42 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "dev": true, + "dependencies": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -4106,6 +4495,39 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4348,6 +4770,38 @@ "source-map": "^0.6.0" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -4438,6 +4892,21 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4572,6 +5041,18 @@ "node": ">=4" } }, + "node_modules/type-fest": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.39.0.tgz", + "integrity": "sha512-w2IGJU1tIgcrepg9ZJ82d8UmItNQtOFJG0HCUE3SzMokKkTsruVDALl2fAdiEzJlfduoU+VyXJWIIUZ+6jV+nw==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typed-rest-client": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-2.1.0.tgz", @@ -4644,12 +5125,54 @@ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universal-user-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", "dev": true }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -4673,6 +5196,16 @@ "node": ">=10.12.0" } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -4929,6 +5462,23 @@ } }, "dependencies": { + "@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true + }, "@bcoe/v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", @@ -5212,9 +5762,9 @@ "dev": true }, "@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", + "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", "dev": true, "requires": { "eslint-visitor-keys": "^3.4.3" @@ -5258,19 +5808,25 @@ } } }, + "@eslint/config-helpers": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", + "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", + "dev": true + }, "@eslint/core": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", - "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "dev": true, "requires": { "@types/json-schema": "^7.0.15" } }, "@eslint/eslintrc": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", - "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -5312,9 +5868,9 @@ } }, "@eslint/js": { - "version": "9.20.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", - "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", + "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", "dev": true }, "@eslint/object-schema": { @@ -5324,13 +5880,24 @@ "dev": true }, "@eslint/plugin-kit": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.6.tgz", - "integrity": "sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", + "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", "dev": true, "requires": { - "@eslint/core": "^0.11.0", + "@eslint/core": "^0.13.0", "levn": "^0.4.1" + }, + "dependencies": { + "@eslint/core": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", + "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.15" + } + } } }, "@humanfs/core": { @@ -5628,6 +6195,12 @@ "undici-types": "~6.20.0" } }, + "@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, "@types/source-map-support": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@types/source-map-support/-/source-map-support-0.5.10.tgz", @@ -5923,12 +6496,30 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + } + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "builtin-modules": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", + "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==", + "dev": true + }, "c8": { "version": "10.1.3", "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz", @@ -5980,6 +6571,12 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001707", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", + "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", + "dev": true + }, "chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", @@ -6023,6 +6620,29 @@ "readdirp": "^4.0.1" } }, + "ci-info": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", + "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", + "dev": true + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + } + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -6201,6 +6821,15 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "core-js-compat": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz", + "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==", + "dev": true, + "requires": { + "browserslist": "^4.24.4" + } + }, "cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -6335,6 +6964,12 @@ "integrity": "sha512-7nXPYDeKh6DgJDR/mpt2G7N/hCNSGwwoPVmoI3+4TEwOb07VFN1WMPG0DFf6nMEjrkgdj8Og7l7IaEEk3VE6Zg==", "dev": true }, + "electron-to-chromium": { + "version": "1.5.129", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.129.tgz", + "integrity": "sha512-JlXUemX4s0+9f8mLqib/bHH8gOHf5elKS6KeWG3sk3xozb/JTq/RLXIv8OKUWiK4Ah00Wm88EFj5PYkFr4RUPA==", + "dev": true + }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -6418,21 +7053,22 @@ "dev": true }, "eslint": { - "version": "9.20.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.1.tgz", - "integrity": "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", + "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.11.0", - "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.20.0", - "@eslint/plugin-kit": "^0.2.5", + "@eslint/config-array": "^0.19.2", + "@eslint/config-helpers": "^0.2.0", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.23.0", + "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.1", + "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -6440,7 +7076,7 @@ "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.2.0", + "eslint-scope": "^8.3.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", @@ -6511,10 +7147,49 @@ "scslre": "^0.3.0" } }, + "eslint-plugin-unicorn": { + "version": "58.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-58.0.0.tgz", + "integrity": "sha512-fc3iaxCm9chBWOHPVjn+Czb/wHS0D2Mko7wkOdobqo9R2bbFObc4LyZaLTNy0mhZOP84nKkLhTUQxlLOZ7EjKw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.25.9", + "@eslint-community/eslint-utils": "^4.5.1", + "@eslint/plugin-kit": "^0.2.7", + "ci-info": "^4.2.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.41.0", + "esquery": "^1.6.0", + "globals": "^16.0.0", + "indent-string": "^5.0.0", + "is-builtin-module": "^5.0.0", + "jsesc": "^3.1.0", + "pluralize": "^8.0.0", + "read-package-up": "^11.0.0", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.12.0", + "semver": "^7.7.1", + "strip-indent": "^4.0.0" + }, + "dependencies": { + "globals": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", + "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", + "dev": true + }, + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true + } + } + }, "eslint-scope": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", - "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -6676,6 +7351,12 @@ "path-exists": "^4.0.0" } }, + "find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "dev": true + }, "flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -6854,6 +7535,15 @@ "pretty-ms": "^8.0.0" } }, + "hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "requires": { + "lru-cache": "^10.0.1" + } + }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -6888,6 +7578,12 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, + "index-to-position": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.0.0.tgz", + "integrity": "sha512-sCO7uaLVhRJ25vz1o8s9IFM3nVS4DkuQnyjMwiQPKvQuBYBDmb8H7zx8ki7nVh4HJQOdVWebyvLE0qt+clruxA==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -6919,6 +7615,15 @@ "binary-extensions": "^2.0.0" } }, + "is-builtin-module": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", + "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==", + "dev": true, + "requires": { + "builtin-modules": "^5.0.0" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -7013,6 +7718,12 @@ "integrity": "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==", "dev": true }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -7028,6 +7739,12 @@ "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", "dev": true }, + "jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true + }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -7229,6 +7946,12 @@ } } }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -7484,6 +8207,23 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "requires": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7561,6 +8301,17 @@ "callsites": "^3.0.0" } }, + "parse-json": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.2.0.tgz", + "integrity": "sha512-eONBZy4hm2AgxjNFd8a4nyDJnzUAH0g34xSQAwWEVGCjdZ4ZL7dKZBfq267GWP/JaS9zW62Xs2FeAdDvpHHJGQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.0.0", + "type-fest": "^4.37.0" + } + }, "parse-ms": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", @@ -7632,6 +8383,12 @@ "irregular-plurals": "^3.2.0" } }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -7677,6 +8434,30 @@ "safe-buffer": "^5.1.0" } }, + "read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "dev": true, + "requires": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + } + }, + "read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + } + }, "readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -7708,6 +8489,29 @@ "refa": "^0.12.1" } }, + "regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true + }, + "regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "requires": { + "jsesc": "~3.0.2" + }, + "dependencies": { + "jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true + } + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7858,6 +8662,38 @@ "source-map": "^0.6.0" } }, + "spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true + }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -7923,6 +8759,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "requires": { + "min-indent": "^1.0.1" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -8022,6 +8867,12 @@ "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true }, + "type-fest": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.39.0.tgz", + "integrity": "sha512-w2IGJU1tIgcrepg9ZJ82d8UmItNQtOFJG0HCUE3SzMokKkTsruVDALl2fAdiEzJlfduoU+VyXJWIIUZ+6jV+nw==", + "dev": true + }, "typed-rest-client": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-2.1.0.tgz", @@ -8070,12 +8921,28 @@ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, + "unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true + }, "universal-user-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", "dev": true }, + "update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "requires": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -8096,6 +8963,16 @@ "convert-source-map": "^2.0.0" } }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", diff --git a/package.json b/package.json index ef2c80f8b91c2..de9f3ad573117 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "eslint": "^9.20.1", "eslint-formatter-autolinkable-stylish": "^1.4.0", "eslint-plugin-regexp": "^2.7.0", + "eslint-plugin-unicorn": "^58.0.0", "fast-xml-parser": "^4.5.2", "glob": "^10.4.5", "globals": "^15.15.0", diff --git a/scripts/build/tests.mjs b/scripts/build/tests.mjs index c81cd7800183b..2a7bde7eab0e9 100644 --- a/scripts/build/tests.mjs +++ b/scripts/build/tests.mjs @@ -209,7 +209,7 @@ export async function cleanTestDirs() { export function writeTestConfigFile(tests, skipSysTests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, timeout, keepFailed, shards, shardId) { const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, - skipSysTests: skipSysTests ? skipSysTests : undefined, + skipSysTests: skipSysTests ? true : undefined, runners: runners ? runners.split(",") : undefined, light, workerCount, diff --git a/scripts/errorCheck.mjs b/scripts/errorCheck.mjs index e7068a13fcec3..bdfd5c3862b58 100644 --- a/scripts/errorCheck.mjs +++ b/scripts/errorCheck.mjs @@ -1,3 +1,4 @@ +import assert from "assert"; import fs from "fs"; import fsPromises from "fs/promises"; import { glob } from "glob"; @@ -23,7 +24,8 @@ async function checkErrorBaselines() { let g; while (g = errRegex.exec(baseline)) { const errCode = +g[1]; - const msg = keys.filter(k => messages[k].code === errCode)[0]; + const msg = keys.find(k => messages[k].code === errCode); + assert(msg); messages[msg].seen = true; } } diff --git a/scripts/eslint/rules/no-keywords.cjs b/scripts/eslint/rules/no-keywords.cjs index 653f22a5814ac..cc3c75a904af4 100644 --- a/scripts/eslint/rules/no-keywords.cjs +++ b/scripts/eslint/rules/no-keywords.cjs @@ -25,7 +25,7 @@ module.exports = createRule({ defaultOptions: [], create(context) { - const keywords = [ + const keywords = new Set([ "Undefined", "undefined", "Boolean", @@ -35,10 +35,10 @@ module.exports = createRule({ "Number", "number", "any", - ]; + ]); /** @type {(name: string) => boolean} */ - const isKeyword = name => keywords.includes(name); + const isKeyword = name => keywords.has(name); /** @type {(node: TSESTree.Identifier) => void} */ const report = node => { diff --git a/scripts/eslint/rules/only-arrow-functions.cjs b/scripts/eslint/rules/only-arrow-functions.cjs index c3f814b21d088..73a7f42455fb0 100644 --- a/scripts/eslint/rules/only-arrow-functions.cjs +++ b/scripts/eslint/rules/only-arrow-functions.cjs @@ -34,7 +34,7 @@ module.exports = createRule({ create(context, [{ allowNamedFunctions, allowDeclarations }]) { /** @type {(node: FunctionDeclarationOrExpression) => boolean} */ - const isThisParameter = node => !!node.params.length && !!node.params.find(param => param.type === AST_NODE_TYPES.Identifier && param.name === "this"); + const isThisParameter = node => node.params.some(param => param.type === AST_NODE_TYPES.Identifier && param.name === "this"); /** @type {(node: TSESTree.Node) => boolean} */ const isMethodType = node => { diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 1c472cebead0d..da83f830cbdf3 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -1396,7 +1396,7 @@ function getBuildInfo(state: BuilderProgramStateWithDefinedProgram): BuildInfo { function toFileIdListId(set: ReadonlySet): IncrementalBuildInfoFileIdListId { const fileIds = arrayFrom(set.keys(), toFileId).sort(compareValues); - const key = fileIds.join(); + const key = fileIds.join(","); let fileIdListId = fileNamesToFileIdListId?.get(key); if (fileIdListId === undefined) { fileIdsList = append(fileIdsList, fileIds); @@ -2247,7 +2247,7 @@ export function toProgramEmitPending( value: IncrementalBuildInfoBundlePendingEmit, options: CompilerOptions | undefined, ): BuilderFileEmit | undefined { - return !value ? getBuilderFileEmit(options || {}) : value; + return value || getBuilderFileEmit(options || {}); } /** @internal */ diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 67a733cbbb811..795e280b7971d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12194,6 +12194,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // up recursively calling getTypeOfAlias, causing a stack overflow. links.type ??= exportSymbol?.declarations && isDuplicatedCommonJSExport(exportSymbol.declarations) && symbol.declarations!.length ? getFlowTypeFromCommonJSExport(exportSymbol) : isDuplicatedCommonJSExport(symbol.declarations) ? autoType + // eslint-disable-next-line unicorn/prefer-logical-operator-over-ternary : declaredType ? declaredType : getSymbolFlags(targetSymbol) & SymbolFlags.Value ? getTypeOfSymbol(targetSymbol) : errorType; @@ -15023,7 +15024,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const writeType = getWriteTypeOfSymbol(prop); if (writeTypes || writeType !== type) { - writeTypes = append(!writeTypes ? propTypes.slice() : writeTypes, writeType); + writeTypes = append(writeTypes ?? propTypes.slice(), writeType); } if (type !== firstType) { checkFlags |= CheckFlags.HasNonUniformType; @@ -15322,6 +15323,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // the intersected key type, we just use unknownType for the key type as nothing actually depends on the // keyType property of the returned IndexInfo. return applicableInfos ? createIndexInfo(unknownType, getIntersectionType(map(applicableInfos, info => info.type)), reduceLeft(applicableInfos, (isReadonly, info) => isReadonly && info.isReadonly, /*initial*/ true)) : + // eslint-disable-next-line unicorn/prefer-logical-operator-over-ternary applicableInfo ? applicableInfo : stringIndexInfo && isApplicableIndexType(keyType, stringType) ? stringIndexInfo : undefined; @@ -17190,7 +17192,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // [...X[]] is equivalent to just X[] return readonly ? globalReadonlyArrayType : globalArrayType; } - const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() + + const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join(",") + (readonly ? "R" : "") + (some(namedMemberDeclarations, node => !!node) ? "," + map(namedMemberDeclarations, node => node ? getNodeId(node) : "_").join(",") : ""); let type = tupleTypes.get(key); @@ -22268,7 +22270,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const sourceSize = sourceUnionOrIntersection.types.length; const targetSize = targetUnionOrIntersection.types.length; - if (sourceSize * targetSize > 1E6) { + if (sourceSize * targetSize > 1e6) { tracing.instant(tracing.Phase.CheckTypes, "traceUnionsOrIntersectionsTooLarge_DepthLimit", { sourceId: source.id, sourceSize, @@ -42870,6 +42872,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // For a union, get a union of the awaited types of each constituent. if (type.flags & TypeFlags.Union) { + // We want to indicate that the search should go backwards for perf. + // eslint-disable-next-line unicorn/prefer-includes if (awaitedTypeStack.lastIndexOf(type.id) >= 0) { if (errorNode) { error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method); @@ -42894,6 +42898,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const thisTypeForErrorOut: { value: Type | undefined; } = { value: undefined }; const promisedType = getPromisedTypeOfPromise(type, /*errorNode*/ undefined, thisTypeForErrorOut); if (promisedType) { + // We want to indicate that the search should go backwards for perf. + // eslint-disable-next-line unicorn/prefer-includes if (type.id === promisedType.id || awaitedTypeStack.lastIndexOf(promisedType.id) >= 0) { // Verify that we don't have a bad actor in the form of a promise whose // promised type is the same as the promise type, or a mutually recursive @@ -49216,7 +49222,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else { const copy = createSymbol(SymbolFlags.Signature, InternalSymbolName.Index); copy.declarations = mapDefined(infos, i => i.declaration); - copy.parent = type.aliasSymbol ? type.aliasSymbol : type.symbol ? type.symbol : getSymbolAtLocation(copy.declarations[0].parent); + copy.parent = type.aliasSymbol ?? type.symbol ?? getSymbolAtLocation(copy.declarations[0].parent); symbolLinks.filteredIndexSymbolCache.set(nodeListId, copy); return copy; } @@ -52769,6 +52775,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getEffectivePropertyNameForPropertyNameNode(node: PropertyName) { const name = getPropertyNameForPropertyNameNode(node); + // eslint-disable-next-line unicorn/prefer-logical-operator-over-ternary return name ? name : isComputedPropertyName(node) ? tryGetNameFromType(getTypeOfExpression(node.expression)) : undefined; } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 8248a04194666..7f0609db9235c 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -2638,7 +2638,7 @@ export function convertToTSConfig(configParseResult: ParsedCommandLine, configFi version: undefined, }, watchOptions: watchOptionMap && optionMapToObject(watchOptionMap), - references: map(configParseResult.projectReferences, r => ({ ...r, path: r.originalPath ? r.originalPath : "", originalPath: undefined })), + references: map(configParseResult.projectReferences, r => ({ ...r, path: r.originalPath || "", originalPath: undefined })), files: length(files) ? files : undefined, ...(configParseResult.options.configFile?.configFileSpecs ? { include: filterSameAsDefaultInclude(configParseResult.options.configFile.configFileSpecs.validatedIncludeSpecs), @@ -2798,7 +2798,7 @@ export function getCompilerOptionsDiffValue(options: CompilerOptions, newLine: s return getOverwrittenDefaultOptions(); function makePadding(paddingLength: number): string { - return Array(paddingLength + 1).join(" "); + return " ".repeat(paddingLength); } function getOverwrittenDefaultOptions() { @@ -2842,7 +2842,7 @@ export function generateTSConfig(options: CompilerOptions, fileNames: readonly s return writeConfigurations(); function makePadding(paddingLength: number): string { - return Array(paddingLength + 1).join(" "); + return " ".repeat(paddingLength); } function isAllowedOptionForOutput({ category, name, isCommandLineOnly }: CommandLineOption): boolean { diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 42e8637ac178a..4e2dc8497212c 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -1054,7 +1054,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n") } function computeColumnWidths(height: number) { - const columns: number[] = fill(Array(height), 0); + const columns: number[] = fill(new Array(height), 0); for (const node of nodes) { columns[node.level] = Math.max(columns[node.level], node.text.length); } @@ -1128,9 +1128,9 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n") function renderGraph() { const columnCount = columnWidths.length; const laneCount = maxBy(nodes, 0, n => n.lane) + 1; - const lanes: string[] = fill(Array(laneCount), ""); - const grid: (FlowGraphNode | undefined)[][] = columnWidths.map(() => Array(laneCount)); - const connectors: Connection[][] = columnWidths.map(() => fill(Array(laneCount), 0)); + const lanes: string[] = fill(new Array(laneCount), ""); + const grid: (FlowGraphNode | undefined)[][] = columnWidths.map(() => new Array(laneCount)); + const connectors: Connection[][] = columnWidths.map(() => fill(new Array(laneCount), 0)); // build connectors for (const node of nodes) { diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 3fa7da5d5c960..03cbc78fc3790 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -2315,6 +2315,7 @@ function loadEntrypointsFromExportMap( }); } else { + // eslint-disable-next-line unicorn/prefer-set-has const partsAfterFirst = getPathComponents(target).slice(2); if (partsAfterFirst.includes("..") || partsAfterFirst.includes(".") || partsAfterFirst.includes("node_modules")) { return false; @@ -2777,6 +2778,7 @@ function getLoadModuleFromTargetExportOrImport(extensions: Extensions, state: Mo return toSearchResult(/*value*/ undefined); } const parts = pathIsRelative(target) ? getPathComponents(target).slice(1) : getPathComponents(target); + // eslint-disable-next-line unicorn/prefer-set-has const partsAfterFirst = parts.slice(1); if (partsAfterFirst.includes("..") || partsAfterFirst.includes(".") || partsAfterFirst.includes("node_modules")) { if (state.traceEnabled) { diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index eacba122e496c..f9d8acf027897 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -1107,7 +1107,7 @@ function tryGetModuleNameFromExportsOrImports( else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-restricted-syntax // conditional mapping for (const key of getOwnKeys(exports as MapLike)) { - if (key === "default" || conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(conditions, key)) { + if (key === "default" || conditions.includes(key) || isApplicableVersionedTypesKey(conditions, key)) { const subTarget = (exports as MapLike)[key]; const result = tryGetModuleNameFromExportsOrImports(options, host, targetFilePath, packageDirectory, packageName, subTarget, conditions, mode, isImports, preferTsExtension); if (result) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8c69cccba1282..09d4a41002972 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -10561,7 +10561,7 @@ export function processCommentPragmas(context: PragmaContext, sourceText: string for (const pragma of pragmas) { if (context.pragmas.has(pragma.name)) { const currentValue = context.pragmas.get(pragma.name); - if (currentValue instanceof Array) { + if (Array.isArray(currentValue)) { currentValue.push(pragma.args); } else { @@ -10622,7 +10622,7 @@ export function processPragmasIntoFields(context: PragmaContext, reportDiagnosti break; } case "amd-module": { - if (entryOrList instanceof Array) { + if (Array.isArray(entryOrList)) { for (const entry of entryOrList) { if (context.moduleName) { // TODO: It's probably fine to issue this diagnostic on all instances of the pragma diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 7c69055ec1f66..dd24d383d5eaf 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -280,13 +280,13 @@ function perceivedOsRootLengthForWatching(pathComponents: Readonly { const nativePattern = /^native |^\([^)]+\)$|^(?:internal[\\/]|[\w\s]+(?:\.js)?$)/; const _fs: typeof import("fs") = require("fs"); const _path: typeof import("path") = require("path"); - const _os = require("os"); + const _os: typeof import("os") = require("os"); + const _buffer: typeof import("buffer") = require("buffer"); // crypto can be absent on reduced node installations let _crypto: typeof import("crypto") | undefined; try { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 342c0f2af7146..1869337b733b4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -7864,7 +7864,7 @@ export const enum CharacterCodes { W = 0x57, X = 0x58, Y = 0x59, - Z = 0x5a, + Z = 0x5A, ampersand = 0x26, // & asterisk = 0x2A, // * diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5755369134d8a..82543dba1e243 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -7554,19 +7554,19 @@ function getExpandedCharCodes(input: string): number[] { output.push(charCode); } else if (charCode < 0x800) { - output.push((charCode >> 6) | 0B11000000); - output.push((charCode & 0B00111111) | 0B10000000); + output.push((charCode >> 6) | 0b11000000); + output.push((charCode & 0b00111111) | 0b10000000); } else if (charCode < 0x10000) { - output.push((charCode >> 12) | 0B11100000); - output.push(((charCode >> 6) & 0B00111111) | 0B10000000); - output.push((charCode & 0B00111111) | 0B10000000); + output.push((charCode >> 12) | 0b11100000); + output.push(((charCode >> 6) & 0b00111111) | 0b10000000); + output.push((charCode & 0b00111111) | 0b10000000); } else if (charCode < 0x20000) { - output.push((charCode >> 18) | 0B11110000); - output.push(((charCode >> 12) & 0B00111111) | 0B10000000); - output.push(((charCode >> 6) & 0B00111111) | 0B10000000); - output.push((charCode & 0B00111111) | 0B10000000); + output.push((charCode >> 18) | 0b11110000); + output.push(((charCode >> 12) & 0b00111111) | 0b10000000); + output.push(((charCode >> 6) & 0b00111111) | 0b10000000); + output.push((charCode & 0b00111111) | 0b10000000); } else { Debug.assert(false, "Unexpected code point"); @@ -7594,9 +7594,9 @@ export function convertToBase64(input: string): string { // Convert every 6-bits in the input 3 character points // into a base64 digit byte1 = charCodes[i] >> 2; - byte2 = (charCodes[i] & 0B00000011) << 4 | charCodes[i + 1] >> 4; - byte3 = (charCodes[i + 1] & 0B00001111) << 2 | charCodes[i + 2] >> 6; - byte4 = charCodes[i + 2] & 0B00111111; + byte2 = (charCodes[i] & 0b00000011) << 4 | charCodes[i + 1] >> 4; + byte3 = (charCodes[i + 1] & 0b00001111) << 2 | charCodes[i + 2] >> 6; + byte4 = charCodes[i + 2] & 0b00111111; // We are out of characters in the input, set the extra // digits to 64 (padding character). @@ -7627,12 +7627,12 @@ function getStringFromExpandedCharCodes(codes: number[]): string { output += String.fromCharCode(charCode); i++; } - else if ((charCode & 0B11000000) === 0B11000000) { - let value = charCode & 0B00111111; + else if ((charCode & 0b11000000) === 0b11000000) { + let value = charCode & 0b00111111; i++; let nextCode: number = codes[i]; - while ((nextCode & 0B11000000) === 0B10000000) { - value = (value << 6) | (nextCode & 0B00111111); + while ((nextCode & 0b11000000) === 0b10000000) { + value = (value << 6) | (nextCode & 0b00111111); i++; nextCode = codes[i]; } @@ -7676,9 +7676,9 @@ export function base64decode(host: { base64decode?(input: string): string; } | u const ch3 = base64Digits.indexOf(input[i + 2]); const ch4 = base64Digits.indexOf(input[i + 3]); - const code1 = ((ch1 & 0B00111111) << 2) | ((ch2 >> 4) & 0B00000011); - const code2 = ((ch2 & 0B00001111) << 4) | ((ch3 >> 2) & 0B00001111); - const code3 = ((ch3 & 0B00000011) << 6) | (ch4 & 0B00111111); + const code1 = ((ch1 & 0b00111111) << 2) | ((ch2 >> 4) & 0b00000011); + const code2 = ((ch2 & 0b00001111) << 4) | ((ch3 >> 2) & 0b00001111); + const code3 = ((ch3 & 0b00000011) << 6) | (ch4 & 0b00111111); if (code2 === 0 && ch3 !== 0) { // code2 decoded to zero, but ch3 was padding - elide code2 and code3 expandedCharCodes.push(code1); @@ -10104,7 +10104,7 @@ export function tryParsePattern(pattern: string): string | Pattern | undefined { if (indexOfStar === -1) { return pattern; } - return pattern.indexOf("*", indexOfStar + 1) !== -1 + return pattern.includes("*", indexOfStar + 1) ? undefined : { prefix: pattern.substr(0, indexOfStar), diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 02623678a0cf0..3b9f0c4413d0f 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1347,6 +1347,7 @@ export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeP } export function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined { + // eslint-disable-next-line unicorn/prefer-logical-operator-over-ternary return node.constraint ? node.constraint : isJSDocTemplateTag(node.parent) && node === node.parent.typeParameters[0] ? node.parent.constraint : undefined; @@ -2595,7 +2596,7 @@ export function isTypeReferenceType(node: Node): node is TypeReferenceType { return node.kind === SyntaxKind.TypeReference || node.kind === SyntaxKind.ExpressionWithTypeArguments; } -const MAX_SMI_X86 = 0x3fff_ffff; +const MAX_SMI_X86 = 0x3FFF_FFFF; /** @internal */ export function guessIndentation(lines: string[]): number | undefined { let indentation = MAX_SMI_X86; diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index a859bcc60009d..208ad8830c59d 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -304,7 +304,7 @@ function createTabularErrorsDisplay(filesInError: (ReportFileInError | undefined const distinctFiles = filesInError.filter((value, index, self) => index === self.findIndex(file => file?.fileName === value?.fileName)); if (distinctFiles.length === 0) return ""; - const numberLength = (num: number) => Math.log(num) * Math.LOG10E + 1; + const numberLength = (num: number) => Math.log10(num) + 1; const fileToErrorCount = distinctFiles.map(file => ([file, countWhere(filesInError, fileInError => fileInError!.fileName === file!.fileName)] as const)); const maxErrors = maxBy(fileToErrorCount, 0, value => value[1]); @@ -317,7 +317,7 @@ function createTabularErrorsDisplay(filesInError: (ReportFileInError | undefined tabularData += " ".repeat(headerPadding) + headerRow + "\n"; fileToErrorCount.forEach(row => { const [file, errorCount] = row; - const errorCountDigitsLength = Math.log(errorCount) * Math.LOG10E + 1 | 0; + const errorCountDigitsLength = Math.log10(errorCount) + 1 | 0; const leftPadding = errorCountDigitsLength < leftPaddingGoal ? " ".repeat(leftPaddingGoal - errorCountDigitsLength) : ""; @@ -786,7 +786,7 @@ export function createCompilerHostFromProgramHost(host: ProgramHost, getCom /** @internal */ export function getSourceFileVersionAsHashFromText(host: Pick, text: string): string { // If text can contain the sourceMapUrl ignore sourceMapUrl for calcualting hash - if (text.match(sourceMapCommentRegExpDontCareLineStart)) { + if (sourceMapCommentRegExpDontCareLineStart.test(text)) { let lineEnd = text.length; let lineStart = lineEnd; for (let pos = lineEnd - 1; pos >= 0; pos--) { @@ -808,12 +808,12 @@ export function getSourceFileVersionAsHashFromText(host: Pick { } private resetDependers(module: SystemModule, stack: SystemModule[]) { + // We want to indicate that the search should go backwards for perf. + // eslint-disable-next-line unicorn/prefer-includes if (stack.lastIndexOf(module) !== -1) { return; } @@ -460,6 +462,8 @@ class SystemLoader extends Loader { if (module.state < SystemModuleState.Linked) throw new Error("Invalid state for evaluation."); if (module.state !== SystemModuleState.Linked) return; + // We want to indicate that the search should go backwards for perf. + // eslint-disable-next-line unicorn/prefer-includes if (stack.lastIndexOf(module) !== -1) { // we are already evaluating this module return; @@ -703,6 +707,8 @@ class AmdLoader extends Loader { } private resetDependers(module: AmdModule, stack: AmdModule[]) { + // We want to indicate that the search should go backwards for perf. + // eslint-disable-next-line unicorn/prefer-includes if (stack.lastIndexOf(module) !== -1) { return; } @@ -721,6 +727,8 @@ class AmdLoader extends Loader { if (module.state < AmdModuleState.Linked) throw new Error("Invalid state for evaluation."); if (module.state !== AmdModuleState.Linked) return; + // We want to indicate that the search should go backwards for perf. + // eslint-disable-next-line unicorn/prefer-includes if (stack.lastIndexOf(module) !== -1) { // we are already evaluating this module return; diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index e1a410dfb5d3b..ab233cdca471d 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -493,18 +493,18 @@ export class TestState { this.openFile(0); function memoWrap(ls: ts.LanguageService, target: TestState): ts.LanguageService { - const cacheableMembers: (keyof typeof ls)[] = [ + const cacheableMembers = new Set([ "getCompletionEntryDetails", "getCompletionEntrySymbol", "getQuickInfoAtPosition", "getReferencesAtPosition", "getDocumentHighlights", - ]; + ]); const proxy = {} as ts.LanguageService; const keys = ts.getAllKeys(ls); for (const k of keys) { const key = k as keyof typeof ls; - if (!cacheableMembers.includes(key)) { + if (!cacheableMembers.has(key)) { proxy[key] = (...args: any[]) => (ls[key] as (...args: any[]) => any)(...args); continue; } @@ -2256,7 +2256,7 @@ export class TestState { const isEmpty = selectionStart.line === selectionEnd.line && selectionStart.character === selectionEnd.character; const selectionPadLength = lineNumber === selectionStart.line ? selectionStart.character : 0; const selectionPad = " ".repeat(selectionPadLength + lineNumberPrefixLength); - const selectionLength = isEmpty ? 0 : Math.max(lineNumber < selectionEnd.line ? spanLine.trimRight().length - selectionPadLength : selectionEnd.character - selectionPadLength, 1); + const selectionLength = isEmpty ? 0 : Math.max(lineNumber < selectionEnd.line ? spanLine.trimEnd().length - selectionPadLength : selectionEnd.character - selectionPadLength, 1); const selectionLine = isEmpty ? "<" : "^".repeat(selectionLength); output.push(`${selectionPad}${selectionLine}`); } @@ -4282,7 +4282,7 @@ export class TestState { let text = ""; text += `${prefix}╭ ${file.fileName}:${startLc.line + 1}:${startLc.character + 1}-${endLc.line + 1}:${endLc.character + 1}\n`; for (const line of lines) { - text += `${prefix}│ ${line.trimRight()}\n`; + text += `${prefix}│ ${line.trimEnd()}\n`; } text += `${trailingPrefix}╰\n`; return text; @@ -4863,7 +4863,7 @@ function parseTestData(basePath: string, contents: string, fileName: string): Fo directive = getNonFileNameOptionInObject(globalOptions); } if (directive) { - throw Error(`It is not allowed to use ${config.fileName} along with directive '${directive}'`); + throw new Error(`It is not allowed to use ${config.fileName} along with directive '${directive}'`); } } @@ -5244,7 +5244,7 @@ function highlightDifferenceBetweenStrings(source: string, target: string) { range.start + 1 + additionalOffset, range.start + range.length + 1 + additionalOffset, ); - const after = emTarget.slice(range.start + range.length + 1 + additionalOffset, emTarget.length); + const after = emTarget.slice(range.start + range.length + 1 + additionalOffset); emTarget = before + lhs + between + rhs + after; }); return emTarget; diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index dadf1477f743e..e613e4d882cb7 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -85,7 +85,7 @@ function createNodeIO(): IO { let paths: string[] = []; for (const file of files) { const pathToFile = pathModule.join(folder, file); - if (!spec || file.match(spec)) { + if (!spec || spec.test(file)) { paths.push(pathToFile); } } @@ -672,7 +672,7 @@ export namespace Compiler { // Calculate the start of the squiggle const squiggleStart = Math.max(0, relativeOffset); // TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another - outputLines += newLine() + " " + line.substr(0, squiggleStart).replace(/\S/g, " ") + new Array(Math.min(length, line.length - squiggleStart) + 1).join("~"); + outputLines += newLine() + " " + line.substr(0, squiggleStart).replace(/\S/g, " ") + "~".repeat(Math.min(length, line.length - squiggleStart)); // If the error ended here, or we're at the end of the file, emit its message if ((lineIndex === lines.length - 1) || nextLineStart > end) { @@ -889,7 +889,7 @@ export namespace Compiler { typeLines += codeLines.slice(0, result.line + 1).join("\r\n") + "\r\n"; } else if (result.line !== lastIndexWritten) { - if (!((lastIndexWritten + 1 < codeLines.length) && (codeLines[lastIndexWritten + 1].match(/^\s*[{|}]\s*$/) || codeLines[lastIndexWritten + 1].trim() === ""))) { + if (!((lastIndexWritten + 1 < codeLines.length) && (/^\s*[{|}]\s*$/.test(codeLines[lastIndexWritten + 1]) || codeLines[lastIndexWritten + 1].trim() === ""))) { typeLines += "\r\n"; } typeLines += codeLines.slice(lastIndexWritten + 1, result.line + 1).join("\r\n") + "\r\n"; @@ -906,7 +906,7 @@ export namespace Compiler { lastIndexWritten ??= -1; if (lastIndexWritten + 1 < codeLines.length) { - if (!((lastIndexWritten + 1 < codeLines.length) && (codeLines[lastIndexWritten + 1].match(/^\s*[{|}]\s*$/) || codeLines[lastIndexWritten + 1].trim() === ""))) { + if (!((lastIndexWritten + 1 < codeLines.length) && (/^\s*[{|}]\s*$/.test(codeLines[lastIndexWritten + 1]) || codeLines[lastIndexWritten + 1].trim() === ""))) { typeLines += "\r\n"; } typeLines += codeLines.slice(lastIndexWritten + 1).join("\r\n"); diff --git a/src/harness/util.ts b/src/harness/util.ts index fc67ac36f069e..52fada441adc8 100644 --- a/src/harness/util.ts +++ b/src/harness/util.ts @@ -84,10 +84,10 @@ function guessIndentation(lines: string[]) { export function getByteOrderMarkLength(text: string): number { if (text.length >= 1) { const ch0 = text.charCodeAt(0); - if (ch0 === 0xfeff) return 1; - if (ch0 === 0xfe) return text.length >= 2 && text.charCodeAt(1) === 0xff ? 2 : 0; - if (ch0 === 0xff) return text.length >= 2 && text.charCodeAt(1) === 0xfe ? 2 : 0; - if (ch0 === 0xef) return text.length >= 3 && text.charCodeAt(1) === 0xbb && text.charCodeAt(2) === 0xbf ? 3 : 0; + if (ch0 === 0xFEFF) return 1; + if (ch0 === 0xFE) return text.length >= 2 && text.charCodeAt(1) === 0xFF ? 2 : 0; + if (ch0 === 0xFF) return text.length >= 2 && text.charCodeAt(1) === 0xFE ? 2 : 0; + if (ch0 === 0xEF) return text.length >= 3 && text.charCodeAt(1) === 0xBB && text.charCodeAt(2) === 0xBF ? 3 : 0; } return 0; } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 23f8d844c9856..cccd91cfc2a0c 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -3793,7 +3793,7 @@ export class ProjectService { sourceMapFileInfo.getSnapshot(); if (sourceMapFileInfo.documentPositionMapper !== undefined) { sourceMapFileInfo.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo.sourceInfos); - return sourceMapFileInfo.documentPositionMapper ? sourceMapFileInfo.documentPositionMapper : undefined; + return sourceMapFileInfo.documentPositionMapper || undefined; } } declarationInfo.sourceMapFilePath = undefined; diff --git a/src/server/project.ts b/src/server/project.ts index 90205d695015c..eb1779638f24b 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2384,7 +2384,7 @@ function extractUnresolvedImportsFromSourceFile( if ( (!resolvedModule || !resolutionExtensionIsTSOrJson(resolvedModule.extension)) && !isExternalModuleNameRelative(name) && - !ambientModules.some(m => m === name) + !ambientModules.includes(name) ) { unresolvedImports = append(unresolvedImports, parsePackageName(name).packageName); } diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 8635d543cdb06..b254aba33a034 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -422,9 +422,7 @@ export class ScriptInfo { if (hasMixedContent || this.isDynamic) { this.realpath = this.path; } - this.scriptKind = scriptKind - ? scriptKind - : getScriptKindFromFileName(fileName); + this.scriptKind = scriptKind || getScriptKindFromFileName(fileName); } /** @internal */ diff --git a/src/server/session.ts b/src/server/session.ts index 006eb57d7af70..7908f348b92a9 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -204,7 +204,7 @@ export const nullCancellationToken: ServerCancellationToken = { function hrTimeToMilliseconds(time: [number, number]): number { const seconds = time[0]; const nanoseconds = time[1]; - return ((1e9 * seconds) + nanoseconds) / 1000000.0; + return ((1e9 * seconds) + nanoseconds) / 1000000; } function isDeclarationFileInJSOnlyNonConfiguredProject(project: Project, file: NormalizedPath) { @@ -2503,7 +2503,7 @@ export class Session implements EventSender { return { start: scriptInfo.positionToLineOffset(edit.span.start), end: scriptInfo.positionToLineOffset(textSpanEnd(edit.span)), - newText: edit.newText ? edit.newText : "", + newText: edit.newText || "", }; }); } @@ -3155,7 +3155,7 @@ export class Session implements EventSender { return { start: scriptInfo.positionToLineOffset(change.span.start), end: scriptInfo.positionToLineOffset(change.span.start + change.span.length), - newText: change.newText ? change.newText : "", + newText: change.newText || "", }; } diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 07ac83e40ea19..71710bd8327bd 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -882,7 +882,7 @@ function getArgBindingName(funcNode: Expression, transformer: Transformer): Synt } function getOriginalNode(node: Node): Node { - return node.original ? node.original : node; + return node.original ?? node; } } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index e2b83f0c5fe8b..f8ad1d38bfdf3 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -607,7 +607,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog // has named bindings d.importClause?.namedBindings && // is not being fully removed - emptyImportDeclarations.indexOf(d) === -1 && + !emptyImportDeclarations.includes(d) && // is not gaining named imports !addToExisting.get(d.importClause)?.namedImports && // all named imports are being removed @@ -632,8 +632,8 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog const importDeclaration = findAncestor(declaration, isImportDeclaration); if ( importDeclaration && - emptyImportDeclarations.indexOf(importDeclaration) === -1 && - namedBindingsToDelete.indexOf(importDeclaration) === -1 + !emptyImportDeclarations.includes(importDeclaration) && + !namedBindingsToDelete.includes(importDeclaration) ) { if (declaration.kind === SyntaxKind.ImportClause) { changeTracker.delete(sourceFile, declaration.name!); diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 522577f9d8f87..c1de99fb7c23b 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1762,7 +1762,7 @@ export namespace Core { const called = climbPastPropertyAccess(name); const call = isCallExpression(called.parent) && called.parent.expression === called ? called.parent : undefined; const referenceSymbol = checker.getSymbolAtLocation(name); - if (referenceSymbol && checker.getRootSymbols(referenceSymbol).some(s => s === symbol)) { + if (referenceSymbol && checker.getRootSymbols(referenceSymbol).includes(symbol)) { if (cb(name, call)) { return true; } diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 45d80841d1894..cfc3c4956ed83 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -49,7 +49,7 @@ export function getAllRules(): RuleSpec[] { } } function anyTokenExcept(...tokens: SyntaxKind[]): TokenRange { - return { tokens: allTokens.filter(t => !tokens.some(t2 => t2 === t)), isSpecific: false }; + return { tokens: allTokens.filter(t => !tokens.includes(t)), isSpecific: false }; } const anyToken: TokenRange = { tokens: allTokens, isSpecific: false }; diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 0f8cb859d6822..6a108c9990493 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -311,12 +311,12 @@ function getCommentDisplayParts(tag: JSDocTag, checker?: TypeChecker): SymbolDis forEach(templateTag.typeParameters, tp => { displayParts.push(namePart(tp.getText())); if (lastTypeParameter !== tp) { - displayParts.push(...[punctuationPart(SyntaxKind.CommaToken), spacePart()]); + displayParts.push(punctuationPart(SyntaxKind.CommaToken), spacePart()); } }); } if (comment) { - displayParts.push(...[spacePart(), ...getDisplayPartsFromComment(comment, checker)]); + displayParts.push(spacePart(), ...getDisplayPartsFromComment(comment, checker)); } return displayParts; case SyntaxKind.JSDocTypeTag: @@ -341,7 +341,7 @@ function getCommentDisplayParts(tag: JSDocTag, checker?: TypeChecker): SymbolDis function addComment(s: string) { if (comment) { - if (s.match(/^https?$/)) { + if (/^https?$/.test(s)) { return [textPart(s), ...getDisplayPartsFromComment(comment, checker)]; } else { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index b4c32d566b126..8a05e2e6b5d55 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -593,7 +593,7 @@ function mergeChildren(children: NavigationBarNode[], node: NavigationBarNode): return true; } - if (itemsWithSameName instanceof Array) { + if (Array.isArray(itemsWithSameName)) { for (const itemWithSameName of itemsWithSameName) { if (tryMerge(itemWithSameName, child, index, node)) { return false; diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index 5613d2011102b..b282f67be8d10 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -137,7 +137,7 @@ export function getSourceMapper(host: SourceMapperHost): SourceMapper { function getOrCreateSourceFileLike(fileName: string): SourceFileLike | undefined { const path = toPath(fileName); const fileFromCache = sourceFileLike.get(path); - if (fileFromCache !== undefined) return fileFromCache ? fileFromCache : undefined; + if (fileFromCache !== undefined) return fileFromCache || undefined; if (!host.readFile || host.fileExists && !host.fileExists(fileName)) { sourceFileLike.set(path, false); @@ -148,7 +148,7 @@ export function getSourceMapper(host: SourceMapperHost): SourceMapper { const text = host.readFile(fileName); const file = text ? createSourceFileLike(text) : false; sourceFileLike.set(path, file); - return file ? file : undefined; + return file || undefined; } // This can be called from source mapper in either source program or program that includes generated file diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 83db802709fe3..e0a5ec5d1d633 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2040,6 +2040,8 @@ export function getPossibleTypeArgumentsInfo(tokenIn: Node | undefined, sourceFi // This is a rare case, but one that saves on a _lot_ of work if true - if the source file has _no_ `<` character, // then there obviously can't be any type arguments - no expensive brace-matching backwards scanning required + // We want to indicate that the search should go backwards for perf. + // eslint-disable-next-line unicorn/prefer-includes if (sourceFile.text.lastIndexOf("<", tokenIn ? tokenIn.pos : sourceFile.text.length) === -1) { return undefined; } diff --git a/src/testRunner/parallel/host.ts b/src/testRunner/parallel/host.ts index 400971655c6b4..93845fa4f420e 100644 --- a/src/testRunner/parallel/host.ts +++ b/src/testRunner/parallel/host.ts @@ -215,7 +215,7 @@ export function start(importTests: () => Promise): void { function startDelayed(perfData: { [testHash: string]: number; } | undefined, totalCost: number) { console.log(`Discovered ${tasks.length} unittest suites` + (newTasks.length ? ` and ${newTasks.length} new suites.` : ".")); console.log("Discovering runner-based tests..."); - const discoverStart = +(new Date()); + const discoverStart = Date.now(); for (const runner of runners) { for (const file of runner.getTestFiles()) { let size: number; @@ -254,7 +254,7 @@ export function start(importTests: () => Promise): void { const packfraction = 0.9; const chunkSize = 1000; // ~1KB or 1s for sending batches near the end of a test const batchSize = (totalCost / workerCount) * packfraction; // Keep spare tests for unittest thread in reserve - console.log(`Discovered ${tasks.length} test files in ${+(new Date()) - discoverStart}ms.`); + console.log(`Discovered ${tasks.length} test files in ${Date.now() - discoverStart}ms.`); console.log(`Starting to run tests using ${workerCount} threads...`); const totalFiles = tasks.length; diff --git a/src/testRunner/parallel/worker.ts b/src/testRunner/parallel/worker.ts index 0dde6ae90cab3..af6ad876b94d3 100644 --- a/src/testRunner/parallel/worker.ts +++ b/src/testRunner/parallel/worker.ts @@ -226,7 +226,7 @@ export function start(importTests: () => Promise): void { function runSuite(task: Task, suite: Mocha.Suite, fn: (result: TaskResult) => void) { const errors: ErrorInfo[] = []; const passes: TestInfo[] = []; - const start = +new Date(); + const start = Date.now(); const runner = new Mocha.Runner(suite, { delay: false }); runner @@ -244,7 +244,7 @@ export function start(importTests: () => Promise): void { runner.dispose(); }) .run(() => { - fn({ task, errors, passes, passing: passes.length, duration: +new Date() - start }); + fn({ task, errors, passes, passing: passes.length, duration: Date.now() - start }); }); } diff --git a/src/testRunner/projectsRunner.ts b/src/testRunner/projectsRunner.ts index 5befdf497dff2..83f95ea345b06 100644 --- a/src/testRunner/projectsRunner.ts +++ b/src/testRunner/projectsRunner.ts @@ -290,7 +290,7 @@ class ProjectTestCase { } if (errs.length) { - throw Error(errs.join("\n ")); + throw new Error(errs.join("\n ")); } } } diff --git a/src/testRunner/unittests/config/commandLineParsing.ts b/src/testRunner/unittests/config/commandLineParsing.ts index b23bfb4997d9f..759b6ffb4b6ce 100644 --- a/src/testRunner/unittests/config/commandLineParsing.ts +++ b/src/testRunner/unittests/config/commandLineParsing.ts @@ -13,7 +13,7 @@ describe("unittests:: config:: commandLineParsing:: parseCommandLine", () => { baseline.push("WatchOptions::"); baseline.push(jsonToReadableText(parsed.watchOptions)); baseline.push("FileNames::"); - baseline.push(parsed.fileNames.join()); + baseline.push(parsed.fileNames.join(",")); baseline.push("Errors::"); baseline.push(ts.formatDiagnostics(parsed.errors, { getCurrentDirectory: () => "/", @@ -205,7 +205,7 @@ describe("unittests:: config:: commandLineParsing:: parseBuildOptions", () => { baseline.push("WatchOptions::"); baseline.push(jsonToReadableText(parsed.watchOptions)); baseline.push("Projects::"); - baseline.push(parsed.projects.join()); + baseline.push(parsed.projects.join(",")); baseline.push("Errors::"); baseline.push(ts.formatDiagnostics(parsed.errors, { getCurrentDirectory: () => "/", diff --git a/src/testRunner/unittests/config/tsconfigParsing.ts b/src/testRunner/unittests/config/tsconfigParsing.ts index c3893dde6eb59..d2b0d2c9c05c1 100644 --- a/src/testRunner/unittests/config/tsconfigParsing.ts +++ b/src/testRunner/unittests/config/tsconfigParsing.ts @@ -59,7 +59,7 @@ describe("unittests:: config:: tsconfigParsing:: parseConfigFileTextToJson", () basePath, baselineParsed: (baseline, parsed) => { baseline.push("FileNames::"); - baseline.push(parsed.fileNames.join()); + baseline.push(parsed.fileNames.join(",")); }, })), skipJson, diff --git a/src/testRunner/unittests/helpers/baseline.ts b/src/testRunner/unittests/helpers/baseline.ts index 97146d59b03cb..8b6b9eed78cbc 100644 --- a/src/testRunner/unittests/helpers/baseline.ts +++ b/src/testRunner/unittests/helpers/baseline.ts @@ -525,5 +525,5 @@ export function baselineAfterTscCompile( } export function tscBaselineName(scenario: string, subScenario: string, commandLineArgs: readonly string[], suffix?: string) { - return `${ts.isBuildCommand(commandLineArgs) ? "tsbuild" : "tsc"}${isWatch(commandLineArgs) ? "Watch" : ""}/${scenario}/${subScenario.split(" ").join("-")}${suffix ? suffix : ""}.js`; + return `${ts.isBuildCommand(commandLineArgs) ? "tsbuild" : "tsc"}${isWatch(commandLineArgs) ? "Watch" : ""}/${scenario}/${subScenario.split(" ").join("-")}${suffix ?? ""}.js`; } diff --git a/src/testRunner/unittests/helpers/noEmit.ts b/src/testRunner/unittests/helpers/noEmit.ts index ccf3d04431e58..c4bdfc754912a 100644 --- a/src/testRunner/unittests/helpers/noEmit.ts +++ b/src/testRunner/unittests/helpers/noEmit.ts @@ -364,7 +364,7 @@ export function forEachNoEmitTsc(commandType: string[]): void { { caption: "Introduce error", edit: sys => sys.writeFile("/home/src/projects/project/a.ts", aTsContent), - discrepancyExplanation: compilerOptions.incremental && subScenario.indexOf("multiFile/syntax") !== -1 ? () => [ + discrepancyExplanation: compilerOptions.incremental && subScenario.includes("multiFile/syntax") ? () => [ "DtsSignature of ts files: Incremental build have dts signature for ts files from emit so its not d.ts or same as file version", ] : undefined, }, @@ -373,7 +373,7 @@ export function forEachNoEmitTsc(commandType: string[]): void { edit: noop, commandLineArgs: [...commandType, "."], }, - compilerOptions.incremental && subScenario.indexOf("multiFile/syntax") !== -1 ? { + compilerOptions.incremental && subScenario.includes("multiFile/syntax") ? { ...noChangeRun, discrepancyExplanation: () => [ "DtsSignature of files: Incremental build have dts signature for ts files from emit so its not d.ts or same as file version", diff --git a/src/testRunner/unittests/helpers/tsc.ts b/src/testRunner/unittests/helpers/tsc.ts index 85cc75125190c..7f9df97269e26 100644 --- a/src/testRunner/unittests/helpers/tsc.ts +++ b/src/testRunner/unittests/helpers/tsc.ts @@ -229,7 +229,7 @@ function verifyTscEditDiscrepancies( incrementalReadableBuildInfo.affectedFilesPendingEmit?.forEach(([actualFileOrArray]) => { const actualFile = ts.isString(actualFileOrArray) ? actualFileOrArray : actualFileOrArray[0]; if ( - !ts.find( + !ts.some( (cleanReadableBuildInfo as ReadableIncrementalMultiFileEmitBuildInfo)?.affectedFilesPendingEmit, ([expectedFileOrArray]) => actualFile === (ts.isString(expectedFileOrArray) ? expectedFileOrArray : expectedFileOrArray[0]), ) @@ -259,7 +259,7 @@ function verifyTscEditDiscrepancies( const readableCleanBuildInfo = cleanReadableBuildInfo as ReadableIncrementalBuildInfo | undefined; readableIncrementalBuildInfo?.changeFileSet?.forEach(actualFile => { if ( - !ts.find( + !ts.some( readableCleanBuildInfo?.changeFileSet, expectedFile => actualFile === expectedFile, ) @@ -308,7 +308,7 @@ function verifyTscEditDiscrepancies( // if there are errors in the file !ts.isString(cleanFileDiagnostics?.[1]) && // and its not already verified, its issue with the error caching - !ts.find( + !ts.some( readableIncrementalBuildInfo?.semanticDiagnosticsPerFile, ([actualFile]) => actualFile === expectedFile, ) @@ -323,12 +323,12 @@ function verifyTscEditDiscrepancies( readableIncrementalBuildInfo?.emitDiagnosticsPerFile?.forEach(([actualFile]) => { if ( // Does not have emit diagnostics in clean buildInfo - !ts.find( + !ts.some( readableCleanBuildInfo!.emitDiagnosticsPerFile, ([expectedFile]) => actualFile === expectedFile, ) && // Is not marked as affectedFilesPendingEmit in clean buildInfo - (!ts.find( + (!ts.some( (readableCleanBuildInfo as ReadableIncrementalMultiFileEmitBuildInfo).affectedFilesPendingEmit, ([expectedFileOrArray]) => actualFile === (ts.isString(expectedFileOrArray) ? expectedFileOrArray : expectedFileOrArray[0]), )) && diff --git a/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts b/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts index aef731f604235..6d6c3225543fc 100644 --- a/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts +++ b/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts @@ -907,7 +907,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, watches.forEach(path, ({ cb, inode }) => { if (this.inodeWatching && inode !== undefined && inode !== currentInode) return; let relativeFileName = eventFullPath ? this.getRelativePathToDirectory(fullPath, eventFullPath) : ""; - if (useTildeSuffix) relativeFileName = (relativeFileName ? relativeFileName : getBaseFileName(fullPath)) + "~"; + if (useTildeSuffix) relativeFileName = (relativeFileName || getBaseFileName(fullPath)) + "~"; cb(eventName, relativeFileName); }); } diff --git a/src/testRunner/unittests/moduleResolution.ts b/src/testRunner/unittests/moduleResolution.ts index 4cc25806235dd..7d8f927ef9651 100644 --- a/src/testRunner/unittests/moduleResolution.ts +++ b/src/testRunner/unittests/moduleResolution.ts @@ -63,8 +63,8 @@ function runBaseline(scenario: string, baselines: readonly string[]) { describe("unittests:: moduleResolution:: Node module resolution - relative paths", () => { // node module resolution does _not_ implicitly append these extensions to an extensionless path (though will still attempt to load them if explicitly) - const nonImplicitExtensions = [ts.Extension.Mts, ts.Extension.Dmts, ts.Extension.Mjs, ts.Extension.Cts, ts.Extension.Dcts, ts.Extension.Cjs]; - const autoExtensions = ts.filter(ts.supportedTSExtensionsFlat, e => !nonImplicitExtensions.includes(e)); + const nonImplicitExtensions = new Set([ts.Extension.Mts, ts.Extension.Dmts, ts.Extension.Mjs, ts.Extension.Cts, ts.Extension.Dcts, ts.Extension.Cjs]); + const autoExtensions = ts.filter(ts.supportedTSExtensionsFlat, e => !nonImplicitExtensions.has(e)); it("load as file", () => { const baselines: string[] = []; diff --git a/src/testRunner/unittests/services/hostNewLineSupport.ts b/src/testRunner/unittests/services/hostNewLineSupport.ts index 3879e78d0bf68..ad4e15a23ccd5 100644 --- a/src/testRunner/unittests/services/hostNewLineSupport.ts +++ b/src/testRunner/unittests/services/hostNewLineSupport.ts @@ -38,6 +38,7 @@ describe("unittests:: services:: hostNewLineSupport", () => { assert(result.outputFiles.length === 1, "a number of files other than 1 was output"); assert(result.outputFiles[0].name === "input.js", `Expected output file name input.js, but got ${result.outputFiles[0].name}`); assert(result.outputFiles[0].text.match(options.newLine === ts.NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); + // eslint-disable-next-line unicorn/prefer-regexp-test assert(!result.outputFiles[0].text.match(options.newLine === ts.NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); } @@ -55,6 +56,7 @@ describe("unittests:: services:: hostNewLineSupport", () => { const span = ls.getOutliningSpans("input.ts")[0]; const textAfterSpanCollapse = content.substring(span.textSpan.start + span.textSpan.length); assert(textAfterSpanCollapse.match(options.newLine === ts.NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); + // eslint-disable-next-line unicorn/prefer-regexp-test assert(!textAfterSpanCollapse.match(options.newLine === ts.NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); } diff --git a/src/testRunner/unittests/tsserver/autoImportProvider.ts b/src/testRunner/unittests/tsserver/autoImportProvider.ts index cc3d1e052045b..ed840732c80f3 100644 --- a/src/testRunner/unittests/tsserver/autoImportProvider.ts +++ b/src/testRunner/unittests/tsserver/autoImportProvider.ts @@ -281,7 +281,7 @@ describe("unittests:: tsserver:: autoImportProvider::", () => { packages.push(createPackage(i)); } - const dependencies = packages.reduce((hash, p) => ({ ...hash, [JSON.parse(p[0].content).name]: "*" }), {}); + const dependencies = Object.fromEntries(packages.map(p => [JSON.parse(p[0].content).name, "*"])); const packageJson: File = { path: "/user/username/projects/project/package.json", content: jsonToReadableText(dependencies) }; const { session } = setup([...ts.flatten(packages), indexTs, tsconfig, packageJson]); diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index 65228e4f13d3c..9faf5ae14079b 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -1344,7 +1344,7 @@ bar;`, compilerOptions: { module: "none", composite: true, - ...(extendOptionsProject2 || {}), + ...extendOptionsProject2, }, references: [ { path: "../project1" }, @@ -1547,7 +1547,7 @@ bar;`, const config: File = { path: `/user/username/projects/myproject/${packageName}/tsconfig.json`, content: jsonToReadableText({ - compilerOptions: { composite: true, ...optionsToExtend || {} }, + compilerOptions: { composite: true, ...optionsToExtend }, references: references?.map(path => ({ path: `../${path}` })), }), };