Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epidemian
GitHub Repository: epidemian/eslint-plugin-import
Path: blob/main/src/rules/no-relative-packages.js
829 views
1
import path from 'path';
2
import readPkgUp from 'eslint-module-utils/readPkgUp';
3
4
import resolve from 'eslint-module-utils/resolve';
5
import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor';
6
import importType from '../core/importType';
7
import docsUrl from '../docsUrl';
8
9
function findNamedPackage(filePath) {
10
const found = readPkgUp({ cwd: filePath });
11
if (found.pkg && !found.pkg.name) {
12
return findNamedPackage(path.join(found.path, '../..'));
13
}
14
return found;
15
}
16
17
function checkImportForRelativePackage(context, importPath, node) {
18
const potentialViolationTypes = ['parent', 'index', 'sibling'];
19
if (potentialViolationTypes.indexOf(importType(importPath, context)) === -1) {
20
return;
21
}
22
23
const resolvedImport = resolve(importPath, context);
24
const resolvedContext = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename();
25
26
if (!resolvedImport || !resolvedContext) {
27
return;
28
}
29
30
const importPkg = findNamedPackage(resolvedImport);
31
const contextPkg = findNamedPackage(resolvedContext);
32
33
if (importPkg.pkg && contextPkg.pkg && importPkg.pkg.name !== contextPkg.pkg.name) {
34
const importBaseName = path.basename(importPath);
35
const importRoot = path.dirname(importPkg.path);
36
const properPath = path.relative(importRoot, resolvedImport);
37
const properImport = path.join(
38
importPkg.pkg.name,
39
path.dirname(properPath),
40
importBaseName === path.basename(importRoot) ? '' : importBaseName,
41
);
42
context.report({
43
node,
44
message: `Relative import from another package is not allowed. Use \`${properImport}\` instead of \`${importPath}\``,
45
});
46
}
47
}
48
49
module.exports = {
50
meta: {
51
type: 'suggestion',
52
docs: {
53
url: docsUrl('no-relative-packages'),
54
},
55
schema: [makeOptionsSchema()],
56
},
57
58
create(context) {
59
return moduleVisitor((source) => checkImportForRelativePackage(context, source.value, source), context.options[0]);
60
},
61
};
62
63