UNPKG

@lesnoypudge/eslint-plugin-import-export

Version:

lesnoypudge's eslint-plugin-import-export

214 lines (213 loc) 6.14 kB
import { never, invariant } from "@lesnoypudge/utils"; import { messageIds } from "./extra.js"; import * as t from "@babel/types"; import { generate } from "@babel/generator"; import { AST_NODE_TYPES } from "@typescript-eslint/utils"; const tt = AST_NODE_TYPES; const padded = (text) => { return " ".repeat(4) + text; }; const getImportAst = (node) => { const ast = t.importDeclaration( node.specifiers.map((clause) => { switch (clause.type) { case tt.ImportSpecifier: { const original = clause.imported.type === tt.Identifier ? clause.imported.name : clause.imported.value; return t.importSpecifier( t.identifier(original), t.identifier(clause.local.name) ); } case tt.ImportDefaultSpecifier: { return t.importDefaultSpecifier( t.identifier(clause.local.name) ); } default: { never("unhandled import specifier"); } } }), t.stringLiteral(node.source.value) ); return ast; }; const getExportAst = (node) => { var _a; invariant((_a = node.source) == null ? void 0 : _a.value); const ast = t.exportNamedDeclaration( null, node.specifiers.map((clause) => { const local = clause.local.type === tt.Literal ? clause.local.value : clause.local.name; const exported = clause.exported.type === tt.Literal ? clause.exported.value : clause.exported.name; return t.exportSpecifier( t.identifier(local), t.identifier(exported) ); }), t.stringLiteral(node.source.value) ); return ast; }; const getOneLinerImport = (node) => { return generate(getImportAst(node)).code.replaceAll('"', "'"); }; const getOneLinerExport = (node) => { return generate(getExportAst(node)).code.replaceAll('"', "'"); }; const getMultilineImport = (node) => { const ast = getImportAst(node); const first = ast.specifiers[0]; invariant(first); const withDefault = t.isImportDefaultSpecifier(first); const defaultName = withDefault ? first.local.name + ", " : ""; const rest = withDefault ? ast.specifiers.slice(1) : ast.specifiers; return [ `import ${defaultName}{`, ...rest.map((clause) => { invariant(t.isImportSpecifier(clause)); const imported = t.isStringLiteral(clause.imported) ? clause.imported.value : clause.imported.name; const local = clause.local.name; if (imported !== local) { return padded(`${local} as ${imported},`); } return `${padded(imported)},`; }), `} from '${ast.source.value}';` ].join("\n"); }; const getMultilineExport = (node) => { const ast = getExportAst(node); const source = ast.source ? ` from '${ast.source.value}'` : ""; return [ `export {`, ...ast.specifiers.map((clause) => { invariant(t.isExportSpecifier(clause)); const exported = t.isStringLiteral(clause.exported) ? clause.exported.value : clause.exported.name; const local = clause.local.name; if (exported !== local) { return padded(`${local} as ${exported},`); } return `${padded(exported)},`; }), `}${source};` ].join("\n"); }; const ruleVisitors = (context) => { const getIsMultiline = (node) => { return context.sourceCode.getText(node).split("\n").length > 1; }; const getIsExceeds = (length) => { return length > 80; }; const getConditions = ({ isExceeds, node }) => { const isMultiline = getIsMultiline(node); const isOneLiner = !isMultiline; const shouldTransformToOneLiner = isMultiline && !isExceeds; const shouldTransformToMultiline = isOneLiner && isExceeds; const shouldBail = !shouldTransformToMultiline && !shouldTransformToOneLiner; return { shouldTransformToMultiline, shouldTransformToOneLiner, shouldBail }; }; const handleImportDeclaration = (node) => { const withSpecifiers = node.specifiers.some((clause) => { return clause.type === tt.ImportSpecifier; }); if (!withSpecifiers) return; const isExceeds = getIsExceeds( getOneLinerImport(node).length ); const { shouldBail, shouldTransformToMultiline, shouldTransformToOneLiner } = getConditions({ isExceeds, node }); if (shouldBail) return; if (shouldTransformToMultiline) { return context.report({ messageId: messageIds.longOneLiner, node, fix: (fixer) => { return fixer.replaceText( node, getMultilineImport(node) ); } }); } if (shouldTransformToOneLiner) { return context.report({ messageId: messageIds.shortMultiline, node, fix: (fixer) => { return fixer.replaceText( node, getOneLinerImport(node) ); } }); } never(); }; const handleExportNamedDeclaration = (node) => { if (node.declaration !== null) return; const isExceeds = getIsExceeds( getOneLinerExport(node).length ); const { shouldBail, shouldTransformToMultiline, shouldTransformToOneLiner } = getConditions({ isExceeds, node }); if (shouldBail) return; if (shouldTransformToMultiline) { return context.report({ messageId: messageIds.longOneLiner, node, fix: (fixer) => { return fixer.replaceText( node, getMultilineExport(node) ); } }); } if (shouldTransformToOneLiner) { return context.report({ messageId: messageIds.shortMultiline, node, fix: (fixer) => { return fixer.replaceText( node, getOneLinerExport(node) ); } }); } never(); }; return { [tt.ImportDeclaration]: (node) => { try { handleImportDeclaration(node); } catch { } }, [tt.ExportNamedDeclaration]: (node) => { try { handleExportNamedDeclaration(node); } catch { } } }; }; export { ruleVisitors }; //# sourceMappingURL=ruleVisitors.js.map