164 lines
8.1 KiB
JavaScript
164 lines
8.1 KiB
JavaScript
|
"use strict";
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||
|
// See LICENSE in the project root for license information.
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.PackageMetadataManager = exports.PackageMetadata = void 0;
|
||
|
const path = __importStar(require("path"));
|
||
|
const node_core_library_1 = require("@rushstack/node-core-library");
|
||
|
const Extractor_1 = require("../api/Extractor");
|
||
|
/**
|
||
|
* Represents analyzed information for a package.json file.
|
||
|
* This object is constructed and returned by PackageMetadataManager.
|
||
|
*/
|
||
|
class PackageMetadata {
|
||
|
constructor(packageJsonPath, packageJson, aedocSupported) {
|
||
|
this.packageJsonPath = packageJsonPath;
|
||
|
this.packageJson = packageJson;
|
||
|
this.aedocSupported = aedocSupported;
|
||
|
}
|
||
|
}
|
||
|
exports.PackageMetadata = PackageMetadata;
|
||
|
/**
|
||
|
* This class maintains a cache of analyzed information obtained from package.json
|
||
|
* files. It is built on top of the PackageJsonLookup class.
|
||
|
*
|
||
|
* @remarks
|
||
|
*
|
||
|
* IMPORTANT: Don't use PackageMetadataManager to analyze source files from the current project:
|
||
|
* 1. Files such as tsdoc-metadata.json may not have been built yet, and thus may contain incorrect information.
|
||
|
* 2. The current project is not guaranteed to have a package.json file at all. For example, API Extractor can
|
||
|
* be invoked on a bare .d.ts file.
|
||
|
*
|
||
|
* Use ts.program.isSourceFileFromExternalLibrary() to test source files before passing the to PackageMetadataManager.
|
||
|
*/
|
||
|
class PackageMetadataManager {
|
||
|
constructor(packageJsonLookup, messageRouter) {
|
||
|
this._packageMetadataByPackageJsonPath = new Map();
|
||
|
this._packageJsonLookup = packageJsonLookup;
|
||
|
this._messageRouter = messageRouter;
|
||
|
}
|
||
|
// This feature is still being standardized: https://github.com/microsoft/tsdoc/issues/7
|
||
|
// In the future we will use the @microsoft/tsdoc library to read this file.
|
||
|
static _resolveTsdocMetadataPathFromPackageJson(packageFolder, packageJson) {
|
||
|
const tsdocMetadataFilename = PackageMetadataManager.tsdocMetadataFilename;
|
||
|
let tsdocMetadataRelativePath;
|
||
|
if (packageJson.tsdocMetadata) {
|
||
|
// 1. If package.json contains a field such as "tsdocMetadata": "./path1/path2/tsdoc-metadata.json",
|
||
|
// then that takes precedence. This convention will be rarely needed, since the other rules below generally
|
||
|
// produce a good result.
|
||
|
tsdocMetadataRelativePath = packageJson.tsdocMetadata;
|
||
|
}
|
||
|
else if (packageJson.typings) {
|
||
|
// 2. If package.json contains a field such as "typings": "./path1/path2/index.d.ts", then we look
|
||
|
// for the file under "./path1/path2/tsdoc-metadata.json"
|
||
|
tsdocMetadataRelativePath = path.join(path.dirname(packageJson.typings), tsdocMetadataFilename);
|
||
|
}
|
||
|
else if (packageJson.main) {
|
||
|
// 3. If package.json contains a field such as "main": "./path1/path2/index.js", then we look for
|
||
|
// the file under "./path1/path2/tsdoc-metadata.json"
|
||
|
tsdocMetadataRelativePath = path.join(path.dirname(packageJson.main), tsdocMetadataFilename);
|
||
|
}
|
||
|
else {
|
||
|
// 4. If none of the above rules apply, then by default we look for the file under "./tsdoc-metadata.json"
|
||
|
// since the default entry point is "./index.js"
|
||
|
tsdocMetadataRelativePath = tsdocMetadataFilename;
|
||
|
}
|
||
|
// Always resolve relative to the package folder.
|
||
|
const tsdocMetadataPath = path.resolve(packageFolder, tsdocMetadataRelativePath);
|
||
|
return tsdocMetadataPath;
|
||
|
}
|
||
|
/**
|
||
|
* @param tsdocMetadataPath - An explicit path that can be configured in api-extractor.json.
|
||
|
* If this parameter is not an empty string, it overrides the normal path calculation.
|
||
|
* @returns the absolute path to the TSDoc metadata file
|
||
|
*/
|
||
|
static resolveTsdocMetadataPath(packageFolder, packageJson, tsdocMetadataPath) {
|
||
|
if (tsdocMetadataPath) {
|
||
|
return path.resolve(packageFolder, tsdocMetadataPath);
|
||
|
}
|
||
|
return PackageMetadataManager._resolveTsdocMetadataPathFromPackageJson(packageFolder, packageJson);
|
||
|
}
|
||
|
/**
|
||
|
* Writes the TSDoc metadata file to the specified output file.
|
||
|
*/
|
||
|
static writeTsdocMetadataFile(tsdocMetadataPath, newlineKind) {
|
||
|
const fileObject = {
|
||
|
tsdocVersion: '0.12',
|
||
|
toolPackages: [
|
||
|
{
|
||
|
packageName: '@microsoft/api-extractor',
|
||
|
packageVersion: Extractor_1.Extractor.version
|
||
|
}
|
||
|
]
|
||
|
};
|
||
|
const fileContent = '// This file is read by tools that parse documentation comments conforming to the TSDoc standard.\n' +
|
||
|
'// It should be published with your NPM package. It should not be tracked by Git.\n' +
|
||
|
node_core_library_1.JsonFile.stringify(fileObject);
|
||
|
node_core_library_1.FileSystem.writeFile(tsdocMetadataPath, fileContent, {
|
||
|
convertLineEndings: newlineKind,
|
||
|
ensureFolderExists: true
|
||
|
});
|
||
|
}
|
||
|
/**
|
||
|
* Finds the package.json in a parent folder of the specified source file, and
|
||
|
* returns a PackageMetadata object. If no package.json was found, then undefined
|
||
|
* is returned. The results are cached.
|
||
|
*/
|
||
|
tryFetchPackageMetadata(sourceFilePath) {
|
||
|
const packageJsonFilePath = this._packageJsonLookup.tryGetPackageJsonFilePathFor(sourceFilePath);
|
||
|
if (!packageJsonFilePath) {
|
||
|
return undefined;
|
||
|
}
|
||
|
let packageMetadata = this._packageMetadataByPackageJsonPath.get(packageJsonFilePath);
|
||
|
if (!packageMetadata) {
|
||
|
const packageJson = this._packageJsonLookup.loadNodePackageJson(packageJsonFilePath);
|
||
|
const packageJsonFolder = path.dirname(packageJsonFilePath);
|
||
|
let aedocSupported = false;
|
||
|
const tsdocMetadataPath = PackageMetadataManager._resolveTsdocMetadataPathFromPackageJson(packageJsonFolder, packageJson);
|
||
|
if (node_core_library_1.FileSystem.exists(tsdocMetadataPath)) {
|
||
|
this._messageRouter.logVerbose("console-found-tsdoc-metadata" /* ConsoleMessageId.FoundTSDocMetadata */, 'Found metadata in ' + tsdocMetadataPath);
|
||
|
// If the file exists at all, assume it was written by API Extractor
|
||
|
aedocSupported = true;
|
||
|
}
|
||
|
packageMetadata = new PackageMetadata(packageJsonFilePath, packageJson, aedocSupported);
|
||
|
this._packageMetadataByPackageJsonPath.set(packageJsonFilePath, packageMetadata);
|
||
|
}
|
||
|
return packageMetadata;
|
||
|
}
|
||
|
/**
|
||
|
* Returns true if the source file is part of a package whose .d.ts files support AEDoc annotations.
|
||
|
*/
|
||
|
isAedocSupportedFor(sourceFilePath) {
|
||
|
const packageMetadata = this.tryFetchPackageMetadata(sourceFilePath);
|
||
|
if (!packageMetadata) {
|
||
|
return false;
|
||
|
}
|
||
|
return packageMetadata.aedocSupported;
|
||
|
}
|
||
|
}
|
||
|
PackageMetadataManager.tsdocMetadataFilename = 'tsdoc-metadata.json';
|
||
|
exports.PackageMetadataManager = PackageMetadataManager;
|
||
|
//# sourceMappingURL=PackageMetadataManager.js.map
|