From 0a79ed0f8a05c90589fd25df89cd0cb0a73d90e8 Mon Sep 17 00:00:00 2001 From: Ilia Kebets Date: Tue, 28 Nov 2023 11:52:46 +0100 Subject: [PATCH 1/2] Add eslint-plugin-import module --- package-lock.json | 387 +++++++++++++++++++++- package.json | 2 + packages/jsts/src/linter/bundle-loader.ts | 9 +- typings/eslint-plugin-import/index.d.ts | 4 + 4 files changed, 389 insertions(+), 13 deletions(-) create mode 100644 typings/eslint-plugin-import/index.d.ts diff --git a/package-lock.json b/package-lock.json index 5d250d67c0c..1db3291e1c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "builtin-modules", "bytes", "eslint", + "eslint-plugin-import", "eslint-plugin-jsx-a11y", "eslint-plugin-react", "eslint-plugin-react-hooks", @@ -62,6 +63,7 @@ "builtin-modules": "3.3.0", "bytes": "3.1.2", "eslint": "8.47.0", + "eslint-plugin-import": "2.29.0", "eslint-plugin-jsx-a11y": "6.7.1", "eslint-plugin-react": "7.33.2", "eslint-plugin-react-hooks": "4.6.0", @@ -3143,6 +3145,12 @@ "inBundle": true, "license": "MIT" }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "inBundle": true + }, "node_modules/@types/lodash": { "version": "4.14.198", "dev": true, @@ -3751,6 +3759,22 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "inBundle": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.2", "inBundle": true, @@ -5321,6 +5345,126 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "inBundle": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "inBundle": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "inBundle": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "inBundle": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", + "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "inBundle": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "inBundle": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "inBundle": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "inBundle": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "inBundle": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.7.1", "resolved": "https://repox.jfrog.io/repox/api/npm/npm/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", @@ -6167,9 +6311,10 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "inBundle": true, - "license": "MIT" + "version": "1.1.2", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "inBundle": true }, "node_modules/function.prototype.name": { "version": "1.1.6", @@ -6510,6 +6655,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "inBundle": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hosted-git-info": { "version": "4.1.0", "inBundle": true, @@ -6794,14 +6951,12 @@ } }, "node_modules/is-core-module": { - "version": "2.13.0", + "version": "2.13.1", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "inBundle": true, - "license": "MIT", "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "hasown": "^2.0.0" } }, "node_modules/is-date-object": { @@ -9486,6 +9641,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "inBundle": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, "node_modules/object.hasown": { "version": "1.1.3", "inBundle": true, @@ -11714,6 +11881,39 @@ } } }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "inBundle": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "inBundle": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "inBundle": true, + "engines": { + "node": ">=4" + } + }, "node_modules/tslib": { "version": "1.14.1", "inBundle": true, @@ -14133,6 +14333,11 @@ "@types/json-schema": { "version": "7.0.13" }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, "@types/lodash": { "version": "4.14.198", "dev": true @@ -14477,6 +14682,18 @@ "array-union": { "version": "2.1.0" }, + "array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, "array.prototype.flat": { "version": "1.3.2", "requires": { @@ -15548,6 +15765,103 @@ } } }, + "eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.29.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", + "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "requires": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, "eslint-plugin-jsx-a11y": { "version": "6.7.1", "resolved": "https://repox.jfrog.io/repox/api/npm/npm/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", @@ -15989,7 +16303,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1" + "version": "1.1.2", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "function.prototype.name": { "version": "1.1.6", @@ -16171,6 +16487,14 @@ "has-symbols": "^1.0.2" } }, + "hasown": { + "version": "2.0.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, "hosted-git-info": { "version": "4.1.0", "requires": { @@ -16313,9 +16637,11 @@ "version": "1.2.7" }, "is-core-module": { - "version": "2.13.0", + "version": "2.13.1", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "is-date-object": { @@ -17931,6 +18257,17 @@ "es-abstract": "^1.22.1" } }, + "object.groupby": { + "version": "1.0.1", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, "object.hasown": { "version": "1.1.3", "requires": { @@ -19209,6 +19546,32 @@ "yn": "3.1.1" } }, + "tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://repox.jfrog.io/repox/api/npm/npm/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + } + } + }, "tslib": { "version": "1.14.1" }, diff --git a/package.json b/package.json index ecde088d2b4..8579f00d1a8 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "builtin-modules": "3.3.0", "bytes": "3.1.2", "eslint": "8.47.0", + "eslint-plugin-import": "2.29.0", "eslint-plugin-jsx-a11y": "6.7.1", "eslint-plugin-react": "7.33.2", "eslint-plugin-react-hooks": "4.6.0", @@ -123,6 +124,7 @@ "builtin-modules", "bytes", "eslint", + "eslint-plugin-import", "eslint-plugin-jsx-a11y", "eslint-plugin-react", "eslint-plugin-react-hooks", diff --git a/packages/jsts/src/linter/bundle-loader.ts b/packages/jsts/src/linter/bundle-loader.ts index 6d5230e9789..7f4d663875f 100755 --- a/packages/jsts/src/linter/bundle-loader.ts +++ b/packages/jsts/src/linter/bundle-loader.ts @@ -23,6 +23,7 @@ import { tsEslintRules } from '../rules/typescript-eslint'; import { rules as pluginRules } from 'eslint-plugin-sonarjs'; import { rules as reactESLintRules } from 'eslint-plugin-react'; import { rules as reactA11yRules } from 'eslint-plugin-jsx-a11y'; +import { rules as importRules } from 'eslint-plugin-import'; import { rules as internalRules } from '../rules'; import { customRules as internalCustomRules, CustomRule } from './custom-rules'; import { debug, getContext } from '@sonar/shared'; @@ -58,7 +59,13 @@ const loaders: { [key: string]: Function } = { * Core ESLint rules could be overridden by the implementation from specific * dependencies, which should be the default behaviour in most cases. */ - const dependencies = [eslintRules, tsEslintRules, reactESLintRules, reactA11yRules]; + const dependencies = [ + eslintRules, + tsEslintRules, + reactESLintRules, + reactA11yRules, + importRules, + ]; for (const dependencyRules of dependencies) { for (const [name, module] of Object.entries(dependencyRules)) { externalRules[name] = module; diff --git a/typings/eslint-plugin-import/index.d.ts b/typings/eslint-plugin-import/index.d.ts new file mode 100644 index 00000000000..2ddeddefd1e --- /dev/null +++ b/typings/eslint-plugin-import/index.d.ts @@ -0,0 +1,4 @@ +declare module 'eslint-plugin-import' { + import { Rule } from 'eslint'; + export const rules: { [name: string]: Rule.RuleModule }; +} From 0d2d4c54a0ec1bcc6f7022e5352a42c852c2279b Mon Sep 17 00:00:00 2001 From: Ilia Kebets Date: Tue, 28 Nov 2023 11:53:15 +0100 Subject: [PATCH 2/2] Add rule S6859 (`eslint-plugin-import/no-absolute-path`): Imports should not use absolute paths --- .../jsts/file-for-rules/javascript-S1451.json | 3 ++ .../jsts/file-for-rules/javascript-S3533.json | 3 ++ .../jsts/file-for-rules/javascript-S6859.json | 5 +++ its/sources/jsts/custom/S6859.js | 1 + .../jsts/src/linter/quickfixes/messages.ts | 1 + packages/jsts/src/linter/quickfixes/rules.ts | 3 ++ .../wrapper/quickfixes/no-absolute-path.ts | 3 ++ .../sonar/javascript/checks/CheckList.java | 1 + .../checks/NoAbsolutePathCheck.java | 36 +++++++++++++++++++ .../javascript/rules/javascript/S6859.html | 22 ++++++++++++ .../javascript/rules/javascript/S6859.json | 29 +++++++++++++++ .../rules/javascript/Sonar_way_profile.json | 3 +- 12 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 its/ruling/src/test/expected/jsts/file-for-rules/javascript-S6859.json create mode 100644 its/sources/jsts/custom/S6859.js create mode 100644 packages/jsts/tests/linter/fixtures/wrapper/quickfixes/no-absolute-path.ts create mode 100644 sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoAbsolutePathCheck.java create mode 100644 sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6859.html create mode 100644 sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6859.json diff --git a/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S1451.json b/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S1451.json index 059794a7438..102aa4fb554 100644 --- a/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S1451.json +++ b/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S1451.json @@ -203,6 +203,9 @@ "file-for-rules:S6851.js": [ 0 ], +"file-for-rules:S6859.js": [ +0 +], "file-for-rules:boundOrAssignedEvalOrArguments.js": [ 0 ] diff --git a/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S3533.json b/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S3533.json index e5619ec25a8..832c1c1b37a 100644 --- a/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S3533.json +++ b/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S3533.json @@ -55,5 +55,8 @@ ], "file-for-rules:S6438.js": [ 1 +], +"file-for-rules:S6859.js": [ +1 ] } diff --git a/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S6859.json b/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S6859.json new file mode 100644 index 00000000000..16a47329de1 --- /dev/null +++ b/its/ruling/src/test/expected/jsts/file-for-rules/javascript-S6859.json @@ -0,0 +1,5 @@ +{ +"file-for-rules:S6859.js": [ +1 +] +} diff --git a/its/sources/jsts/custom/S6859.js b/its/sources/jsts/custom/S6859.js new file mode 100644 index 00000000000..9c9e3cf9a25 --- /dev/null +++ b/its/sources/jsts/custom/S6859.js @@ -0,0 +1 @@ +const f = require('/foo/bar'); diff --git a/packages/jsts/src/linter/quickfixes/messages.ts b/packages/jsts/src/linter/quickfixes/messages.ts index 6296577e41c..d2f2039c5e0 100644 --- a/packages/jsts/src/linter/quickfixes/messages.ts +++ b/packages/jsts/src/linter/quickfixes/messages.ts @@ -28,6 +28,7 @@ const quickFixMessages = new Map([ ['comma-dangle', 'Remove this trailing comma'], ['eol-last', 'Add a new line at the end of file'], ['jsx-no-useless-fragment', 'Remove redundant fragment'], + ['no-absolute-path', 'Replace with a relative path'], ['no-empty-interface', 'Replace with type alias'], ['no-extra-bind', 'Remove .bind() call'], ['no-extra-boolean-cast', 'Remove extra cast'], diff --git a/packages/jsts/src/linter/quickfixes/rules.ts b/packages/jsts/src/linter/quickfixes/rules.ts index 6ebb8883086..12b332fdf66 100644 --- a/packages/jsts/src/linter/quickfixes/rules.ts +++ b/packages/jsts/src/linter/quickfixes/rules.ts @@ -128,4 +128,7 @@ export const quickFixRules = new Set([ 'switch-without-default', 'unnecessary-character-escapes', 'unused-import', + + // eslint-plugin-import + 'no-absolute-path', ]); diff --git a/packages/jsts/tests/linter/fixtures/wrapper/quickfixes/no-absolute-path.ts b/packages/jsts/tests/linter/fixtures/wrapper/quickfixes/no-absolute-path.ts new file mode 100644 index 00000000000..3f8b1605d66 --- /dev/null +++ b/packages/jsts/tests/linter/fixtures/wrapper/quickfixes/no-absolute-path.ts @@ -0,0 +1,3 @@ +import { foo } from '/home/project/bar'; + +foo(); diff --git a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java index 1607e850333..67efda69119 100644 --- a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java +++ b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java @@ -242,6 +242,7 @@ public static List> getAllChecks() { NestedControlFlowDepthCheck.class, NewCapCheck.class, NewOperatorMisuseCheck.class, + NoAbsolutePathCheck.class, NoAccessKeyCheck.class, NoAccessStateInSetstateCheck.class, NoAccessorFieldMismatchCheck.class, diff --git a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoAbsolutePathCheck.java b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoAbsolutePathCheck.java new file mode 100644 index 00000000000..60544a4008a --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoAbsolutePathCheck.java @@ -0,0 +1,36 @@ +/** + * SonarQube JavaScript Plugin + * Copyright (C) 2011-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.javascript.checks; + +import org.sonar.check.Rule; +import org.sonar.plugins.javascript.api.EslintBasedCheck; +import org.sonar.plugins.javascript.api.JavaScriptRule; +import org.sonar.plugins.javascript.api.TypeScriptRule; + +@TypeScriptRule +@JavaScriptRule +@Rule(key = "S6859") +public class NoAbsolutePathCheck implements EslintBasedCheck { + + @Override + public String eslintKey() { + return "no-absolute-path"; + } +} diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6859.html b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6859.html new file mode 100644 index 00000000000..0ee0b0b9a13 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6859.html @@ -0,0 +1,22 @@ +

Why is this an issue?

+

In Node.js importing modules is doable by providing an absolute path such as /lib/foo/bar.js. Doing this restricts the portability of +your code, making it specific to your computer’s file system and potentially causing issues when the code is distributed, for example, through NPM +packages.

+

How to fix it

+

Replace the absolute path with one that is relative to your current file.

+

Code examples

+

Noncompliant code example

+
+import { foo } from '/home/project/api/bar.js';
+
+

Compliant solution

+
+import { foo } from '../api/bar.js';
+
+

Resources

+

Documentation

+ + diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6859.json b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6859.json new file mode 100644 index 00000000000..3048afd405f --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6859.json @@ -0,0 +1,29 @@ +{ + "title": "Imports should not use absolute paths", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "pitfall", + "paths" + ], + "defaultSeverity": "Minor", + "ruleSpecification": "RSPEC-6859", + "sqKey": "S6859", + "scope": "All", + "quickfix": "covered", + "code": { + "impacts": { + "MAINTAINABILITY": "HIGH", + "RELIABILITY": "LOW" + }, + "attribute": "MODULAR" + }, + "compatibleLanguages": [ + "JAVASCRIPT", + "TYPESCRIPT" + ] +} diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json index 91b87e4e5a9..36ab55d9bd3 100644 --- a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json @@ -323,6 +323,7 @@ "S6852", "S6853", "S6854", - "S6855" + "S6855", + "S6859" ] }