UNPKG

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
const path = require('path'); const { isPathRelative } = require('../helpers'); "use strict"; 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 }