eslint-plugin/lib/rules/no-package-imports.js

102 lines
2.9 KiB
JavaScript

/**
* @fileoverview Fix relative and absolute imports to invalid locations
* @author @gosticks
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: "Fix relative and absolute imports to invalid locations",
category: "Possible Errors",
recommended: false,
},
fixable: "code", // or "code" or "whitespace"
schema: [
{
type: "object",
properties: {
options: {
type: "array",
items: {
anyOf: [
{
type: "object",
properties: {
invalidPrefix: {
type: "string",
},
invalidSuffix: {
type: "string",
},
monorepoRoot: {
type: "string",
},
template: {
type: "string",
},
},
additionalProperties: true,
},
],
},
},
},
},
],
messages: {
incorrectImport: "Import is invalid within the current monorepo setup",
},
},
create: function (context) {
// create a replacer regex and a target string
const replacers = context.options[0].options.map((option) => [
// match all string [../]*$invalidPrefix/anything/$invalidSuffix[/anything]
new RegExp(
`(?:(?:..\\/)*${option.invalidPrefix})+\\/([^\\/]+)\\/${option.invalidSuffix}(\\/(.+))?`
),
option.template ?? `${option.monorepoRoot}/$1$2`,
]);
/**
* report an error.
* @param {ASTNode} node the node to report.
* @param {[RegExp, string]} replacer regex to match and template for substitution
* @returns {void}
*/
function report(node, [replacer, str]) {
context.report({
node,
messageId: "incorrectImport",
fix: function (fixer) {
return fixer.replaceTextRange(
[node.source.range[0] + 1, node.source.range[1] - 1],
`${node.source.value.replace(replacer, str)}`
);
},
});
}
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
return {
ImportDeclaration(node) {
// iterate over each replacer pair and substitute import source if needed
replacers.forEach(([replacer, str]) => {
const matchResults = node.source.value.match(replacer);
if (matchResults) {
report(node, [replacer, str]);
}
});
},
};
},
};