ntts
Version:
A CLI tool for refactoring an existing NodeJs application to a fully functional TypeScript application.
252 lines (251 loc) • 13 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var ts_morph_1 = require("ts-morph");
var fs_1 = require("fs");
var ignore_1 = __importDefault(require("ignore"));
var path_1 = require("path");
var imports_refactor_1 = __importDefault(require("./imports-refactor/imports-refactor"));
var class_refactor_1 = __importDefault(require("./class-refactor/class-refactor"));
var exports_refactor_1 = __importDefault(require("./exports-refactor/exports-refactor"));
var logger_1 = __importDefault(require("../logger/logger"));
var tsconfig_handler_1 = __importDefault(require("../tsconfig-handler/tsconfig-handler"));
var types_refactor_1 = __importDefault(require("./types-refactor/types-refactor"));
var generate_progress_bar_1 = require("./helpers/generate-progress-bar/generate-progress-bar");
var interface_creator_1 = require("./types-refactor/interface-handler/interface-creator/interface-creator");
var CodeRefactor = /** @class */ (function () {
function CodeRefactor() {
}
var _a;
_a = CodeRefactor;
CodeRefactor.convertToTypescript = function (project, target, unknown) {
_a.refactorExports(project);
_a.refactorImports(project);
_a.refactorClasses(project);
_a.addTypeAlias(project, target, unknown);
_a.generateInterfaces(project, target);
_a.inferParameterTypes(project, target);
_a.inferFunctionTypeParameterTypes(project, target);
_a.inferParameterTypes(project, target);
_a.inferFunctionTypeParameterTypes(project, target);
_a.setFunctionReturnTypes(project, target);
_a.inferWriteAccessType(project, target);
_a.inferContextualType(project, target);
_a.inferInterfaceProperties(project, target);
_a.replaceTypes(project, target);
_a.mergeInterfaces(project, target);
_a.filterUnionType(project);
_a.mergeInterfaces(project, target);
_a.removeUnnecessaryTypeNodes(project);
_a.refactorImportTypesAndGlobalVariables(project);
_a.simplifyOptionalNodes(project, target);
_a.simplifyTypeNodes(project, target);
};
CodeRefactor.addSourceFiles = function (ignores, path) {
logger_1.default.info('Loading project files');
var project = new ts_morph_1.Project({
tsConfigFilePath: tsconfig_handler_1.default.tsconfigFileName(),
skipAddingFilesFromTsConfig: true,
});
var ig = (0, ignore_1.default)().add(ignores);
_a.readDirectory(project, path || '.', ig);
return project;
};
CodeRefactor.readDirectory = function (project, path, ig) {
(0, fs_1.readdirSync)(path, { withFileTypes: true })
.forEach(function (item) { return _a.checkDirectoryEntry(project, item, path, ig); });
return project;
};
CodeRefactor.checkDirectoryEntry = function (project, item, path, ig) {
var fullPath = (0, path_1.join)(path, item.name);
var ignores = ig.ignores(fullPath);
if (!ignores && item.isFile() && fullPath.endsWith('.ts')) {
project.addSourceFileAtPath(fullPath);
}
if (!ignores && item.isDirectory()) {
_a.readDirectory(project, fullPath, ig);
}
return project;
};
CodeRefactor.refactorExports = function (project) {
logger_1.default.info('Refactoring exports');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
exports_refactor_1.default.moduleExportsToExport(s);
bar.tick();
});
logger_1.default.success('Exports refactored');
};
CodeRefactor.refactorImports = function (project) {
logger_1.default.info('Refactoring requires to imports');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
var modulesResult = sourceFiles.reduce(function (moduleSpecifierResult, s) {
imports_refactor_1.default.requiresToImports(s);
imports_refactor_1.default.refactorImportClauses(s);
var result = imports_refactor_1.default.reformatImports(s, moduleSpecifierResult);
bar.tick();
return result;
}, { fileEndings: [] });
imports_refactor_1.default.resolveModuleSpecifierResults(modulesResult);
logger_1.default.success('Requires refactored');
};
CodeRefactor.refactorClasses = function (project) {
logger_1.default.info('Refactoring classes');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
class_refactor_1.default.toTypeScriptClasses(s);
bar.tick();
});
logger_1.default.success('Classes refactored');
};
CodeRefactor.generateInterfaces = function (project, target) {
logger_1.default.info('Generating interfaces from object literal types');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.createInterfacesFromObjectTypes(s, project, target);
bar.tick();
});
logger_1.default.success('Generated interfaces from object literal types where possible');
};
CodeRefactor.inferParameterTypes = function (project, target) {
logger_1.default.info('Declaring parameter types by usage');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.inferParameterTypes(s, project, target);
bar.tick();
});
logger_1.default.success('Parameter type declared where possible');
};
CodeRefactor.inferFunctionTypeParameterTypes = function (project, target) {
logger_1.default.info('Declaring parameter types of function types by usage');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.inferFunctionTypeParameterTypes(s, project, target);
bar.tick();
});
logger_1.default.success('Parameter type declared where possible');
};
CodeRefactor.inferWriteAccessType = function (project, target) {
logger_1.default.info('Declaring variable and property types by write access');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.inferWriteAccessType(s, project, target);
bar.tick();
});
logger_1.default.success('Variable and Property type declared where possible');
};
CodeRefactor.inferInterfaceProperties = function (project, target) {
logger_1.default.info('Checking usage of generated interfaces for additional properties and types');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.inferInterfaceProperties(s, project, target);
bar.tick();
});
logger_1.default.success('Defined type and added properties to interfaces where possible');
};
CodeRefactor.inferContextualType = function (project, target) {
logger_1.default.info('Inferring type of untyped declarations by contextual type');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.inferContextualType(s, project, target);
bar.tick();
});
logger_1.default.success('Inferred type where possible');
};
CodeRefactor.replaceTypes = function (project, target) {
logger_1.default.info('Replacing undesirable types');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
var typeAlias = (0, interface_creator_1.getTypeAliasType)(project, target);
sourceFiles.forEach(function (s) {
types_refactor_1.default.replaceInvalidTypes(s, typeAlias);
bar.tick();
});
logger_1.default.success('Replaced undesirable types');
};
CodeRefactor.mergeInterfaces = function (project, target) {
logger_1.default.info('Merging duplicate interfaces');
types_refactor_1.default.mergeDuplicateInterfaces(project, target);
logger_1.default.success('Merged duplicate interfaces where possible');
};
CodeRefactor.refactorImportTypesAndGlobalVariables = function (project) {
logger_1.default.info('Refactoring import types to simple type references and importing global variables');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.refactorImportTypesAndTypeReferences(s);
bar.tick();
});
logger_1.default.success('Refactored import types to simple type references and imported global variables where possible');
};
CodeRefactor.filterUnionType = function (project) {
logger_1.default.info('Filtering out duplicate types in union types');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.filterUnionType(s);
bar.tick();
});
logger_1.default.success('Filtered union types');
};
CodeRefactor.simplifyOptionalNodes = function (project, target) {
logger_1.default.info('Removing undefined type from optional node');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
var typeAlias = (0, interface_creator_1.getTypeAliasType)(project, target);
sourceFiles.forEach(function (s) {
types_refactor_1.default.removeUndefinedFromOptional(s, typeAlias);
bar.tick();
});
logger_1.default.success('Removed undefined types');
};
CodeRefactor.simplifyTypeNodes = function (project, target) {
logger_1.default.info('Removing null or undefined types');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
var typeAlias = (0, interface_creator_1.getTypeAliasType)(project, target);
sourceFiles.forEach(function (s) {
types_refactor_1.default.removeNullOrUndefinedTypes(s, typeAlias);
bar.tick();
});
logger_1.default.success('Removed null or undefined types');
};
CodeRefactor.addTypeAlias = function (project, target, unknown) {
logger_1.default.info("Adding type alias of type ".concat(unknown ? 'unknown' : 'any'));
(0, interface_creator_1.addTypeAlias)(project, target, unknown);
logger_1.default.success('Added type alias');
};
CodeRefactor.setFunctionReturnTypes = function (project, target) {
logger_1.default.info('Replacing object types of function returns with interfaces');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.setFunctionReturnTypes(s, project, target);
bar.tick();
});
logger_1.default.success('Replaced object types of function returns with interfaces');
};
CodeRefactor.removeUnnecessaryTypeNodes = function (project) {
logger_1.default.info('Removing unnecessary type nodes');
var sourceFiles = project.getSourceFiles();
var bar = (0, generate_progress_bar_1.generateProgressBar)(sourceFiles.length);
sourceFiles.forEach(function (s) {
types_refactor_1.default.removeUnnecessaryTypeNodes(s);
bar.tick();
});
logger_1.default.success('Removed unnecessary type nodes');
};
return CodeRefactor;
}());
exports.default = CodeRefactor;