UNPKG

@microsoft/api-documenter

Version:

Read JSON files from api-extractor, generate documentation pages

823 lines 37.1 kB
"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; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.YamlDocumenter = void 0; const path = __importStar(require("path")); const yaml = require("js-yaml"); const node_core_library_1 = require("@rushstack/node-core-library"); const tsdoc_1 = require("@microsoft/tsdoc"); const api_extractor_model_1 = require("@microsoft/api-extractor-model"); const Utilities_1 = require("../utils/Utilities"); const CustomMarkdownEmitter_1 = require("../markdown/CustomMarkdownEmitter"); const ToSdpConvertHelper_1 = require("../utils/ToSdpConvertHelper"); const typescript_schema_json_1 = __importDefault(require("../yaml/typescript.schema.json")); const yamlApiSchema = node_core_library_1.JsonSchema.fromLoadedObject(typescript_schema_json_1.default); /** * Writes documentation in the Universal Reference YAML file format, as defined by typescript.schema.json. */ class YamlDocumenter { constructor(apiModel, newDocfxNamespaces = false, yamlFormat = 'sdp') { this._apiModel = apiModel; this.newDocfxNamespaces = newDocfxNamespaces; this._yamlFormat = yamlFormat; this._markdownEmitter = new CustomMarkdownEmitter_1.CustomMarkdownEmitter(this._apiModel); this._apiItemsByCanonicalReference = new Map(); this._initApiItems(); } /** @virtual */ generateFiles(outputFolder) { console.log(); this._deleteOldOutputFiles(outputFolder); for (const apiPackage of this._apiModel.packages) { console.log(`Writing ${apiPackage.name} package`); this._visitApiItems(outputFolder, apiPackage, undefined); } if (this._yamlFormat === 'sdp') { (0, ToSdpConvertHelper_1.convertUDPYamlToSDP)(outputFolder); } this._writeTocFile(outputFolder, this._apiModel.packages); } /** @virtual */ onGetTocRoot() { return { name: 'SharePoint Framework reference', href: '~/overview/sharepoint.md', items: [] }; } /** @virtual */ onCustomizeYamlItem(yamlItem) { // virtual // (overridden by child class) } _visitApiItems(outputFolder, apiItem, parentYamlFile) { let savedYamlReferences; if (!this._shouldEmbed(apiItem.kind)) { savedYamlReferences = this._yamlReferences; this._yamlReferences = undefined; } const yamlItem = this._generateYamlItem(apiItem); if (!yamlItem) { return false; } this.onCustomizeYamlItem(yamlItem); if (this._shouldEmbed(apiItem.kind)) { if (!parentYamlFile) { throw new node_core_library_1.InternalError('Missing file context'); } parentYamlFile.items.push(yamlItem); } else { const newYamlFile = { items: [] }; newYamlFile.items.push(yamlItem); const children = this._getLogicalChildren(apiItem); for (const child of children) { if (child instanceof api_extractor_model_1.ApiDocumentedItem) { if (this._visitApiItems(outputFolder, child, newYamlFile)) { if (!yamlItem.children) { yamlItem.children = []; } yamlItem.children.push(this._getUid(child)); } } } if (this._yamlReferences && this._yamlReferences.references.length > 0) { newYamlFile.references = this._yamlReferences.references; } this._yamlReferences = savedYamlReferences; const yamlFilePath = this._getYamlFilePath(outputFolder, apiItem); if (apiItem.kind === api_extractor_model_1.ApiItemKind.Package) { console.log('Writing ' + yamlFilePath); } this._writeYamlFile(newYamlFile, yamlFilePath, 'UniversalReference', yamlApiSchema); if (parentYamlFile) { // References should be recorded in the parent YAML file with the local name of the embedded item. // This avoids unnecessary repetition when listing items inside of a namespace. this._recordYamlReference(this._ensureYamlReferences(), this._getUid(apiItem), this._getYamlItemName(apiItem, { includeNamespace: !this.newDocfxNamespaces, includeSignature: true }), this._getYamlItemName(apiItem, { includeNamespace: true, includeSignature: true })); } } return true; } _getLogicalChildren(apiItem) { const children = []; if (apiItem.kind === api_extractor_model_1.ApiItemKind.Package) { // Skip over the entry point, since it's not part of the documentation hierarchy this._flattenNamespaces(apiItem.members[0].members, children, this.newDocfxNamespaces ? 0 /* FlattenMode.NestedNamespacesAndChildren */ : 3 /* FlattenMode.NestedChildren */); } else { this._flattenNamespaces(apiItem.members, children, this.newDocfxNamespaces ? 2 /* FlattenMode.ImmediateChildren */ : 3 /* FlattenMode.NestedChildren */); } return children; } // Flattens nested namespaces into top level entries so that the following: // namespace X { export namespace Y { export namespace Z { } } // Is represented as: // - X // - X.Y // - X.Y.Z _flattenNamespaces(items, childrenOut, mode) { let hasNonNamespaceChildren = false; for (const item of items) { if (item.kind === api_extractor_model_1.ApiItemKind.Namespace) { switch (mode) { case 3 /* FlattenMode.NestedChildren */: // Include children of namespaces, but not the namespaces themselves. This matches existing legacy behavior. this._flattenNamespaces(item.members, childrenOut, 3 /* FlattenMode.NestedChildren */); break; case 1 /* FlattenMode.NestedNamespacesOnly */: case 0 /* FlattenMode.NestedNamespacesAndChildren */: // At any level, always include a nested namespace if it has non-namespace children, but do not include its // non-namespace children in the result. // Record the offset at which the namespace is added in case we need to remove it later. const index = childrenOut.length; childrenOut.push(item); if (!this._flattenNamespaces(item.members, childrenOut, 1 /* FlattenMode.NestedNamespacesOnly */)) { // This namespace had no non-namespace children, remove it. childrenOut.splice(index, 1); } break; } } else if (this._shouldInclude(item.kind)) { switch (mode) { case 3 /* FlattenMode.NestedChildren */: case 0 /* FlattenMode.NestedNamespacesAndChildren */: case 2 /* FlattenMode.ImmediateChildren */: // At the top level, include non-namespace children as well. childrenOut.push(item); break; } hasNonNamespaceChildren = true; } } return hasNonNamespaceChildren; } /** * Write the table of contents */ _writeTocFile(outputFolder, apiItems) { const tocFile = this.buildYamlTocFile(apiItems); const tocFilePath = path.join(outputFolder, 'toc.yml'); console.log('Writing ' + tocFilePath); this._writeYamlFile(tocFile, tocFilePath, '', undefined); } /** @virtual */ buildYamlTocFile(apiItems) { const tocFile = { items: [] }; const rootItem = this.onGetTocRoot(); tocFile.items.push(rootItem); rootItem.items.push(...this._buildTocItems(apiItems)); return tocFile; } _buildTocItems(apiItems) { const tocItems = []; for (const apiItem of apiItems) { let tocItem; if (apiItem.kind === api_extractor_model_1.ApiItemKind.Namespace && !this.newDocfxNamespaces) { tocItem = { name: this._getTocItemName(apiItem) }; } else { if (this._shouldEmbed(apiItem.kind)) { // Don't generate table of contents items for embedded definitions continue; } tocItem = { name: this._getTocItemName(apiItem), uid: this._getUid(apiItem) }; } tocItems.push(tocItem); const children = this._getLogicalChildren(apiItem); const childItems = this._buildTocItems(children); if (childItems.length > 0) { tocItem.items = childItems; } } return tocItems; } /** @virtual */ _getTocItemName(apiItem) { let name; if (apiItem.kind === api_extractor_model_1.ApiItemKind.Package) { name = node_core_library_1.PackageName.getUnscopedName(apiItem.displayName); } else { name = this._getYamlItemName(apiItem); } if (name === apiItem.displayName && apiItem.getMergedSiblings().length > 1) { name += ` (${apiItem.kind})`; } return name; } _shouldEmbed(apiItemKind) { switch (apiItemKind) { case api_extractor_model_1.ApiItemKind.Class: case api_extractor_model_1.ApiItemKind.Package: case api_extractor_model_1.ApiItemKind.Interface: case api_extractor_model_1.ApiItemKind.Enum: case api_extractor_model_1.ApiItemKind.TypeAlias: return false; case api_extractor_model_1.ApiItemKind.Namespace: return !this.newDocfxNamespaces; } return true; } _shouldInclude(apiItemKind) { // Filter out known items that are not yet supported switch (apiItemKind) { case api_extractor_model_1.ApiItemKind.CallSignature: case api_extractor_model_1.ApiItemKind.ConstructSignature: case api_extractor_model_1.ApiItemKind.IndexSignature: return false; } return true; } _generateYamlItem(apiItem) { // Filter out known items that are not yet supported if (!this._shouldInclude(apiItem.kind)) { return undefined; } const uid = this._getUidObject(apiItem); const yamlItem = { uid: uid.toString() }; if (apiItem.tsdocComment) { const tsdocComment = apiItem.tsdocComment; if (tsdocComment.summarySection) { const summary = this._renderMarkdown(tsdocComment.summarySection, apiItem); if (summary) { yamlItem.summary = summary; } } if (tsdocComment.remarksBlock) { const remarks = this._renderMarkdown(tsdocComment.remarksBlock.content, apiItem); if (remarks) { yamlItem.remarks = remarks; } } if (tsdocComment) { // Write the @example blocks const exampleBlocks = tsdocComment.customBlocks.filter((x) => x.blockTag.tagNameWithUpperCase === tsdoc_1.StandardTags.example.tagNameWithUpperCase); for (const exampleBlock of exampleBlocks) { const example = this._renderMarkdown(exampleBlock.content, apiItem); if (example) { yamlItem.example = [...(yamlItem.example || []), example]; } } } if (tsdocComment.deprecatedBlock) { const deprecatedMessage = this._renderMarkdown(tsdocComment.deprecatedBlock.content, apiItem); if (deprecatedMessage.length > 0) { yamlItem.deprecated = { content: deprecatedMessage }; } } } if (api_extractor_model_1.ApiReleaseTagMixin.isBaseClassOf(apiItem)) { if (apiItem.releaseTag === api_extractor_model_1.ReleaseTag.Alpha || apiItem.releaseTag === api_extractor_model_1.ReleaseTag.Beta) { yamlItem.isPreview = true; } } yamlItem.name = this._getYamlItemName(apiItem, { includeSignature: true, includeNamespace: !this.newDocfxNamespaces }); yamlItem.fullName = this._getYamlItemName(apiItem, { includeSignature: true, includeNamespace: true }); yamlItem.langs = ['typeScript']; // Add the namespace of the item if it is contained in one. // Do not add the namespace parent of a namespace as they are flattened in the documentation. if (apiItem.kind !== api_extractor_model_1.ApiItemKind.Namespace && apiItem.parent && apiItem.parent.kind === api_extractor_model_1.ApiItemKind.Namespace && this.newDocfxNamespaces) { yamlItem.namespace = apiItem.parent.canonicalReference.toString(); } switch (apiItem.kind) { case api_extractor_model_1.ApiItemKind.Enum: yamlItem.type = 'enum'; break; case api_extractor_model_1.ApiItemKind.EnumMember: yamlItem.type = 'field'; const enumMember = apiItem; if (enumMember.initializerExcerpt && enumMember.initializerExcerpt.text.length > 0) { yamlItem.numericValue = enumMember.initializerExcerpt.text; } break; case api_extractor_model_1.ApiItemKind.Class: yamlItem.type = 'class'; this._populateYamlClassOrInterface(uid, yamlItem, apiItem); break; case api_extractor_model_1.ApiItemKind.Interface: yamlItem.type = 'interface'; this._populateYamlClassOrInterface(uid, yamlItem, apiItem); break; case api_extractor_model_1.ApiItemKind.Method: case api_extractor_model_1.ApiItemKind.MethodSignature: yamlItem.type = 'method'; this._populateYamlFunctionLike(uid, yamlItem, apiItem); break; case api_extractor_model_1.ApiItemKind.Constructor: yamlItem.type = 'constructor'; this._populateYamlFunctionLike(uid, yamlItem, apiItem); break; case api_extractor_model_1.ApiItemKind.Package: yamlItem.type = 'package'; break; case api_extractor_model_1.ApiItemKind.Namespace: yamlItem.type = 'namespace'; break; case api_extractor_model_1.ApiItemKind.Property: case api_extractor_model_1.ApiItemKind.PropertySignature: const apiProperty = apiItem; if (apiProperty.isEventProperty) { yamlItem.type = 'event'; } else { yamlItem.type = 'property'; } this._populateYamlProperty(uid, yamlItem, apiProperty); break; case api_extractor_model_1.ApiItemKind.Function: yamlItem.type = 'function'; this._populateYamlFunctionLike(uid, yamlItem, apiItem); break; case api_extractor_model_1.ApiItemKind.Variable: yamlItem.type = 'variable'; this._populateYamlVariable(uid, yamlItem, apiItem); break; case api_extractor_model_1.ApiItemKind.TypeAlias: yamlItem.type = 'typealias'; this._populateYamlTypeAlias(uid, yamlItem, apiItem); break; default: throw new Error('Unimplemented item kind: ' + apiItem.kind); } if (apiItem.kind !== api_extractor_model_1.ApiItemKind.Package && !this._shouldEmbed(apiItem.kind)) { const associatedPackage = apiItem.getAssociatedPackage(); if (!associatedPackage) { throw new Error('Unable to determine associated package for ' + apiItem.displayName); } yamlItem.package = this._getUid(associatedPackage); } return yamlItem; } _populateYamlTypeParameters(contextUid, apiItem) { const typeParameters = []; for (const apiTypeParameter of apiItem.typeParameters) { const typeParameter = { id: apiTypeParameter.name }; if (apiTypeParameter.tsdocTypeParamBlock) { typeParameter.description = this._renderMarkdown(apiTypeParameter.tsdocTypeParamBlock.content, apiItem); } if (!apiTypeParameter.constraintExcerpt.isEmpty) { typeParameter.type = [this._renderType(contextUid, apiTypeParameter.constraintExcerpt)]; } typeParameters.push(typeParameter); } return typeParameters; } _populateYamlClassOrInterface(uid, yamlItem, apiItem) { if (apiItem instanceof api_extractor_model_1.ApiClass) { if (apiItem.extendsType) { yamlItem.extends = [this._renderType(uid, apiItem.extendsType.excerpt)]; yamlItem.inheritance = this._renderInheritance(uid, [apiItem.extendsType]); } if (apiItem.implementsTypes.length > 0) { yamlItem.implements = []; for (const implementsType of apiItem.implementsTypes) { yamlItem.implements.push(this._renderType(uid, implementsType.excerpt)); } } } else if (apiItem instanceof api_extractor_model_1.ApiInterface) { if (apiItem.extendsTypes.length > 0) { yamlItem.extends = []; for (const extendsType of apiItem.extendsTypes) { yamlItem.extends.push(this._renderType(uid, extendsType.excerpt)); } yamlItem.inheritance = this._renderInheritance(uid, apiItem.extendsTypes); } const typeParameters = this._populateYamlTypeParameters(uid, apiItem); if (typeParameters.length) { yamlItem.syntax = { typeParameters }; } } if (apiItem.tsdocComment) { if (apiItem.tsdocComment.modifierTagSet.isSealed()) { let sealedMessage; if (apiItem.kind === api_extractor_model_1.ApiItemKind.Class) { sealedMessage = 'This class is marked as `@sealed`. Subclasses should not extend it.'; } else { sealedMessage = 'This interface is marked as `@sealed`. Other interfaces should not extend it.'; } if (!yamlItem.remarks) { yamlItem.remarks = sealedMessage; } else { yamlItem.remarks = sealedMessage + '\n\n' + yamlItem.remarks; } } } } _populateYamlFunctionLike(uid, yamlItem, apiItem) { const syntax = { content: apiItem.getExcerptWithModifiers() }; yamlItem.syntax = syntax; if (api_extractor_model_1.ApiReturnTypeMixin.isBaseClassOf(apiItem)) { const returnType = this._renderType(uid, apiItem.returnTypeExcerpt); let returnDescription = ''; if (apiItem.tsdocComment && apiItem.tsdocComment.returnsBlock) { returnDescription = this._renderMarkdown(apiItem.tsdocComment.returnsBlock.content, apiItem); // temporary workaround for people who mistakenly add a hyphen, e.g. "@returns - blah" returnDescription = returnDescription.replace(/^\s*-\s+/, ''); } if (returnType || returnDescription) { syntax.return = { type: [returnType], description: returnDescription }; } } const parameters = []; for (const apiParameter of apiItem.parameters) { let parameterDescription = ''; if (apiParameter.tsdocParamBlock) { parameterDescription = this._renderMarkdown(apiParameter.tsdocParamBlock.content, apiItem); } parameters.push({ id: apiParameter.name, description: parameterDescription, type: [this._renderType(uid, apiParameter.parameterTypeExcerpt)], optional: apiParameter.isOptional }); } if (parameters.length) { syntax.parameters = parameters; } if (api_extractor_model_1.ApiTypeParameterListMixin.isBaseClassOf(apiItem)) { const typeParameters = this._populateYamlTypeParameters(uid, apiItem); if (typeParameters.length) { syntax.typeParameters = typeParameters; } } } _populateYamlProperty(uid, yamlItem, apiItem) { const syntax = { content: apiItem.getExcerptWithModifiers() }; yamlItem.syntax = syntax; if (apiItem.propertyTypeExcerpt.text) { syntax.return = { type: [this._renderType(uid, apiItem.propertyTypeExcerpt)] }; } } _populateYamlVariable(uid, yamlItem, apiItem) { const syntax = { content: apiItem.getExcerptWithModifiers() }; yamlItem.syntax = syntax; if (apiItem.variableTypeExcerpt.text) { syntax.return = { type: [this._renderType(uid, apiItem.variableTypeExcerpt)] }; } } _populateYamlTypeAlias(uid, yamlItem, apiItem) { const syntax = { content: apiItem.getExcerptWithModifiers() }; yamlItem.syntax = syntax; const typeParameters = this._populateYamlTypeParameters(uid, apiItem); if (typeParameters.length) { syntax.typeParameters = typeParameters; } if (apiItem.typeExcerpt.text) { syntax.return = { type: [this._renderType(uid, apiItem.typeExcerpt)] }; } } _renderMarkdown(docSection, contextApiItem) { const stringBuilder = new tsdoc_1.StringBuilder(); this._markdownEmitter.emit(stringBuilder, docSection, { contextApiItem, onGetFilenameForApiItem: (apiItem) => { // NOTE: GitHub's markdown renderer does not resolve relative hyperlinks correctly // unless they start with "./" or "../". // To ensure the xref is properly escaped, we first encode the entire xref // to handle escaping of reserved characters. Then we must replace '#' and '?' // characters so that they are not interpreted as a querystring or hash. // We must also backslash-escape unbalanced `(` and `)` characters as the // markdown spec insists that they are only valid when balanced. To reduce // the overhead we only support balanced parenthesis with a depth of 1. return encodeURI(`xref:${this._getUid(apiItem)}`) .replace(/[#?]/g, (s) => encodeURIComponent(s)) .replace(/(\([^(]*\))|[()]/g, (s, balanced) => balanced || '\\' + s); } }); return stringBuilder.toString().trim(); } _writeYamlFile(dataObject, filePath, yamlMimeType, schema) { node_core_library_1.JsonFile.validateNoUndefinedMembers(dataObject); let stringified = yaml.safeDump(dataObject, { lineWidth: 120 }); if (yamlMimeType) { stringified = `### YamlMime:${yamlMimeType}\n` + stringified; } node_core_library_1.FileSystem.writeFile(filePath, stringified, { convertLineEndings: node_core_library_1.NewlineKind.CrLf, ensureFolderExists: true }); if (schema) { schema.validateObject(dataObject, filePath); } } /** * Calculate the DocFX "uid" for the ApiItem * Example: `node-core-library!JsonFile#load` */ _getUid(apiItem) { return this._getUidObject(apiItem).toString(); } _getUidObject(apiItem) { return apiItem.canonicalReference; } /** * Initialize the _apiItemsByCanonicalReference data structure. */ _initApiItems() { this._initApiItemsRecursive(this._apiModel); } /** * Helper for _initApiItems() */ _initApiItemsRecursive(apiItem) { if (apiItem.canonicalReference && !apiItem.canonicalReference.isEmpty) { this._apiItemsByCanonicalReference.set(apiItem.canonicalReference.toString(), apiItem); } // Recurse container members if (api_extractor_model_1.ApiItemContainerMixin.isBaseClassOf(apiItem)) { for (const apiMember of apiItem.members) { this._initApiItemsRecursive(apiMember); } } } _ensureYamlReferences() { if (!this._yamlReferences) { this._yamlReferences = { references: [], typeNameToUid: new Map(), uidTypeReferenceCounters: new Map() }; } return this._yamlReferences; } _renderInheritance(contextUid, heritageTypes) { const result = []; for (const heritageType of heritageTypes) { const type = this._renderType(contextUid, heritageType.excerpt); const yamlInheritance = { type }; const apiItem = this._apiItemsByCanonicalReference.get(type); if (apiItem) { if (apiItem instanceof api_extractor_model_1.ApiClass) { if (apiItem.extendsType) { yamlInheritance.inheritance = this._renderInheritance(this._getUidObject(apiItem), [ apiItem.extendsType ]); } } else if (apiItem instanceof api_extractor_model_1.ApiInterface) { if (apiItem.extendsTypes.length > 0) { yamlInheritance.inheritance = this._renderInheritance(this._getUidObject(apiItem), apiItem.extendsTypes); } } } result.push(yamlInheritance); } return result; } _renderType(contextUid, typeExcerpt) { const excerptTokens = [...typeExcerpt.spannedTokens]; // copy the read-only array if (excerptTokens.length === 0) { return ''; } // Remove the last token if it consists only of whitespace const lastToken = excerptTokens[excerptTokens.length - 1]; if (lastToken.kind === api_extractor_model_1.ExcerptTokenKind.Content && !lastToken.text.trim()) { excerptTokens.pop(); if (excerptTokens.length === 0) { return ''; } } const typeName = typeExcerpt.text.trim(); // If there are no references to be used for a complex type, return the type name. if (!excerptTokens.some((tok) => tok.kind === api_extractor_model_1.ExcerptTokenKind.Reference && !!tok.canonicalReference)) { return typeName; } const yamlReferences = this._ensureYamlReferences(); const existingUid = yamlReferences.typeNameToUid.get(typeName); // If this type has already been referenced for the current file, return its uid. if (existingUid) { return existingUid; } // If the excerpt consists of a single reference token, record the reference. if (excerptTokens.length === 1 && excerptTokens[0].kind === api_extractor_model_1.ExcerptTokenKind.Reference && excerptTokens[0].canonicalReference) { const excerptRef = excerptTokens[0].canonicalReference.toString(); const apiItem = this._apiItemsByCanonicalReference.get(excerptRef); return this._recordYamlReference(yamlReferences, excerptTokens[0].canonicalReference.toString(), apiItem ? this._getYamlItemName(apiItem) : typeName, apiItem ? this._getYamlItemName(apiItem, { includeNamespace: true }) : typeName); } // Otherwise, the type is complex and consists of one or more reference tokens. Record a reference // and return its uid. const baseUid = contextUid.withMeaning(undefined).withOverloadIndex(undefined).toString(); // Keep track of the count for the base uid (without meaning or overload index) to ensure // that each complex type reference is unique. const counter = yamlReferences.uidTypeReferenceCounters.get(baseUid) || 0; yamlReferences.uidTypeReferenceCounters.set(baseUid, counter + 1); const uid = contextUid .addNavigationStep("~" /* Navigation.Locals */, `${counter}`) .withMeaning("complex" /* Meaning.ComplexType */) .withOverloadIndex(undefined) .toString(); return this._recordYamlReference(yamlReferences, uid, typeName, typeName, excerptTokens); } _recordYamlReference(yamlReferences, uid, name, fullName, excerptTokens) { if (yamlReferences.references.some((ref) => ref.uid === uid)) { return uid; } // Fill in the reference spec from the excerpt. const specs = []; if (excerptTokens) { for (const token of excerptTokens) { if (token.kind === api_extractor_model_1.ExcerptTokenKind.Reference) { const spec = {}; const specUid = token.canonicalReference && token.canonicalReference.toString(); const apiItem = specUid ? this._apiItemsByCanonicalReference.get(specUid) : undefined; if (specUid) { spec.uid = specUid; } spec.name = token.text; spec.fullName = apiItem ? apiItem.getScopedNameWithinPackage() : token.canonicalReference ? token.canonicalReference .withSource(undefined) .withMeaning(undefined) .withOverloadIndex(undefined) .toString() : token.text; specs.push(spec); } else { specs.push({ name: token.text, fullName: token.text }); } } } const yamlReference = { uid }; if (specs.length > 0) { yamlReference.name = specs .map((s) => s.name) .join('') .trim(); yamlReference.fullName = specs .map((s) => s.fullName || s.name) .join('') .trim(); yamlReference['spec.typeScript'] = specs; } else { if (name !== uid) { yamlReference.name = name; } if (fullName !== uid && fullName !== name) { yamlReference.fullName = fullName; } } yamlReferences.references.push(yamlReference); return uid; } _getYamlItemName(apiItem, options = {}) { const { includeSignature, includeNamespace } = options; const baseName = includeSignature ? Utilities_1.Utilities.getConciseSignature(apiItem) : apiItem.displayName; if ((includeNamespace || apiItem.kind === api_extractor_model_1.ApiItemKind.Namespace) && apiItem.parent && apiItem.parent.kind === api_extractor_model_1.ApiItemKind.Namespace) { // If the immediate parent is a namespace, then add the namespaces to the name. For example: // // // Name: "N1" // export namespace N1 { // // Name: "N1.N2" // export namespace N2 { // // Name: "N1.N2.f(x,y)" // export function f(x: string, y: string): string { // return x + y; // } // // // // Name: "N1.N2.C" // export class C { // // Name: "member(x,y)" <=========== // public member(x: string, y: string): string { // return x + y; // } // } // } // } // // In the above example, "member(x, y)" does not appear as "N1.N2.C.member(x,y)" because YamlDocumenter // embeds this entry in the web page for "N1.N2.C", so the container is obvious. Whereas "N1.N2.f(x,y)" // needs to be qualified because the DocFX template doesn't make pages for namespaces. Instead, they get // flattened into the package's page. const nameParts = [baseName]; for (let current = apiItem.parent; current; current = current.parent) { if (current.kind !== api_extractor_model_1.ApiItemKind.Namespace) { break; } nameParts.unshift(current.displayName); } return nameParts.join('.'); } else { return baseName; } } _getYamlFilePath(outputFolder, apiItem) { let result = ''; for (const current of apiItem.getHierarchy()) { switch (current.kind) { case api_extractor_model_1.ApiItemKind.Model: case api_extractor_model_1.ApiItemKind.EntryPoint: break; case api_extractor_model_1.ApiItemKind.Package: result += Utilities_1.Utilities.getSafeFilenameForName(node_core_library_1.PackageName.getUnscopedName(current.displayName)); break; default: if (current.parent && current.parent.kind === api_extractor_model_1.ApiItemKind.EntryPoint) { result += '/'; } else { result += '.'; } result += Utilities_1.Utilities.getSafeFilenameForName(current.displayName); break; } } let disambiguator = ''; if (apiItem.getMergedSiblings().length > 1) { disambiguator = `-${apiItem.kind.toLowerCase()}`; } return path.join(outputFolder, result + disambiguator + '.yml'); } _deleteOldOutputFiles(outputFolder) { console.log('Deleting old output from ' + outputFolder); node_core_library_1.FileSystem.ensureEmptyFolder(outputFolder); } } exports.YamlDocumenter = YamlDocumenter; //# sourceMappingURL=YamlDocumenter.js.map