UNPKG

3.01 kBJavaScriptView Raw
1const {docsUrl} = require('../utilities');
2
3module.exports = {
4 meta: {
5 docs: {
6 description: 'Prevent importing the entirety of a package.',
7 category: 'Best Practices',
8 recommended: false,
9 uri: docsUrl('restrict-full-import'),
10 },
11 schema: [
12 {
13 restricted: {
14 type: 'array',
15 items: {
16 type: 'string',
17 },
18 uniqueItems: true,
19 },
20 },
21 ],
22 },
23
24 create(context) {
25 const restricted = context.options[0] || [];
26
27 function isRestrictedModule(mod) {
28 return restricted.indexOf(mod) >= 0;
29 }
30
31 function isPotentiallyProblematicLeft(left) {
32 return (
33 left.type === 'Identifier' ||
34 (left.type === 'ObjectPattern' &&
35 left.properties.some((prop) => {
36 return (
37 prop.type === 'SpreadProperty' ||
38 prop.type === 'ExperimentalRestProperty' ||
39 prop.type === 'RestElement'
40 );
41 })) ||
42 (left.type === 'ArrayPattern' &&
43 left.elements.some((element) => {
44 return element != null && element.type === 'RestElement';
45 }))
46 );
47 }
48
49 function isPotentiallyProblematicRight(right) {
50 return (
51 right &&
52 right.type === 'CallExpression' &&
53 right.callee.type === 'Identifier' &&
54 right.callee.name === 'require' &&
55 isRestrictedModule(right.arguments[0].value)
56 );
57 }
58
59 function isFullImportSpecifier(specifier) {
60 return (
61 specifier.type === 'ImportDefaultSpecifier' ||
62 specifier.type === 'ImportNamespaceSpecifier' ||
63 (specifier.type === 'ImportSpecifier' &&
64 specifier.imported.name === 'default')
65 );
66 }
67
68 function hasFullImport(specifiers) {
69 return specifiers.some(isFullImportSpecifier);
70 }
71
72 function checkImportDeclaration(node) {
73 const specifiers = node.specifiers;
74
75 if (isRestrictedModule(node.source.value) && hasFullImport(specifiers)) {
76 context.report({
77 node:
78 specifiers.length > 1
79 ? specifiers.find(isFullImportSpecifier)
80 : node,
81 message: `Unexpected full import of restricted module '${node.source.value}'.`,
82 });
83 }
84 }
85
86 function checkRequire(node, left, right) {
87 if (
88 isPotentiallyProblematicLeft(left) &&
89 isPotentiallyProblematicRight(right)
90 ) {
91 context.report({
92 node,
93 message: `Unexpected full import of restricted module '${right.arguments[0].value}'.`,
94 });
95 }
96 }
97
98 function checkVariableDeclarator(node) {
99 checkRequire(node, node.id, node.init);
100 }
101
102 function checkAssignmentExpression(node) {
103 checkRequire(node, node.left, node.right);
104 }
105
106 return {
107 ImportDeclaration: checkImportDeclaration,
108 VariableDeclarator: checkVariableDeclarator,
109 AssignmentExpression: checkAssignmentExpression,
110 };
111 },
112};