import-conductor
Version:
Automatically organize your Typescript import statements
106 lines • 5.47 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.organizeImports = exports.organizeImportsForFile = exports.actions = void 0;
const fs_1 = require("fs");
const simple_git_1 = __importDefault(require("simple-git"));
const typescript_1 = __importDefault(require("typescript"));
const config_1 = require("../config");
const line_ending_detector_1 = require("../helpers/line-ending-detector");
const log_1 = require("../helpers/log");
const categorize_imports_1 = require("./categorize-imports");
const collect_import_nodes_1 = require("./collect-import-nodes");
const collect_non_import_nodes_1 = require("./collect-non-import-nodes");
const format_import_statements_1 = require("./format-import-statements");
const get_import_statement_map_1 = require("./get-import-statement-map");
const sort_import_categories_1 = require("./sort-import-categories");
const git = simple_git_1.default();
exports.actions = {
none: 'none',
skipped: 'skipped',
reordered: 'reordered',
};
function getFileComment(fileContent) {
const fileComment = /^(?:(\/\/.*)|(\/\*[^]*?\*\/))/.exec(fileContent);
if (fileComment) {
const [singleLine, multiLine] = fileComment;
return singleLine || multiLine;
}
return '';
}
function organizeImportsForFile(filePath) {
return __awaiter(this, void 0, void 0, function* () {
// staged files might also include deleted files, we need to verify they exist.
if (!/\.tsx?$/.test(filePath) || !fs_1.existsSync(filePath)) {
return exports.actions.none;
}
let fileContent = fs_1.readFileSync(filePath).toString();
if (/\/[/*]\s*import-conductor-skip/.test(fileContent)) {
log_1.log('gray', 'skipped (via comment)', filePath);
return exports.actions.skipped;
}
const { staged, autoAdd, dryRun } = config_1.getConfig();
const fileWithOrganizedImports = yield organizeImports(fileContent);
const fileHasChanged = fileWithOrganizedImports !== fileContent;
const isValidAction = [exports.actions.none, exports.actions.skipped].every((action) => action !== fileWithOrganizedImports);
if (fileHasChanged && isValidAction) {
!dryRun && fs_1.writeFileSync(filePath, fileWithOrganizedImports);
let msg = 'imports reordered';
if (staged && autoAdd) {
yield git.add(filePath);
msg += ', added to git';
}
log_1.log('green', msg, filePath);
return exports.actions.reordered;
}
log_1.log('gray', 'no change needed', filePath);
return exports.actions.none;
});
}
exports.organizeImportsForFile = organizeImportsForFile;
function organizeImports(fileContent) {
return __awaiter(this, void 0, void 0, function* () {
const lineEnding = line_ending_detector_1.detectLineEnding(fileContent);
if (/\/[/*]\s*import-conductor-skip/.test(fileContent)) {
log_1.log('gray', 'Format skipped (via comment)');
return exports.actions.skipped;
}
let fileComment = getFileComment(fileContent);
if (fileComment) {
fileContent = fileContent.replace(fileComment, '');
}
const rootNode = typescript_1.default.createSourceFile('temp', fileContent, typescript_1.default.ScriptTarget.Latest, true);
const importNodes = collect_import_nodes_1.collectImportNodes(rootNode);
const importStatementMap = get_import_statement_map_1.getImportStatementMap(importNodes);
if (importStatementMap.size === 0) {
return exports.actions.none;
}
const categorizedImports = categorize_imports_1.categorizeImportLiterals(importStatementMap);
const sortedAndCategorizedImports = sort_import_categories_1.sortImportCategories(categorizedImports);
let updatedContent = format_import_statements_1.formatImportStatements(sortedAndCategorizedImports, lineEnding);
const lastImport = importNodes.pop();
const contentWithoutImportStatements = fileContent.slice(lastImport.end);
const nonImportNodes = collect_non_import_nodes_1.collectNonImportNodes(rootNode, lastImport);
if (nonImportNodes) {
updatedContent += nonImportNodes.map((n) => n.getFullText()).join('');
}
updatedContent += contentWithoutImportStatements;
if (fileComment) {
updatedContent = `${fileComment}\n` + updatedContent;
}
return updatedContent;
});
}
exports.organizeImports = organizeImports;
//# sourceMappingURL=organize-imports.js.map