UNPKG

voluptasmollitia

Version:
181 lines (158 loc) 6.36 kB
/** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. import * as path from 'path'; import * as tsdoc from '@microsoft/tsdoc'; import colors from 'colors'; import { CommandLineAction, CommandLineFlagParameter, CommandLineStringParameter } from '@rushstack/ts-command-line'; import { FileSystem } from '@rushstack/node-core-library'; import { ApiModel, ApiItem, ApiItemContainerMixin, ApiDocumentedItem, IResolveDeclarationReferenceResult } from 'api-extractor-model-me'; export interface IBuildApiModelResult { apiModel: ApiModel; inputFolder: string; outputFolder: string; addFileNameSuffix: boolean; } export abstract class BaseAction extends CommandLineAction { private _inputFolderParameter!: CommandLineStringParameter; private _outputFolderParameter!: CommandLineStringParameter; private _fileNameSuffixParameter!: CommandLineFlagParameter; protected onDefineParameters(): void { // override this._inputFolderParameter = this.defineStringParameter({ parameterLongName: '--input-folder', parameterShortName: '-i', argumentName: 'FOLDER1', description: `Specifies the input folder containing the *.api.json files to be processed.` + ` If omitted, the default is "./input"` }); this._outputFolderParameter = this.defineStringParameter({ parameterLongName: '--output-folder', parameterShortName: '-o', argumentName: 'FOLDER2', description: `Specifies the output folder where the documentation will be written.` + ` ANY EXISTING CONTENTS WILL BE DELETED!` + ` If omitted, the default is "./${this.actionName}"` }); this._fileNameSuffixParameter = this.defineFlagParameter({ parameterLongName: '--name-suffix', parameterShortName: '-s', description: `Add suffix to interface and class names in the file path.` + `For example, packageA.myinterface_i.md for MyInterface interface, ` + `Add packageA.myclass_c.md for MyClass class.` + `This is to avoid name conflict in case packageA also has, for example, an entry point with the same name in lowercase.` + `This option is specifically designed for the Admin SDK where such case occurs.` }); } protected buildApiModel(): IBuildApiModelResult { const apiModel: ApiModel = new ApiModel(); const inputFolder: string = this._inputFolderParameter.value || './input'; if (!FileSystem.exists(inputFolder)) { throw new Error('The input folder does not exist: ' + inputFolder); } const outputFolder: string = this._outputFolderParameter.value || `./${this.actionName}`; FileSystem.ensureFolder(outputFolder); const addFileNameSuffix: boolean = this._fileNameSuffixParameter.value; for (const filename of FileSystem.readFolder(inputFolder)) { if (filename.match(/\.api\.json$/i)) { console.log(`Reading ${filename}`); const filenamePath: string = path.join(inputFolder, filename); apiModel.loadPackage(filenamePath); } } this._applyInheritDoc(apiModel, apiModel); return { apiModel, inputFolder, outputFolder, addFileNameSuffix }; } // TODO: This is a temporary workaround. The long term plan is for API Extractor's DocCommentEnhancer // to apply all @inheritDoc tags before the .api.json file is written. // See DocCommentEnhancer._applyInheritDoc() for more info. private _applyInheritDoc(apiItem: ApiItem, apiModel: ApiModel): void { if (apiItem instanceof ApiDocumentedItem) { if (apiItem.tsdocComment) { const inheritDocTag: tsdoc.DocInheritDocTag | undefined = apiItem.tsdocComment.inheritDocTag; if (inheritDocTag && inheritDocTag.declarationReference) { // Attempt to resolve the declaration reference const result: IResolveDeclarationReferenceResult = apiModel.resolveDeclarationReference( inheritDocTag.declarationReference, apiItem ); if (result.errorMessage) { console.log( colors.yellow( `Warning: Unresolved @inheritDoc tag for ${apiItem.displayName}: ` + result.errorMessage ) ); } else { if ( result.resolvedApiItem instanceof ApiDocumentedItem && result.resolvedApiItem.tsdocComment && result.resolvedApiItem !== apiItem ) { this._copyInheritedDocs( apiItem.tsdocComment, result.resolvedApiItem.tsdocComment ); } } } } } // Recurse members if (ApiItemContainerMixin.isBaseClassOf(apiItem)) { for (const member of apiItem.members) { this._applyInheritDoc(member, apiModel); } } } /** * Copy the content from `sourceDocComment` to `targetDocComment`. * This code is borrowed from DocCommentEnhancer as a temporary workaround. */ private _copyInheritedDocs( targetDocComment: tsdoc.DocComment, sourceDocComment: tsdoc.DocComment ): void { targetDocComment.summarySection = sourceDocComment.summarySection; targetDocComment.remarksBlock = sourceDocComment.remarksBlock; targetDocComment.params.clear(); for (const param of sourceDocComment.params) { targetDocComment.params.add(param); } for (const typeParam of sourceDocComment.typeParams) { targetDocComment.typeParams.add(typeParam); } targetDocComment.returnsBlock = sourceDocComment.returnsBlock; targetDocComment.inheritDocTag = undefined; } }