sortier
Version:
An opinionated code sorter
109 lines (108 loc) • 4.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.sortImportDeclarations = sortImportDeclarations;
const sort_utils_js_1 = require("../../utilities/sort-utils.js");
function sortImportDeclarations(program, comments, fileContents, options) {
const ensuredOptions = ensureOptions(options);
// Get all the import/export nodes
const importExportNodes = program.body.filter((node) => {
return node.type.match(/Export.*Declaration/) || node.type.match(/Import.*Declaration/);
});
// Polyfills shouldn't be sorted - Assuming all imports without specifiers are polyfills
const polyfillIndexesOrUndefined = importExportNodes.map((value) => {
if (value.type === "ImportDeclaration" && value.specifiers.length === 0) {
return value.range;
}
return undefined;
});
const polyfillIndexes = polyfillIndexesOrUndefined
.flat()
.filter((value) => value != undefined);
const contextGroups = (0, sort_utils_js_1.getContextGroups)(importExportNodes, comments, fileContents, polyfillIndexes);
let newFileContents = fileContents.slice();
for (const contextGroup of contextGroups) {
const { comments: unsortedComments, nodes: unsortedNodes } = contextGroup;
const sortedNodes = unsortedNodes.slice().sort((a, b) => {
return sortModuleDeclarations(a, b, ensuredOptions);
});
newFileContents = (0, sort_utils_js_1.reorderValues)(newFileContents, unsortedComments, unsortedNodes, sortedNodes);
}
return newFileContents;
}
function sortModuleDeclarations(a, b, ensuredOptions) {
// If they both aren't import or both aren't export then order based off import/export
if (a.type.substring(0, 4) !== b.type.substring(0, 4)) {
return a.type.indexOf("Export") !== -1 ? 1 : -1;
}
if (ensuredOptions.orderBy === "first-specifier") {
return sortBySpecifier(a, b) || sortByPath(a, b);
}
return sortByPath(a, b) || sortBySpecifier(a, b);
}
function ensureOptions(options) {
return {
orderBy: "source",
...options,
};
}
function sortBySpecifier(a, b) {
const firstSpecifier_A = getFirstSpecifier(a);
const firstSpecifier_B = getFirstSpecifier(b);
return (0, sort_utils_js_1.compare)(firstSpecifier_A, firstSpecifier_B);
}
function getFirstSpecifier(declaration) {
switch (declaration.type) {
case "ExportAllDeclaration":
return "";
case "ExportDefaultDeclaration":
return "";
case "ExportNamedDeclaration":
case "ImportDeclaration": {
const local = declaration.specifiers[0]?.local;
switch (local?.type) {
case "Identifier":
return local.name || "";
case "Literal":
return local.value?.toString() || "";
default:
return "";
}
}
}
}
function sortByPath(a, b) {
const source_A = getSource(a);
const source_B = getSource(b);
if (source_A == null) {
if (source_B == null) {
return 0;
}
else {
return 1;
}
}
if (source_B == null) {
return 1;
}
const aIsRelative = source_A.startsWith(".");
const bIsRelative = source_B.startsWith(".");
if (aIsRelative === bIsRelative) {
const comparisonResult = (0, sort_utils_js_1.compare)(source_A, source_B);
return comparisonResult;
}
else {
return Number(aIsRelative) - Number(bIsRelative);
}
}
function getSource(declaration) {
switch (declaration.type) {
case "ExportAllDeclaration":
return declaration.source.value?.toString();
case "ExportDefaultDeclaration":
return "";
case "ExportNamedDeclaration":
return declaration.source?.value?.toString();
case "ImportDeclaration":
return declaration.source.value?.toString();
}
}