UNPKG

dts-bundle-generator

Version:
114 lines (113 loc) 5.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ts = require("typescript"); var compile_dts_1 = require("./compile-dts"); var types_usage_evaluator_1 = require("./types-usage-evaluator"); var logger_1 = require("./logger"); var skippedNodes = [ ts.SyntaxKind.ExportDeclaration, ts.SyntaxKind.ExportAssignment, ts.SyntaxKind.ImportDeclaration, ts.SyntaxKind.ImportEqualsDeclaration, ]; function generateDtsBundle(filePath, options) { if (options === void 0) { options = {}; } if (!ts.sys.fileExists(filePath)) { throw new Error("File \"" + filePath + "\" does not exist"); } var program = compile_dts_1.compileDts(filePath); var typeChecker = program.getTypeChecker(); // we do not need any types from node_modules dir var sourceFiles = program.getSourceFiles().filter(function (file) { return file.fileName.indexOf('node_modules') === -1; }); var typesUsageEvaluator = new types_usage_evaluator_1.TypesUsageEvaluator(sourceFiles, typeChecker); var rootSourceFileSymbol = typeChecker.getSymbolAtLocation(getRootSourceFile(program)); var rootFileExports = typeChecker.getExportsOfModule(rootSourceFileSymbol).map(function (symbol) { if (symbol.flags & ts.SymbolFlags.Alias) { // so we need to have original symbols from source file symbol = typeChecker.getAliasedSymbol(symbol); } return symbol; }); var resultOutput = ''; for (var _i = 0, sourceFiles_1 = sourceFiles; _i < sourceFiles_1.length; _i++) { var sourceFile = sourceFiles_1[_i]; logger_1.verboseLog("\n\n======= Preparing file: " + sourceFile.fileName + " ======="); var fileOutput = ''; for (var _a = 0, _b = sourceFile.statements; _a < _b.length; _a++) { var node = _b[_a]; // we should skip import and exports statements if (skippedNodes.indexOf(node.kind) !== -1) { continue; } var isNodeUsed = false; if (types_usage_evaluator_1.isNodeDeclaration(node)) { isNodeUsed = rootFileExports.some(typesUsageEvaluator.isTypeUsedBySymbol.bind(typesUsageEvaluator, node)); } else if (node.kind === ts.SyntaxKind.VariableStatement) { var declarations = node.declarationList.declarations; isNodeUsed = declarations.some(isDeclarationExported.bind(null, rootFileExports, typeChecker)); } if (!isNodeUsed) { logger_1.verboseLog("Skip file member: " + node.getText().replace(/(\n|\r)/g, '').slice(0, 50) + "..."); continue; } var nodeText = node.getText(); var hasNodeExportKeyword = hasNodeModifier(node, ts.SyntaxKind.ExportKeyword); if (node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.EnumDeclaration) { if (options.failOnClass === true && node.kind === ts.SyntaxKind.ClassDeclaration) { var classDecl = node; var className = classDecl.name ? classDecl.name.text : ''; var errorMessage = "Class was found in generated dts.\n " + className + " from " + sourceFile.fileName; throw new Error(errorMessage); } // not all classes and enums can be exported - only exported from root file var shouldNodeHasExportKeyword = isDeclarationExported(rootFileExports, typeChecker, node); if (node.kind === ts.SyntaxKind.EnumDeclaration) { // but const enum always can be exported shouldNodeHasExportKeyword = shouldNodeHasExportKeyword || hasNodeModifier(node, ts.SyntaxKind.ConstKeyword); } nodeText = getTextAccordingExport(nodeText, hasNodeExportKeyword, shouldNodeHasExportKeyword); } else { nodeText = getTextAccordingExport(nodeText, hasNodeExportKeyword, true); } fileOutput += nodeText + "\n"; } if (fileOutput.length === 0) { logger_1.normalLog("No output for file: " + sourceFile.fileName); } if (options.outputFilenames) { fileOutput = "// File: " + sourceFile.fileName + "\n\n" + fileOutput + "\n"; } resultOutput += fileOutput; } return resultOutput; } exports.generateDtsBundle = generateDtsBundle; function getRootSourceFile(program) { var rootFiles = program.getRootFileNames(); if (rootFiles.length !== 1) { logger_1.verboseLog("Root files:\n " + rootFiles.join('\n ')); throw new Error("There is not one root file - " + rootFiles.length); } return program.getSourceFile(rootFiles[0]); } function isDeclarationExported(exportedSymbols, typeChecker, declaration) { if (!declaration.name) { return false; } var declarationSymbol = typeChecker.getSymbolAtLocation(declaration.name); return exportedSymbols.some(function (rootExport) { return rootExport === declarationSymbol; }); } function getTextAccordingExport(nodeText, isNodeExported, shouldNodeBeExported) { if (shouldNodeBeExported && !isNodeExported) { return 'export ' + nodeText; } else if (isNodeExported && !shouldNodeBeExported) { return nodeText.slice('export '.length); } return nodeText; } function hasNodeModifier(node, modifier) { return Boolean(node.modifiers && node.modifiers.some(function (nodeModifier) { return nodeModifier.kind === modifier; })); }