eslint-plugin-path
Version:
An ESLint plugin for enforcing consistent imports across project. In other words, it helps to replace all relatives import with absolutes dependinng on settings.
127 lines • 4.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../utils");
const import_types_1 = require("../utils/import-types");
const path_1 = require("path");
/**
* Creates an absolute path to target using an array of alias items
* @param {string} target
* @param {AliasItem[]} aliases
* @returns {string} - absolute path to target
*/
function getAbsolutePathToTarget(target, aliases = []) {
if (!target || !aliases) {
return "";
}
const absolutePath = aliases
.map(({ path, alias }) => `${alias || ""}${(0, path_1.relative)(path, target)}`)
.filter((path) => !(0, import_types_1.isRelativeToParent)(path) && path.indexOf("..") === -1);
return (absolutePath && absolutePath[0]) || "";
}
/**
* Calculate slash counts
* @param {string} path
* @returns {number} - slash counts
*/
function getSlashCounts(path) {
if (!path) {
return 0;
}
return (path.split(/[\\/]/).length || 1) - 1;
}
/**
* Replace all backslashes (\) with forward slashes (/)
* @param {string} path
* @returns {string} - path with forward slashes
*/
function replaceBackSlashesWithForward(path) {
if (!path) {
return "";
}
return path.replace(/\\/g, "/");
}
/**
* Checks if the max path depth has been exceeded
* @param {string} current
* @param {RuleSettings} settings
* @returns {boolean} - true if max depth exceeded
*/
function isMaxDepthExceeded(current, settings) {
if (!current) {
return false;
}
const result = current.match(/\.\.[\\/]/g) || [];
return settings.maxDepth < result.length;
}
/**
* Rule to disallow relative imports of files where absolute is preferred
* @param {Rule.RuleContext} context
* @returns
*/
function noRelativeImportCreate(context) {
const { maxDepth = 2, suggested = false } = context.options[0] || {};
const settings = { maxDepth, suggested };
return (0, utils_1.getImport)(context, ({ node, start, value: current, end, path, packagePath, configSettings, }) => {
if (!isMaxDepthExceeded(current, settings) ||
(0, import_types_1.isExternalPath)(current, packagePath)) {
return;
}
const expected = replaceBackSlashesWithForward(getAbsolutePathToTarget(path, configSettings));
if ((settings.suggested &&
getSlashCounts(current) < getSlashCounts(expected)) ||
expected === "") {
return;
}
const data = {
current,
expected,
};
const fix = (fixer) => fixer.replaceTextRange([start + 1, end - 1], expected);
const descriptor = {
node,
messageId: "noRelativeImports",
data,
fix,
suggest: [
{
messageId: "replaceRelativeImport",
data,
fix,
},
],
};
context.report(descriptor);
});
}
const rule = {
meta: {
type: "problem",
docs: {
description: "disallow relative imports of files where absolute is preferred",
url: "https://github.com/qDanik/eslint-plugin-path/blob/main/docs/rules/no-relative-imports.md",
},
fixable: "code",
hasSuggestions: true,
schema: [
{
type: "object",
properties: {
maxDepth: {
type: "number",
},
suggested: {
type: "boolean",
},
},
additionalProperties: false,
},
],
messages: {
noRelativeImports: "Relative import path '{{current}}' should be replaced with '{{expected}}'",
replaceRelativeImport: "Replace relative import path '{{current}}' with absolute '{{expected}}'",
},
},
create: noRelativeImportCreate,
};
exports.default = rule;
//# sourceMappingURL=no-relative-imports.js.map