UNPKG

ntts

Version:

A CLI tool for refactoring an existing NodeJs application to a fully functional TypeScript application.

252 lines (251 loc) 13 kB
"use strict"; 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;