eslint-plugin-fsd-arch-validator
Version:
Validate whether module imports within your project meet the requirements of FSD architecture
93 lines (77 loc) • 2.56 kB
JavaScript
const path = require('path');
const { isPathRelative } = require('../helpers');
;
module.exports = {
meta: {
type: null, // `problem`, `suggestion`, or `layout`
docs: {
description: "Ensure modules within a singe module are relative",
recommended: false,
url: null, // URL to the documentation page for this rule
},
fixable: 'code', // Or `code` or `whitespace`
schema: [
{
type: 'object',
properties: {
alias: {
type: 'string'
}
}
}
], // Add a schema if the rule has options
},
create(context) {
const alias = context.options[0]?.alias || '';
return {
ImportDeclaration(node) {
// eg: entities/Article
const value = node.source.value
const importTo = alias ? value.replace(`${alias}/`, '') : value;
// D:\projects\eslint-plugin-fsd-path-checker\lib\rules\src\entities\Article
const fromFilename = context.getFilename();
if(shouldBeRelative(fromFilename, importTo)) {
context.report({
node,
message: 'Imports within a slice should be relative.',
fix: (fixer) => {
const normalizedPath = getNormalizedCurFilePath(fromFilename).split(path.sep).slice(0, -1).join('/');
let relativePath = path.relative(normalizedPath, `/${importTo}`).split(path.sep).join('/');
if(!relativePath.startsWith('.')) {
relativePath = `./${relativePath}`
}
return fixer.replaceText(node.source, `'${relativePath}'`)
}
});
}
}
};
},
};
const layers = {
'entities': 'entities',
'features': 'features',
'widgets': 'widgets',
'pages': 'pages',
}
function getNormalizedCurFilePath(curFilePath) {
const normalizedPath = path.toNamespacedPath(curFilePath);
return normalizedPath.split('src')[1];
}
function shouldBeRelative(from, to) {
if(isPathRelative(to)) {
return false;
}
// eg: entities/Article
const [toLayer, toSlice] = to.split('/'); // [entities, Article]
if (!toLayer || !toSlice || !layers[toLayer]) {
return false
}
const normalizedCurFilePath = getNormalizedCurFilePath(from);
const [, fromLayer, fromSlice] = normalizedCurFilePath.split(path.sep);
if (!fromSlice || !fromLayer || !layers[fromLayer]) {
return false
}
return fromSlice === toSlice && toLayer && fromLayer;
// D:\projects\eslint-plugin-fsd-path-checker\lib\rules\src\entities\Article
}