Skip to content

Commit

Permalink
Update: no-restricted-imports to check re-export (fixes #9678) (#11064)
Browse files Browse the repository at this point in the history
* Fix: no-restricted-imports to check re-export (fixes #9678)

* Add export as use case
  • Loading branch information
nzakas authored and btmills committed Nov 9, 2018
1 parent 3dd7493 commit 79a2797
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 23 deletions.
16 changes: 15 additions & 1 deletion docs/rules/no-restricted-imports.md
@@ -1,6 +1,6 @@
# Disallow specific imports (no-restricted-imports)

Imports are an ES6/ES2015 standard for making the functionality of other modules available in your current module. In CommonJS this is implemented through the require() call which makes this ESLint rule roughly equivalent to its CommonJS counterpart `no-restricted-modules`.
Imports are an ES6/ES2015 standard for making the functionality of other modules available in your current module. In CommonJS this is implemented through the `require()` call which makes this ESLint rule roughly equivalent to its CommonJS counterpart `no-restricted-modules`.

Why would you want to restrict imports?

Expand Down Expand Up @@ -87,6 +87,18 @@ Examples of **incorrect** code for this rule:
import fs from 'fs';
```

```js
/*eslint no-restricted-imports: ["error", "fs"]*/

export { fs } from 'fs';
```

```js
/*eslint no-restricted-imports: ["error", "fs"]*/

export * from 'fs';
```

```js
/*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/

Expand Down Expand Up @@ -135,13 +147,15 @@ Examples of **correct** code for this rule:
/*eslint no-restricted-imports: ["error", "fs"]*/

import crypto from 'crypto';
export { foo } from "bar";
```

```js
/*eslint no-restricted-imports: ["error", { "paths": ["fs"], "patterns": ["eslint/*"] }]*/

import crypto from 'crypto';
import eslint from 'eslint';
export * from "path";
```

```js
Expand Down
60 changes: 38 additions & 22 deletions lib/rules/no-restricted-imports.js
Expand Up @@ -236,31 +236,47 @@ module.exports = {
return restrictedPatterns.length > 0 && restrictedPatternsMatcher.ignores(importSource);
}

return {
ImportDeclaration(node) {
const importSource = node.source.value.trim();
const importNames = node.specifiers.reduce((set, specifier) => {
if (specifier.type === "ImportDefaultSpecifier") {
set.add("default");
} else if (specifier.type === "ImportNamespaceSpecifier") {
set.add("*");
} else {
set.add(specifier.imported.name);
}
return set;
}, new Set());

if (isRestrictedForEverythingImported(importSource, importNames)) {
reportPathForEverythingImported(importSource, node);
/**
* Checks a node to see if any problems should be reported.
* @param {ASTNode} node The node to check.
* @returns {void}
* @private
*/
function checkNode(node) {
const importSource = node.source.value.trim();
const importNames = node.specifiers ? node.specifiers.reduce((set, specifier) => {
if (specifier.type === "ImportDefaultSpecifier") {
set.add("default");
} else if (specifier.type === "ImportNamespaceSpecifier") {
set.add("*");
} else if (specifier.imported) {
set.add(specifier.imported.name);
} else if (specifier.local) {
set.add(specifier.local.name);
}
return set;
}, new Set()) : new Set();

if (isRestrictedPath(importSource, importNames)) {
reportPath(node);
}
if (isRestrictedPattern(importSource)) {
reportPathForPatterns(node);
}
if (isRestrictedForEverythingImported(importSource, importNames)) {
reportPathForEverythingImported(importSource, node);
}

if (isRestrictedPath(importSource, importNames)) {
reportPath(node);
}
if (isRestrictedPattern(importSource)) {
reportPathForPatterns(node);
}
}

return {
ImportDeclaration: checkNode,
ExportNamedDeclaration(node) {
if (node.source) {
checkNode(node);
}
},
ExportAllDeclaration: checkNode
};
}
};
18 changes: 18 additions & 0 deletions tests/lib/rules/no-restricted-imports.js
Expand Up @@ -193,6 +193,24 @@ ruleTester.run("no-restricted-imports", rule, {
code: "import withGitignores from \"foo/bar\";",
options: [{ patterns: ["foo/*", "!foo/baz"] }],
errors: [{ message: "'foo/bar' import is restricted from being used by a pattern.", type: "ImportDeclaration" }]
}, {
code: "export * from \"fs\";",
options: ["fs"],
errors: [{ message: "'fs' import is restricted from being used.", type: "ExportAllDeclaration" }]
}, {
code: "export {a} from \"fs\";",
options: ["fs"],
errors: [{ message: "'fs' import is restricted from being used.", type: "ExportNamedDeclaration" }]
}, {
code: "export {foo as b} from \"fs\";",
options: [{
paths: [{
name: "fs",
importNames: ["foo"],
message: "Don't import 'foo'."
}]
}],
errors: [{ message: "'fs' import is restricted from being used. Don't import 'foo'.", type: "ExportNamedDeclaration" }]
}, {
code: "import withGitignores from \"foo\";",
options: [{
Expand Down

0 comments on commit 79a2797

Please sign in to comment.