UNPKG

eslint-plugin-ferramentas

Version:
123 lines (122 loc) 4.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.rule = exports.ruleName = void 0; const path_1 = require("path"); const Utils_1 = require("../Utils"); exports.ruleName = 'relative-import-order'; const extractOptions = (directory, [firstOption]) => { const { directories, ignore = [], isRelative = Utils_1.RELATIVE_IMPORT_PATTERN, debug = false, } = firstOption; return { ignore: ignore.map((relativePath) => (0, path_1.resolve)(directory, relativePath)), directories: directories.map((relativePath) => (0, path_1.resolve)(directory, relativePath)), isRelative: new RegExp(isRelative), debug, }; }; /** * @returns the position an import should have *if* it is not ignored * - number for the actual position * - true if it was ignored * - false if no match is founf */ const resolvePositionFromConfig = ({ directories, ignore }, importPath) => { const indexPos = directories.findIndex((directory) => importPath.startsWith(directory)); if (indexPos >= 0) { /** * Position from config found */ return indexPos; } if (ignore.some((directory) => importPath.startsWith(directory))) { /** * Import is ignored */ return true; } return false; }; const reportOutOfOrder = (context, node, lastNode) => context.report({ node, message: `Imports from '${(0, Utils_1.extractImportPath)(node)}' should be above the import from '${(0, Utils_1.extractImportPath)(lastNode)}'`, /** Swap imports */ fix: (fixer) => [ fixer.replaceText(node, context.getSourceCode().getText(lastNode)), fixer.replaceText(lastNode, context.getSourceCode().getText(node)), ], }); const reportNonListed = (context, node) => context.report({ node, message: [ `The path '${(0, Utils_1.extractImportPath)(node)}' is not listed on the ESLINT rule '${exports.ruleName}'.`, `If '${exports.ruleName}' is enabled then all imported paths need to be included,`, 'if you do not wish to order this import, add it to the ignored list', ].join('\n'), }); exports.rule = { meta: { type: 'layout', fixable: 'code', hasSuggestions: true, docs: { description: 'enforces a ordering of relative imports, so they follow a consistent structure across all files' }, schema: { type: 'array', items: { type: 'object', properties: { directories: { type: 'array', items: { type: 'string' } }, ignore: { type: 'array', items: { type: 'string' } }, isRelative: { type: 'string' }, debug: { type: 'boolean' }, }, required: ['directories'], additionalProperties: false, }, minItems: 1, maxItems: 1, }, }, create: (context) => { const workingDirectory = context.getCwd(); const currentDirectory = (0, path_1.dirname)(context.getFilename()); const options = extractOptions(workingDirectory, context.options); const debug = (0, Utils_1.createDebugger)(options.debug); debug('workingDirectory', workingDirectory); debug('currentDirectory', currentDirectory); debug('options', options); let lastAux = null; return { ImportDeclaration: (node) => { const importPath = (0, Utils_1.extractImportPath)(node); debug('importPath', importPath); const isRelative = options.isRelative.test(importPath); debug('isRelative', isRelative); if (!isRelative) { /** * If its a module, just give up */ return; } const position = resolvePositionFromConfig(options, (0, path_1.resolve)(currentDirectory, importPath)); debug('position', position); debug('lastAux.position', lastAux === null || lastAux === void 0 ? void 0 : lastAux.position); if (position === true) { /** * Import is in the ignored list */ return; } if (position === false) { reportNonListed(context, node); return; } if (lastAux !== null && lastAux.position !== null && lastAux.position > position) { /** * If their position is swapped, then report */ reportOutOfOrder(context, node, lastAux.node); } lastAux = { position, node }; }, }; }, };