eslint-plugin-import-sorting
Version:
ESLint plugin to group and sort imports by module, à la Python isort
162 lines (161 loc) • 6.08 kB
JavaScript
"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const utils = require("@typescript-eslint/utils");
const computeGroup = require("../utils/compute-group.cjs");
const getEslintDisabledLines = require("../utils/get-eslint-disabled-lines.cjs");
const getGroupNumber = require("../utils/get-group-number.cjs");
const getNewlineErrors = require("../utils/get-newline-errors.cjs");
const isNodeEslintDisabled = require("../utils/is-node-eslint-disabled.cjs");
const makeFixes = require("../utils/make-fixes.cjs");
const makeNewlineFixes = require("../utils/make-newline-fixes.cjs");
const pairwise = require("../utils/pairwise.cjs");
const rangeToDiff = require("../utils/range-to-diff.cjs");
const sortNodesByGroups = require("../utils/sort-nodes-by-groups.cjs");
const IMPORT_GROUPS = [
"unassigned",
"builtin",
"framework",
"external",
"internal",
"local",
"style",
"object",
"unknown"
];
const createRule = utils.ESLintUtils.RuleCreator(
(name) => `https://github.com/stormwarning/eslint-plugin-import-sorting/blob/main/docs/rules/${name}.md`
);
const order = createRule({
name: "order",
meta: {
type: "suggestion",
fixable: "code",
docs: {
description: "Consistently order `import` statements."
},
messages: {
"needs-newline": "There should be at least one empty line between {{left}} and {{right}}",
"extra-newline": "There should be no empty line between {{left}} and {{right}}",
"out-of-order": "{{right}} should occur before {{left}}"
},
schema: []
},
defaultOptions: [],
create(context) {
let { settings, sourceCode } = context;
let options = {
ignoreCase: false,
newlinesBetween: "always",
order: "asc",
type: "natural"
};
let eslintDisabledLines = getEslintDisabledLines.getEslintDisabledLines({
ruleName: context.id,
sourceCode
});
let nodes = [];
function registerNode(node) {
let name;
if (node.type === utils.AST_NODE_TYPES.ImportDeclaration) {
name = node.source.value;
} else if (node.type === utils.AST_NODE_TYPES.TSImportEqualsDeclaration) {
name = node.moduleReference.type === utils.AST_NODE_TYPES.TSExternalModuleReference ? node.moduleReference.expression.value : sourceCode.getText(node.moduleReference);
} else {
let decl = node.declarations[0].init;
let { value } = decl.arguments[0];
name = value.toString();
}
nodes.push({
group: computeGroup.computeGroup(node, settings, sourceCode),
isEslintDisabled: isNodeEslintDisabled.isNodeEslintDisabled(node, eslintDisabledLines),
name,
node,
shouldAddSafetySemicolonWhenInline: true,
size: rangeToDiff.rangeToDiff(node, sourceCode)
});
}
return {
TSImportEqualsDeclaration: registerNode,
ImportDeclaration: registerNode,
VariableDeclaration(node) {
var _a;
if (node.declarations[0].init && node.declarations[0].init.type === utils.AST_NODE_TYPES.CallExpression && node.declarations[0].init.callee.type === utils.AST_NODE_TYPES.Identifier && node.declarations[0].init.callee.name === "require" && ((_a = node.declarations[0].init.arguments[0]) == null ? void 0 : _a.type) === utils.AST_NODE_TYPES.Literal) {
registerNode(node);
}
},
// eslint-disable-next-line @typescript-eslint/naming-convention
"Program:exit"() {
var _a;
function hasContentBetweenNodes(left, right) {
return sourceCode.getTokensBetween(left.node, right.node, {
includeComments: false
}).length > 0;
}
let formattedNodes = [[]];
for (let node of nodes) {
let lastNode = (_a = formattedNodes.at(-1)) == null ? void 0 : _a.at(-1);
if (lastNode && hasContentBetweenNodes(lastNode, node)) {
formattedNodes.push([node]);
} else {
formattedNodes.at(-1).push(node);
}
}
for (let nodeList of formattedNodes) {
let sortedNodes = sortNodesByGroups.sortNodesByGroups(nodeList, options, {});
pairwise.pairwise(nodeList, (left, right) => {
let leftNumber = getGroupNumber.getGroupNumber(IMPORT_GROUPS, left);
let rightNumber = getGroupNumber.getGroupNumber(IMPORT_GROUPS, right);
let indexOfLeft = sortedNodes.indexOf(left);
let indexOfRight = sortedNodes.indexOf(right);
let messages = [];
if (indexOfLeft > indexOfRight) {
messages.push(leftNumber === rightNumber ? "out-of-order" : "out-of-order");
}
messages = [
...messages,
...getNewlineErrors.getNewlineErrors({
missingLineError: "needs-newline",
extraLineError: "extra-newline",
left,
leftNumber,
right,
rightNumber,
sourceCode,
options
})
];
for (let message of messages) {
context.report({
fix: (fixer) => [
...makeFixes.makeFixes({
fixer,
nodes: nodeList,
sortedNodes,
sourceCode
}),
...makeNewlineFixes.makeNewlineFixes({
fixer,
nodes: nodeList,
sortedNodes,
sourceCode,
options
})
],
data: {
rightGroup: right.group,
leftGroup: left.group,
right: right.name,
left: left.name
},
node: right.node,
messageId: message
});
}
});
}
}
};
}
});
exports.IMPORT_GROUPS = IMPORT_GROUPS;
exports.default = order;