Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epidemian
GitHub Repository: epidemian/eslint-plugin-import
Path: blob/main/src/rules/named.js
829 views
1
import * as path from 'path';
2
import Exports from '../ExportMap';
3
import docsUrl from '../docsUrl';
4
5
module.exports = {
6
meta: {
7
type: 'problem',
8
docs: {
9
url: docsUrl('named'),
10
},
11
schema: [
12
{
13
type: 'object',
14
properties: {
15
commonjs: {
16
type: 'boolean',
17
},
18
},
19
additionalProperties: false,
20
},
21
],
22
},
23
24
create(context) {
25
const options = context.options[0] || {};
26
27
function checkSpecifiers(key, type, node) {
28
// ignore local exports and type imports/exports
29
if (
30
node.source == null
31
|| node.importKind === 'type'
32
|| node.importKind === 'typeof'
33
|| node.exportKind === 'type'
34
) {
35
return;
36
}
37
38
if (!node.specifiers.some((im) => im.type === type)) {
39
return; // no named imports/exports
40
}
41
42
const imports = Exports.get(node.source.value, context);
43
if (imports == null) {
44
return;
45
}
46
47
if (imports.errors.length) {
48
imports.reportErrors(context, node);
49
return;
50
}
51
52
node.specifiers.forEach(function (im) {
53
if (
54
im.type !== type
55
// ignore type imports
56
|| im.importKind === 'type' || im.importKind === 'typeof'
57
) {
58
return;
59
}
60
61
const deepLookup = imports.hasDeep(im[key].name);
62
63
if (!deepLookup.found) {
64
if (deepLookup.path.length > 1) {
65
const deepPath = deepLookup.path
66
.map(i => path.relative(path.dirname(context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename()), i.path))
67
.join(' -> ');
68
69
context.report(im[key], `${im[key].name} not found via ${deepPath}`);
70
} else {
71
context.report(im[key], im[key].name + ' not found in \'' + node.source.value + '\'');
72
}
73
}
74
});
75
}
76
77
function checkRequire(node) {
78
if (
79
!options.commonjs
80
|| node.type !== 'VariableDeclarator'
81
// return if it's not an object destructure or it's an empty object destructure
82
|| !node.id || node.id.type !== 'ObjectPattern' || node.id.properties.length === 0
83
// return if there is no call expression on the right side
84
|| !node.init || node.init.type !== 'CallExpression'
85
) {
86
return;
87
}
88
89
const call = node.init;
90
const [source] = call.arguments;
91
const variableImports = node.id.properties;
92
const variableExports = Exports.get(source.value, context);
93
94
if (
95
// return if it's not a commonjs require statement
96
call.callee.type !== 'Identifier' || call.callee.name !== 'require' || call.arguments.length !== 1
97
// return if it's not a string source
98
|| source.type !== 'Literal'
99
|| variableExports == null
100
) {
101
return;
102
}
103
104
if (variableExports.errors.length) {
105
variableExports.reportErrors(context, node);
106
return;
107
}
108
109
variableImports.forEach(function (im) {
110
if (im.type !== 'Property' || !im.key || im.key.type !== 'Identifier') {
111
return;
112
}
113
114
const deepLookup = variableExports.hasDeep(im.key.name);
115
116
if (!deepLookup.found) {
117
if (deepLookup.path.length > 1) {
118
const deepPath = deepLookup.path
119
.map(i => path.relative(path.dirname(context.getFilename()), i.path))
120
.join(' -> ');
121
122
context.report(im.key, `${im.key.name} not found via ${deepPath}`);
123
} else {
124
context.report(im.key, im.key.name + ' not found in \'' + source.value + '\'');
125
}
126
}
127
});
128
}
129
130
return {
131
ImportDeclaration: checkSpecifiers.bind(null, 'imported', 'ImportSpecifier'),
132
133
ExportNamedDeclaration: checkSpecifiers.bind(null, 'local', 'ExportSpecifier'),
134
135
VariableDeclarator: checkRequire,
136
};
137
},
138
};
139
140