UNPKG

@microsoft/api-extractor

Version:

Validate, document, and review the exported API for a TypeScript library

111 lines 5.43 kB
"use strict"; // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. Object.defineProperty(exports, "__esModule", { value: true }); const path = require("path"); const node_core_library_1 = require("@microsoft/node-core-library"); const AstPackage_1 = require("./ast/AstPackage"); const DocItemLoader_1 = require("./DocItemLoader"); const TypeScriptMessageFormatter_1 = require("./utils/TypeScriptMessageFormatter"); /** * The main entry point for the "api-extractor" utility. The Analyzer object invokes the * TypeScript Compiler API to analyze a project, and constructs the AstItem * abstract syntax tree. */ class ExtractorContext { constructor(options) { this.packageJsonLookup = new node_core_library_1.PackageJsonLookup(); this.policies = options.policies; this.validationRules = options.validationRules; const folder = this.packageJsonLookup.tryGetPackageFolderFor(options.entryPointFile); if (!folder) { throw new Error('Unable to find a package.json for entry point: ' + options.entryPointFile); } this._packageFolder = folder; this.packageJson = this.packageJsonLookup.tryLoadPackageJsonFor(this._packageFolder); this.parsedPackageName = node_core_library_1.PackageName.parse(this.packageJson.name); this.docItemLoader = new DocItemLoader_1.DocItemLoader(this._packageFolder); this._logger = options.logger; // This runs a full type analysis, and then augments the Abstract Syntax Tree (i.e. declarations) // with semantic information (i.e. symbols). The "diagnostics" are a subset of the everyday // compile errors that would result from a full compilation. for (const diagnostic of options.program.getSemanticDiagnostics()) { const errorText = TypeScriptMessageFormatter_1.TypeScriptMessageFormatter.format(diagnostic.messageText); this.reportError(`TypeScript: ${errorText}`, diagnostic.file, diagnostic.start); } this.typeChecker = options.program.getTypeChecker(); const rootFile = options.program.getSourceFile(options.entryPointFile); if (!rootFile) { throw new Error('Unable to load file: ' + options.entryPointFile); } this.package = new AstPackage_1.AstPackage(this, rootFile); // construct members this.package.completeInitialization(); // creates ApiDocumentation this.package.visitTypeReferencesForAstItem(); } /** * Returns the full name of the package being analyzed. */ get packageName() { return this.packageJson.name; } /** * Returns the folder for the package being analyzed. */ get packageFolder() { return this._packageFolder; } /** * Reports an error message to the registered ApiErrorHandler. */ reportError(message, sourceFile, start) { if (sourceFile && start) { const lineAndCharacter = sourceFile.getLineAndCharacterOfPosition(start); let filename2 = sourceFile.fileName .replace(/\/lib\//g, '/src/') .replace(/\.d\.ts$/g, '.ts'); if (!node_core_library_1.FileSystem.exists(filename2)) { filename2 = sourceFile.fileName .replace(/\/lib\//g, '/src/') .replace(/\.d\.ts$/g, '.tsx'); if (!node_core_library_1.FileSystem.exists(filename2)) { filename2 = sourceFile.fileName; } } // If the file is under the packageFolder, then show a relative path const relativePath = path.relative(this.packageFolder, filename2); const shownPath = relativePath.substr(0, 2) === '..' ? filename2 : relativePath; // Format the error so that VS Code can follow it. For example: // "src\MyClass.ts(15,1): The JSDoc tag "@blah" is not supported by AEDoc" this._logger.logError(`${shownPath}(${lineAndCharacter.line + 1},${lineAndCharacter.character + 1}): ` + message); } else { this._logger.logError(message); } } /** * Scans for external package api files and loads them into the docItemLoader member before * any API analysis begins. * * @param externalJsonCollectionPath - an absolute path to to the folder that contains all the external * api json files. * Ex: if externalJsonPath is './resources', then in that folder * are 'es6-collections.api.json', etc. */ loadExternalPackages(externalJsonCollectionPath) { if (!externalJsonCollectionPath) { return; } node_core_library_1.FileSystem.readFolder(externalJsonCollectionPath, { absolutePaths: true }).forEach(file => { if (path.extname(file) === '.json') { // Example: "C:\Example\my-package.json" --> "my-package" const packageName = path.parse(file).name; this.docItemLoader.loadPackageIntoCache(file, packageName); } }); } } exports.ExtractorContext = ExtractorContext; //# sourceMappingURL=ExtractorContext.js.map