diff --git a/docs/rules/no-restricted-imports.md b/docs/rules/no-restricted-imports.md index d8e06101b41..dfef65faa5a 100644 --- a/docs/rules/no-restricted-imports.md +++ b/docs/rules/no-restricted-imports.md @@ -91,6 +91,17 @@ or like this if you want to apply a custom message to pattern matches: The custom message will be appended to the default error message. +Pattern matches can also be configured to be case-sensitive: + +```json +"no-restricted-imports": ["error", { + "patterns": [{ + "group": ["import1/private/prefix[A-Z]*"], + "caseSensitive": true + }] +}] +``` + To restrict the use of all Node.js core imports (via ): ```json @@ -172,6 +183,15 @@ import * as Foo from "foo"; import pick from 'lodash/pick'; ``` +```js +/*eslint no-restricted-imports: ["error", { patterns: [{ + group: ["foo[A-Z]*"], + caseSensitive: true +}]}]*/ + +import pick from 'fooBar'; +``` + Examples of **correct** code for this rule: ```js @@ -214,6 +234,15 @@ import { AllowedObject as DisallowedObject } from "foo"; import lodash from 'lodash'; ``` +```js +/*eslint no-restricted-imports: ["error", { patterns: [{ + group: ["foo[A-Z]*"], + caseSensitive: true +}]}]*/ + +import pick from 'food'; +``` + ## When Not To Use It Don't use this rule or don't include a module in the list for this rule if you want to be able to import a module in your project without an ESLint error or warning. diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js index 6813037f13a..f4f3d219a1b 100644 --- a/lib/rules/no-restricted-imports.js +++ b/lib/rules/no-restricted-imports.js @@ -63,6 +63,9 @@ const arrayOfStringsOrObjectPatterns = { message: { type: "string", minLength: 1 + }, + caseSensitive: { + type: "boolean" } }, additionalProperties: false, @@ -142,10 +145,18 @@ module.exports = { }, {}); // Handle patterns too, either as strings or groups - const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || []; - const restrictedPatternGroups = restrictedPatterns.length > 0 && typeof restrictedPatterns[0] === "string" - ? [{ matcher: ignore().add(restrictedPatterns) }] - : restrictedPatterns.map(({ group, message }) => ({ matcher: ignore().add(group), customMessage: message })); + let restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || []; + + // standardize to array of objects if we have an array of strings + if (restrictedPatterns.length > 0 && typeof restrictedPatterns[0] === "string") { + restrictedPatterns = [{ group: restrictedPatterns }]; + } + + // relative paths are supported for this rule + const restrictedPatternGroups = restrictedPatterns.map(({ group, message, caseSensitive }) => ({ + matcher: ignore({ allowRelativePaths: true, ignorecase: !caseSensitive }).add(group), + customMessage: message + })); // if no imports are restricted we don't need to check if (Object.keys(restrictedPaths).length === 0 && restrictedPatternGroups.length === 0) { diff --git a/lib/rules/no-restricted-modules.js b/lib/rules/no-restricted-modules.js index 26e75ef81a2..d92aa7a86bc 100644 --- a/lib/rules/no-restricted-modules.js +++ b/lib/rules/no-restricted-modules.js @@ -103,7 +103,8 @@ module.exports = { return {}; } - const ig = ignore().add(restrictedPatterns); + // relative paths are supported for this rule + const ig = ignore({ allowRelativePaths: true }).add(restrictedPatterns); /** diff --git a/package.json b/package.json index 948d8d959ec..2eafe5ea983 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js index c86e67ecf65..67db38151b5 100644 --- a/tests/lib/rules/no-restricted-imports.js +++ b/tests/lib/rules/no-restricted-imports.js @@ -54,6 +54,16 @@ ruleTester.run("no-restricted-imports", rule, { code: "import withPatterns from \"foo/bar\";", options: [{ patterns: [{ group: ["foo/*", "!foo/bar"], message: "foo is forbidden, use bar instead" }] }] }, + { + code: "import withPatternsCaseSensitive from 'foo';", + options: [{ + patterns: [{ + group: ["FOO"], + message: "foo is forbidden, use bar instead", + caseSensitive: true + }] + }] + }, { code: "import AllowedObject from \"foo\";", options: [{ @@ -288,6 +298,16 @@ ruleTester.run("no-restricted-imports", rule, { column: 1, endColumn: 36 }] + }, { + code: "import withPatternsCaseInsensitive from 'foo';", + options: [{ patterns: [{ group: ["FOO"] }] }], + errors: [{ + message: "'foo' import is restricted from being used by a pattern.", + type: "ImportDeclaration", + line: 1, + column: 1, + endColumn: 47 + }] }, { code: "import withGitignores from \"foo/bar\";", options: [{ patterns: ["foo/*", "!foo/baz"] }],