diff --git a/tools/api-markdown-documenter/api-report/api-markdown-documenter.alpha.api.md b/tools/api-markdown-documenter/api-report/api-markdown-documenter.alpha.api.md
index 048d96b1e324..fcfd3d56e58d 100644
--- a/tools/api-markdown-documenter/api-report/api-markdown-documenter.alpha.api.md
+++ b/tools/api-markdown-documenter/api-report/api-markdown-documenter.alpha.api.md
@@ -61,7 +61,7 @@ export interface ApiItemTransformationConfigurationBase {
}
// @public
-export interface ApiItemTransformationOptions extends ApiItemTransformationConfigurationBase, Partial, LoggingConfiguration {
+export interface ApiItemTransformationOptions extends ApiItemTransformationConfigurationBase, DocumentationSuiteOptions, LoggingConfiguration {
readonly defaultSectionLayout?: (apiItem: ApiItem, childSections: SectionNode[] | undefined, config: ApiItemTransformationConfiguration) => SectionNode[];
readonly transformations?: Partial;
}
@@ -106,7 +106,7 @@ export interface ApiItemTransformations {
declare namespace ApiItemUtilities {
export {
- doesItemRequireOwnDocument,
+ doesItemKindRequireOwnDocument,
filterItems,
getHeadingForApiItem,
getLinkForApiItem,
@@ -211,17 +211,22 @@ function createTypeParametersSection(typeParameters: readonly TypeParameter[], c
export const defaultConsoleLogger: Logger;
// @public
-export namespace DefaultDocumentationSuiteOptions {
- const defaultDocumentBoundaries: ApiMemberKind[];
- const defaultHierarchyBoundaries: ApiMemberKind[];
+export namespace DefaultDocumentationSuiteConfiguration {
export function defaultGetAlertsForItem(apiItem: ApiItem): string[];
- export function defaultGetFileNameForItem(apiItem: ApiItem): string;
export function defaultGetHeadingTextForItem(apiItem: ApiItem): string;
export function defaultGetLinkTextForItem(apiItem: ApiItem): string;
export function defaultGetUriBaseOverrideForItem(): string | undefined;
export function defaultSkipPackage(): boolean;
}
+// @public
+export type DocumentationHierarchyConfiguration = SectionHierarchyConfiguration | DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+
+// @public
+export interface DocumentationHierarchyConfigurationBase {
+ readonly kind: THierarchyKind;
+}
+
// @public
export interface DocumentationLiteralNode extends Literal, DocumentationNode {
readonly isLiteral: true;
@@ -306,21 +311,30 @@ export abstract class DocumentationParentNodeBase string[];
- readonly getFileNameForItem: (apiItem: ApiItem) => string;
readonly getHeadingTextForItem: (apiItem: ApiItem) => string;
readonly getLinkTextForItem: (apiItem: ApiItem) => string;
readonly getUriBaseOverrideForItem: (apiItem: ApiItem) => string | undefined;
- readonly hierarchyBoundaries: HierarchyBoundaries;
+ readonly hierarchy: HierarchyConfiguration;
readonly includeBreadcrumb: boolean;
readonly includeTopLevelDocumentHeading: boolean;
- readonly minimumReleaseLevel: Omit;
+ readonly minimumReleaseLevel?: Exclude;
readonly skipPackage: (apiPackage: ApiPackage) => boolean;
}
// @public
-export type DocumentBoundaries = ApiMemberKind[];
+export type DocumentationSuiteOptions = Omit, "hierarchy"> & {
+ readonly hierarchy?: HierarchyOptions;
+};
+
+// @public
+export interface DocumentHierarchyConfiguration extends DocumentationHierarchyConfigurationBase, DocumentHierarchyProperties {
+}
+
+// @public
+export interface DocumentHierarchyProperties {
+ readonly documentName?: string | undefined | ((apiItem: ApiItem) => string | undefined);
+}
// @public
export class DocumentNode implements Parent, DocumentNodeProps {
@@ -360,7 +374,7 @@ export namespace DocumentWriter {
}
// @public
-function doesItemRequireOwnDocument(apiItem: ApiItem, documentBoundaries: DocumentBoundaries): boolean;
+function doesItemKindRequireOwnDocument(apiItemKind: ValidApiItemKind, hierarchyConfig: Required): boolean;
// @public
export class FencedCodeBlockNode extends DocumentationParentNodeBase implements MultiLineDocumentationNode {
@@ -374,12 +388,28 @@ export class FencedCodeBlockNode extends DocumentationParentNodeBase implements
// @public
export interface FileSystemConfiguration {
readonly newlineKind?: NewlineKind;
- outputDirectoryPath: string;
+ readonly outputDirectoryPath: string;
}
// @public
function filterItems(apiItems: readonly ApiItem[], config: ApiItemTransformationConfiguration): ApiItem[];
+// @public
+export enum FolderDocumentPlacement {
+ Inside = "inside",
+ Outside = "outside"
+}
+
+// @public
+export interface FolderHierarchyConfiguration extends DocumentationHierarchyConfigurationBase, FolderHierarchyProperties {
+}
+
+// @public
+export interface FolderHierarchyProperties extends DocumentHierarchyProperties {
+ readonly documentPlacement: FolderDocumentPlacement | ((apiItem: ApiItem) => FolderDocumentPlacement);
+ readonly folderName: string | undefined | ((apiItem: ApiItem) => string | undefined);
+}
+
// @public
export function getApiItemTransformationConfigurationWithDefaults(options: ApiItemTransformationOptions): ApiItemTransformationConfiguration;
@@ -449,7 +479,29 @@ export class HeadingNode extends DocumentationParentNodeBase]: DocumentationHierarchyConfiguration;
+} & {
+ [ApiItemKind.Model]: DocumentHierarchyConfiguration;
+ [ApiItemKind.Package]: DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+ [ApiItemKind.EntryPoint]: DocumentHierarchyConfiguration;
+};
+
+// @public
+export enum HierarchyKind {
+ Document = "document",
+ Folder = "folder",
+ Section = "section"
+}
+
+// @public
+export type HierarchyOptions = {
+ [Kind in Exclude]?: HierarchyKind | DocumentationHierarchyConfiguration;
+} & {
+ [ApiItemKind.Model]?: HierarchyKind.Document | DocumentHierarchyConfiguration;
+ [ApiItemKind.Package]?: HierarchyKind.Document | HierarchyKind.Folder | DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+ [ApiItemKind.EntryPoint]?: HierarchyKind.Document | DocumentHierarchyConfiguration;
+};
// @public
export class HorizontalRuleNode implements MultiLineDocumentationNode {
@@ -650,7 +702,7 @@ export { ReleaseTag }
// @alpha
function renderApiModelAsHtml(options: RenderApiModelAsHtmlOptions): Promise;
-// @public
+// @alpha
interface RenderApiModelAsHtmlOptions extends ApiItemTransformationOptions, RenderDocumentAsHtmlConfiguration, FileSystemConfiguration {
}
@@ -672,14 +724,14 @@ export interface RenderDocumentAsHtmlConfiguration extends ToHtmlConfiguration,
}
// @alpha
-function renderDocumentsAsHtml(documents: DocumentNode[], options: RenderDocumentsAsHtmlOptions): Promise;
+function renderDocumentsAsHtml(documents: readonly DocumentNode[], options: RenderDocumentsAsHtmlOptions): Promise;
-// @public
+// @alpha
interface RenderDocumentsAsHtmlOptions extends RenderDocumentAsHtmlConfiguration, FileSystemConfiguration {
}
// @public
-function renderDocumentsAsMarkdown(documents: DocumentNode[], options: RenderDocumentsAsMarkdownOptions): Promise;
+function renderDocumentsAsMarkdown(documents: readonly DocumentNode[], options: RenderDocumentsAsMarkdownOptions): Promise;
// @public
interface RenderDocumentsAsMarkdownOptions extends MarkdownRenderConfiguration, FileSystemConfiguration {
@@ -699,6 +751,9 @@ function renderNode(node: DocumentationNode, writer: DocumentWriter, context: Ma
// @public
function renderNodes(children: DocumentationNode[], writer: DocumentWriter, childContext: MarkdownRenderContext): void;
+// @public
+export type SectionHierarchyConfiguration = DocumentationHierarchyConfigurationBase;
+
// @public
export class SectionNode extends DocumentationParentNodeBase implements MultiLineDocumentationNode {
constructor(children: DocumentationNode[], heading?: HeadingNode);
diff --git a/tools/api-markdown-documenter/api-report/api-markdown-documenter.beta.api.md b/tools/api-markdown-documenter/api-report/api-markdown-documenter.beta.api.md
index d7c3c4006493..f33b0167f424 100644
--- a/tools/api-markdown-documenter/api-report/api-markdown-documenter.beta.api.md
+++ b/tools/api-markdown-documenter/api-report/api-markdown-documenter.beta.api.md
@@ -61,7 +61,7 @@ export interface ApiItemTransformationConfigurationBase {
}
// @public
-export interface ApiItemTransformationOptions extends ApiItemTransformationConfigurationBase, Partial, LoggingConfiguration {
+export interface ApiItemTransformationOptions extends ApiItemTransformationConfigurationBase, DocumentationSuiteOptions, LoggingConfiguration {
readonly defaultSectionLayout?: (apiItem: ApiItem, childSections: SectionNode[] | undefined, config: ApiItemTransformationConfiguration) => SectionNode[];
readonly transformations?: Partial;
}
@@ -106,7 +106,7 @@ export interface ApiItemTransformations {
declare namespace ApiItemUtilities {
export {
- doesItemRequireOwnDocument,
+ doesItemKindRequireOwnDocument,
filterItems,
getHeadingForApiItem,
getLinkForApiItem,
@@ -211,17 +211,22 @@ function createTypeParametersSection(typeParameters: readonly TypeParameter[], c
export const defaultConsoleLogger: Logger;
// @public
-export namespace DefaultDocumentationSuiteOptions {
- const defaultDocumentBoundaries: ApiMemberKind[];
- const defaultHierarchyBoundaries: ApiMemberKind[];
+export namespace DefaultDocumentationSuiteConfiguration {
export function defaultGetAlertsForItem(apiItem: ApiItem): string[];
- export function defaultGetFileNameForItem(apiItem: ApiItem): string;
export function defaultGetHeadingTextForItem(apiItem: ApiItem): string;
export function defaultGetLinkTextForItem(apiItem: ApiItem): string;
export function defaultGetUriBaseOverrideForItem(): string | undefined;
export function defaultSkipPackage(): boolean;
}
+// @public
+export type DocumentationHierarchyConfiguration = SectionHierarchyConfiguration | DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+
+// @public
+export interface DocumentationHierarchyConfigurationBase {
+ readonly kind: THierarchyKind;
+}
+
// @public
export interface DocumentationLiteralNode extends Literal, DocumentationNode {
readonly isLiteral: true;
@@ -306,21 +311,30 @@ export abstract class DocumentationParentNodeBase string[];
- readonly getFileNameForItem: (apiItem: ApiItem) => string;
readonly getHeadingTextForItem: (apiItem: ApiItem) => string;
readonly getLinkTextForItem: (apiItem: ApiItem) => string;
readonly getUriBaseOverrideForItem: (apiItem: ApiItem) => string | undefined;
- readonly hierarchyBoundaries: HierarchyBoundaries;
+ readonly hierarchy: HierarchyConfiguration;
readonly includeBreadcrumb: boolean;
readonly includeTopLevelDocumentHeading: boolean;
- readonly minimumReleaseLevel: Omit;
+ readonly minimumReleaseLevel?: Exclude;
readonly skipPackage: (apiPackage: ApiPackage) => boolean;
}
// @public
-export type DocumentBoundaries = ApiMemberKind[];
+export type DocumentationSuiteOptions = Omit, "hierarchy"> & {
+ readonly hierarchy?: HierarchyOptions;
+};
+
+// @public
+export interface DocumentHierarchyConfiguration extends DocumentationHierarchyConfigurationBase, DocumentHierarchyProperties {
+}
+
+// @public
+export interface DocumentHierarchyProperties {
+ readonly documentName?: string | undefined | ((apiItem: ApiItem) => string | undefined);
+}
// @public
export class DocumentNode implements Parent, DocumentNodeProps {
@@ -360,7 +374,7 @@ export namespace DocumentWriter {
}
// @public
-function doesItemRequireOwnDocument(apiItem: ApiItem, documentBoundaries: DocumentBoundaries): boolean;
+function doesItemKindRequireOwnDocument(apiItemKind: ValidApiItemKind, hierarchyConfig: Required): boolean;
// @public
export class FencedCodeBlockNode extends DocumentationParentNodeBase implements MultiLineDocumentationNode {
@@ -374,12 +388,28 @@ export class FencedCodeBlockNode extends DocumentationParentNodeBase implements
// @public
export interface FileSystemConfiguration {
readonly newlineKind?: NewlineKind;
- outputDirectoryPath: string;
+ readonly outputDirectoryPath: string;
}
// @public
function filterItems(apiItems: readonly ApiItem[], config: ApiItemTransformationConfiguration): ApiItem[];
+// @public
+export enum FolderDocumentPlacement {
+ Inside = "inside",
+ Outside = "outside"
+}
+
+// @public
+export interface FolderHierarchyConfiguration extends DocumentationHierarchyConfigurationBase, FolderHierarchyProperties {
+}
+
+// @public
+export interface FolderHierarchyProperties extends DocumentHierarchyProperties {
+ readonly documentPlacement: FolderDocumentPlacement | ((apiItem: ApiItem) => FolderDocumentPlacement);
+ readonly folderName: string | undefined | ((apiItem: ApiItem) => string | undefined);
+}
+
// @public
export function getApiItemTransformationConfigurationWithDefaults(options: ApiItemTransformationOptions): ApiItemTransformationConfiguration;
@@ -449,7 +479,29 @@ export class HeadingNode extends DocumentationParentNodeBase]: DocumentationHierarchyConfiguration;
+} & {
+ [ApiItemKind.Model]: DocumentHierarchyConfiguration;
+ [ApiItemKind.Package]: DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+ [ApiItemKind.EntryPoint]: DocumentHierarchyConfiguration;
+};
+
+// @public
+export enum HierarchyKind {
+ Document = "document",
+ Folder = "folder",
+ Section = "section"
+}
+
+// @public
+export type HierarchyOptions = {
+ [Kind in Exclude]?: HierarchyKind | DocumentationHierarchyConfiguration;
+} & {
+ [ApiItemKind.Model]?: HierarchyKind.Document | DocumentHierarchyConfiguration;
+ [ApiItemKind.Package]?: HierarchyKind.Document | HierarchyKind.Folder | DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+ [ApiItemKind.EntryPoint]?: HierarchyKind.Document | DocumentHierarchyConfiguration;
+};
// @public
export class HorizontalRuleNode implements MultiLineDocumentationNode {
@@ -647,10 +699,6 @@ export class PlainTextNode extends DocumentationLiteralNodeBase implemen
export { ReleaseTag }
-// @public
-interface RenderApiModelAsHtmlOptions extends ApiItemTransformationOptions, RenderDocumentAsHtmlConfiguration, FileSystemConfiguration {
-}
-
// @public
function renderApiModelAsMarkdown(options: RenderApiModelAsMarkdownOptions): Promise;
@@ -669,11 +717,7 @@ export interface RenderDocumentAsHtmlConfiguration extends ToHtmlConfiguration,
}
// @public
-interface RenderDocumentsAsHtmlOptions extends RenderDocumentAsHtmlConfiguration, FileSystemConfiguration {
-}
-
-// @public
-function renderDocumentsAsMarkdown(documents: DocumentNode[], options: RenderDocumentsAsMarkdownOptions): Promise;
+function renderDocumentsAsMarkdown(documents: readonly DocumentNode[], options: RenderDocumentsAsMarkdownOptions): Promise;
// @public
interface RenderDocumentsAsMarkdownOptions extends MarkdownRenderConfiguration, FileSystemConfiguration {
@@ -693,6 +737,9 @@ function renderNode(node: DocumentationNode, writer: DocumentWriter, context: Ma
// @public
function renderNodes(children: DocumentationNode[], writer: DocumentWriter, childContext: MarkdownRenderContext): void;
+// @public
+export type SectionHierarchyConfiguration = DocumentationHierarchyConfigurationBase;
+
// @public
export class SectionNode extends DocumentationParentNodeBase implements MultiLineDocumentationNode {
constructor(children: DocumentationNode[], heading?: HeadingNode);
diff --git a/tools/api-markdown-documenter/api-report/api-markdown-documenter.public.api.md b/tools/api-markdown-documenter/api-report/api-markdown-documenter.public.api.md
index cb0b02f27518..adbadf58a979 100644
--- a/tools/api-markdown-documenter/api-report/api-markdown-documenter.public.api.md
+++ b/tools/api-markdown-documenter/api-report/api-markdown-documenter.public.api.md
@@ -61,7 +61,7 @@ export interface ApiItemTransformationConfigurationBase {
}
// @public
-export interface ApiItemTransformationOptions extends ApiItemTransformationConfigurationBase, Partial, LoggingConfiguration {
+export interface ApiItemTransformationOptions extends ApiItemTransformationConfigurationBase, DocumentationSuiteOptions, LoggingConfiguration {
readonly defaultSectionLayout?: (apiItem: ApiItem, childSections: SectionNode[] | undefined, config: ApiItemTransformationConfiguration) => SectionNode[];
readonly transformations?: Partial;
}
@@ -106,7 +106,7 @@ export interface ApiItemTransformations {
declare namespace ApiItemUtilities {
export {
- doesItemRequireOwnDocument,
+ doesItemKindRequireOwnDocument,
filterItems,
getHeadingForApiItem,
getLinkForApiItem,
@@ -211,17 +211,22 @@ function createTypeParametersSection(typeParameters: readonly TypeParameter[], c
export const defaultConsoleLogger: Logger;
// @public
-export namespace DefaultDocumentationSuiteOptions {
- const defaultDocumentBoundaries: ApiMemberKind[];
- const defaultHierarchyBoundaries: ApiMemberKind[];
+export namespace DefaultDocumentationSuiteConfiguration {
export function defaultGetAlertsForItem(apiItem: ApiItem): string[];
- export function defaultGetFileNameForItem(apiItem: ApiItem): string;
export function defaultGetHeadingTextForItem(apiItem: ApiItem): string;
export function defaultGetLinkTextForItem(apiItem: ApiItem): string;
export function defaultGetUriBaseOverrideForItem(): string | undefined;
export function defaultSkipPackage(): boolean;
}
+// @public
+export type DocumentationHierarchyConfiguration = SectionHierarchyConfiguration | DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+
+// @public
+export interface DocumentationHierarchyConfigurationBase {
+ readonly kind: THierarchyKind;
+}
+
// @public
export interface DocumentationLiteralNode extends Literal, DocumentationNode {
readonly isLiteral: true;
@@ -306,21 +311,30 @@ export abstract class DocumentationParentNodeBase string[];
- readonly getFileNameForItem: (apiItem: ApiItem) => string;
readonly getHeadingTextForItem: (apiItem: ApiItem) => string;
readonly getLinkTextForItem: (apiItem: ApiItem) => string;
readonly getUriBaseOverrideForItem: (apiItem: ApiItem) => string | undefined;
- readonly hierarchyBoundaries: HierarchyBoundaries;
+ readonly hierarchy: HierarchyConfiguration;
readonly includeBreadcrumb: boolean;
readonly includeTopLevelDocumentHeading: boolean;
- readonly minimumReleaseLevel: Omit;
+ readonly minimumReleaseLevel?: Exclude;
readonly skipPackage: (apiPackage: ApiPackage) => boolean;
}
// @public
-export type DocumentBoundaries = ApiMemberKind[];
+export type DocumentationSuiteOptions = Omit, "hierarchy"> & {
+ readonly hierarchy?: HierarchyOptions;
+};
+
+// @public
+export interface DocumentHierarchyConfiguration extends DocumentationHierarchyConfigurationBase, DocumentHierarchyProperties {
+}
+
+// @public
+export interface DocumentHierarchyProperties {
+ readonly documentName?: string | undefined | ((apiItem: ApiItem) => string | undefined);
+}
// @public
export class DocumentNode implements Parent, DocumentNodeProps {
@@ -360,7 +374,7 @@ export namespace DocumentWriter {
}
// @public
-function doesItemRequireOwnDocument(apiItem: ApiItem, documentBoundaries: DocumentBoundaries): boolean;
+function doesItemKindRequireOwnDocument(apiItemKind: ValidApiItemKind, hierarchyConfig: Required): boolean;
// @public
export class FencedCodeBlockNode extends DocumentationParentNodeBase implements MultiLineDocumentationNode {
@@ -374,12 +388,28 @@ export class FencedCodeBlockNode extends DocumentationParentNodeBase implements
// @public
export interface FileSystemConfiguration {
readonly newlineKind?: NewlineKind;
- outputDirectoryPath: string;
+ readonly outputDirectoryPath: string;
}
// @public
function filterItems(apiItems: readonly ApiItem[], config: ApiItemTransformationConfiguration): ApiItem[];
+// @public
+export enum FolderDocumentPlacement {
+ Inside = "inside",
+ Outside = "outside"
+}
+
+// @public
+export interface FolderHierarchyConfiguration extends DocumentationHierarchyConfigurationBase, FolderHierarchyProperties {
+}
+
+// @public
+export interface FolderHierarchyProperties extends DocumentHierarchyProperties {
+ readonly documentPlacement: FolderDocumentPlacement | ((apiItem: ApiItem) => FolderDocumentPlacement);
+ readonly folderName: string | undefined | ((apiItem: ApiItem) => string | undefined);
+}
+
// @public
export function getApiItemTransformationConfigurationWithDefaults(options: ApiItemTransformationOptions): ApiItemTransformationConfiguration;
@@ -449,7 +479,29 @@ export class HeadingNode extends DocumentationParentNodeBase]: DocumentationHierarchyConfiguration;
+} & {
+ [ApiItemKind.Model]: DocumentHierarchyConfiguration;
+ [ApiItemKind.Package]: DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+ [ApiItemKind.EntryPoint]: DocumentHierarchyConfiguration;
+};
+
+// @public
+export enum HierarchyKind {
+ Document = "document",
+ Folder = "folder",
+ Section = "section"
+}
+
+// @public
+export type HierarchyOptions = {
+ [Kind in Exclude]?: HierarchyKind | DocumentationHierarchyConfiguration;
+} & {
+ [ApiItemKind.Model]?: HierarchyKind.Document | DocumentHierarchyConfiguration;
+ [ApiItemKind.Package]?: HierarchyKind.Document | HierarchyKind.Folder | DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+ [ApiItemKind.EntryPoint]?: HierarchyKind.Document | DocumentHierarchyConfiguration;
+};
// @public
export class HorizontalRuleNode implements MultiLineDocumentationNode {
@@ -625,10 +677,6 @@ export class PlainTextNode extends DocumentationLiteralNodeBase implemen
export { ReleaseTag }
-// @public
-interface RenderApiModelAsHtmlOptions extends ApiItemTransformationOptions, RenderDocumentAsHtmlConfiguration, FileSystemConfiguration {
-}
-
// @public
function renderApiModelAsMarkdown(options: RenderApiModelAsMarkdownOptions): Promise;
@@ -647,11 +695,7 @@ export interface RenderDocumentAsHtmlConfiguration extends ToHtmlConfiguration,
}
// @public
-interface RenderDocumentsAsHtmlOptions extends RenderDocumentAsHtmlConfiguration, FileSystemConfiguration {
-}
-
-// @public
-function renderDocumentsAsMarkdown(documents: DocumentNode[], options: RenderDocumentsAsMarkdownOptions): Promise;
+function renderDocumentsAsMarkdown(documents: readonly DocumentNode[], options: RenderDocumentsAsMarkdownOptions): Promise;
// @public
interface RenderDocumentsAsMarkdownOptions extends MarkdownRenderConfiguration, FileSystemConfiguration {
@@ -671,6 +715,9 @@ function renderNode(node: DocumentationNode, writer: DocumentWriter, context: Ma
// @public
function renderNodes(children: DocumentationNode[], writer: DocumentWriter, childContext: MarkdownRenderContext): void;
+// @public
+export type SectionHierarchyConfiguration = DocumentationHierarchyConfigurationBase;
+
// @public
export class SectionNode extends DocumentationParentNodeBase implements MultiLineDocumentationNode {
constructor(children: DocumentationNode[], heading?: HeadingNode);
diff --git a/tools/api-markdown-documenter/src/ApiItemUtilitiesModule.ts b/tools/api-markdown-documenter/src/ApiItemUtilitiesModule.ts
index 49882c369c86..60e397638707 100644
--- a/tools/api-markdown-documenter/src/ApiItemUtilitiesModule.ts
+++ b/tools/api-markdown-documenter/src/ApiItemUtilitiesModule.ts
@@ -8,7 +8,7 @@
*/
export {
- doesItemRequireOwnDocument,
+ doesItemKindRequireOwnDocument,
filterItems,
getHeadingForApiItem,
getLinkForApiItem,
diff --git a/tools/api-markdown-documenter/src/FileSystemConfiguration.ts b/tools/api-markdown-documenter/src/FileSystemConfiguration.ts
index 2265a661cdfb..2250702730ff 100644
--- a/tools/api-markdown-documenter/src/FileSystemConfiguration.ts
+++ b/tools/api-markdown-documenter/src/FileSystemConfiguration.ts
@@ -14,7 +14,7 @@ export interface FileSystemConfiguration {
/**
* The directory under which the document files will be generated.
*/
- outputDirectoryPath: string;
+ readonly outputDirectoryPath: string;
/**
* Specifies what type of newlines API Documenter should use when writing output files.
diff --git a/tools/api-markdown-documenter/src/LoggingConfiguration.ts b/tools/api-markdown-documenter/src/LoggingConfiguration.ts
index 0da26d92f2d0..fafa881344e4 100644
--- a/tools/api-markdown-documenter/src/LoggingConfiguration.ts
+++ b/tools/api-markdown-documenter/src/LoggingConfiguration.ts
@@ -6,7 +6,7 @@
import type { Logger } from "./Logging.js";
/**
- * Common base interface for configuration interfaces.
+ * Common base interface for configurations that take a logger.
*
* @public
*/
diff --git a/tools/api-markdown-documenter/src/LoggingOptions.ts b/tools/api-markdown-documenter/src/LoggingOptions.ts
new file mode 100644
index 000000000000..4aeb5ef1b154
--- /dev/null
+++ b/tools/api-markdown-documenter/src/LoggingOptions.ts
@@ -0,0 +1,26 @@
+/*!
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
+ * Licensed under the MIT License.
+ */
+
+import type { Logger } from "./Logging.js";
+
+/**
+ * Common base interface for configurations that take a logger.
+ *
+ * @public
+ */
+export interface LoggingOptions {
+ /**
+ * Optional receiver of system log data.
+ *
+ * @defaultValue {@link defaultConsoleLogger}
+ *
+ * @remarks
+ *
+ * A custom logger can be provided for customized policy, or for a target other than the console.
+ *
+ * If you wish to enable `verbose` logging, consider using {@link verboseConsoleLogger}.
+ */
+ readonly logger?: Logger;
+}
diff --git a/tools/api-markdown-documenter/src/RenderHtml.ts b/tools/api-markdown-documenter/src/RenderHtml.ts
index c02352240419..46074df76858 100644
--- a/tools/api-markdown-documenter/src/RenderHtml.ts
+++ b/tools/api-markdown-documenter/src/RenderHtml.ts
@@ -18,7 +18,7 @@ import { type RenderDocumentAsHtmlConfiguration, renderDocumentAsHtml } from "./
/**
* API Model HTML rendering options.
*
- * @public
+ * @alpha
*/
export interface RenderApiModelAsHtmlOptions
extends ApiItemTransformationOptions,
@@ -28,22 +28,6 @@ export interface RenderApiModelAsHtmlOptions
/**
* Renders the provided model and its contents, and writes each document to a file on disk.
*
- * @remarks
- *
- * Which API members get their own documents and which get written to the contents of their parent is
- * determined by {@link DocumentationSuiteConfiguration.documentBoundaries}.
- *
- * The file paths under which the files will be generated is determined by the provided output path and the
- * following configuration properties:
- *
- * - {@link DocumentationSuiteConfiguration.documentBoundaries}
- * - {@link DocumentationSuiteConfiguration.hierarchyBoundaries}
- *
- * @param transformConfig - Configuration for transforming API items into {@link DocumentationNode}s.
- * @param renderConfig - Configuration for rendering {@link DocumentNode}s as HTML.
- * @param fileSystemConfig - Configuration for writing document files to disk.
- * @param logger - Receiver of system log data. Default: {@link defaultConsoleLogger}.
- *
* @alpha
*/
export async function renderApiModelAsHtml(options: RenderApiModelAsHtmlOptions): Promise {
@@ -55,7 +39,7 @@ export async function renderApiModelAsHtml(options: RenderApiModelAsHtmlOptions)
/**
* Options for rendering {@link DocumentNode}s as HTML.
*
- * @public
+ * @alpha
*/
export interface RenderDocumentsAsHtmlOptions
extends RenderDocumentAsHtmlConfiguration,
@@ -66,14 +50,11 @@ export interface RenderDocumentsAsHtmlOptions
*
* @param documents - The documents to render. Each will be rendered to its own file on disk per
* {@link DocumentNode.documentPath} (relative to the provided output directory).
- * @param renderConfig - Configuration for rendering {@link DocumentNode}s as HTML.
- * @param fileSystemConfig - Configuration for writing document files to disk.
- * @param logger - Receiver of system log data. Default: {@link defaultConsoleLogger}.
*
* @alpha
*/
export async function renderDocumentsAsHtml(
- documents: DocumentNode[],
+ documents: readonly DocumentNode[],
options: RenderDocumentsAsHtmlOptions,
): Promise {
const { logger, newlineKind, outputDirectoryPath } = options;
diff --git a/tools/api-markdown-documenter/src/RenderMarkdown.ts b/tools/api-markdown-documenter/src/RenderMarkdown.ts
index 7277cd4b154f..555b73e6eb8e 100644
--- a/tools/api-markdown-documenter/src/RenderMarkdown.ts
+++ b/tools/api-markdown-documenter/src/RenderMarkdown.ts
@@ -28,22 +28,6 @@ export interface RenderApiModelAsMarkdownOptions
/**
* Renders the provided model and its contents, and writes each document to a file on disk.
*
- * @remarks
- *
- * Which API members get their own documents and which get written to the contents of their parent is
- * determined by {@link DocumentationSuiteConfiguration.documentBoundaries}.
- *
- * The file paths under which the files will be generated is determined by the provided output path and the
- * following configuration properties:
- *
- * - {@link DocumentationSuiteConfiguration.documentBoundaries}
- * - {@link DocumentationSuiteConfiguration.hierarchyBoundaries}
- *
- * @param transformConfig - Configuration for transforming API items into {@link DocumentationNode}s.
- * @param renderConfig - Configuration for rendering {@link DocumentNode}s as Markdown.
- * @param fileSystemConfig - Configuration for writing document files to disk.
- * @param logger - Receiver of system log data. Default: {@link defaultConsoleLogger}.
- *
* @public
*/
export async function renderApiModelAsMarkdown(
@@ -68,14 +52,11 @@ export interface RenderDocumentsAsMarkdownOptions
*
* @param documents - The documents to render. Each will be rendered to its own file on disk per
* {@link DocumentNode.documentPath} (relative to the provided output directory).
- * @param renderConfig - Configuration for rendering {@link DocumentNode}s as Markdown.
- * @param fileSystemConfig - Configuration for writing document files to disk.
- * @param logger - Receiver of system log data. Default: {@link defaultConsoleLogger}.
*
* @public
*/
export async function renderDocumentsAsMarkdown(
- documents: DocumentNode[],
+ documents: readonly DocumentNode[],
options: RenderDocumentsAsMarkdownOptions,
): Promise {
const { logger, newlineKind, outputDirectoryPath } = options;
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/ApiItemTransformUtilities.ts b/tools/api-markdown-documenter/src/api-item-transforms/ApiItemTransformUtilities.ts
index 97ddf511fe70..d9a68844b5fa 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/ApiItemTransformUtilities.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/ApiItemTransformUtilities.ts
@@ -3,24 +3,29 @@
* Licensed under the MIT License.
*/
-import * as Path from "node:path";
+import { strict as assert } from "node:assert";
import { type ApiItem, ApiItemKind, ReleaseTag } from "@microsoft/api-extractor-model";
import type { Heading } from "../Heading.js";
import type { Link } from "../Link.js";
import {
+ getApiItemKind,
+ getFilteredParent,
getFileSafeNameForApiItem,
getReleaseTag,
- getApiItemKind,
+ getValueOrDerived,
type ValidApiItemKind,
- getFilteredParent,
} from "../utilities/index.js";
-import type {
- ApiItemTransformationConfiguration,
- DocumentBoundaries,
- HierarchyBoundaries,
+import {
+ FolderDocumentPlacement,
+ HierarchyKind,
+ type ApiItemTransformationConfiguration,
+ type DocumentHierarchyConfiguration,
+ type FolderHierarchyConfiguration,
+ type DocumentationHierarchyConfiguration,
+ type HierarchyConfiguration,
} from "./configuration/index.js";
/**
@@ -28,33 +33,13 @@ import type {
*/
/**
- * Gets the nearest ancestor of the provided item that will have its own rendered document.
- *
- * @remarks
- * This can be useful for determining the file path the item will ultimately be rendered under,
- * as well as for generating links.
- *
- * @param apiItem - The API item for which we are generating a file path.
- * @param documentBoundaries - See {@link DocumentBoundaries}
+ * API item paired with its hierarchy config.
*/
-function getFirstAncestorWithOwnDocument(
- apiItem: ApiItem,
- documentBoundaries: DocumentBoundaries,
-): ApiItem {
- // Walk parentage until we reach an item kind that gets rendered to its own document.
- // That is the document we will target with the generated link.
- let hierarchyItem: ApiItem = apiItem;
- while (!doesItemRequireOwnDocument(hierarchyItem, documentBoundaries)) {
- const parent = getFilteredParent(hierarchyItem);
- if (parent === undefined) {
- throw new Error(
- `Walking hierarchy from "${apiItem.displayName}" does not converge on an item that is rendered ` +
- `to its own document.`,
- );
- }
- hierarchyItem = parent;
- }
- return hierarchyItem;
+export interface ApiItemWithHierarchy<
+ THierarchy extends DocumentationHierarchyConfiguration = DocumentationHierarchyConfiguration,
+> {
+ readonly apiItem: ApiItem;
+ readonly hierarchy: THierarchy;
}
/**
@@ -98,7 +83,7 @@ function getLinkUrlForApiItem(
config: ApiItemTransformationConfiguration,
): string {
const uriBase = config.getUriBaseOverrideForItem(apiItem) ?? config.uriRoot;
- let documentPath = getApiItemPath(apiItem, config).join("/");
+ let documentPath = getDocumentPathForApiItem(apiItem, config.hierarchy);
// Omit "index" file name from path generated in links.
// This can be considered an optimization in most cases, but some documentation systems also special-case
@@ -109,7 +94,7 @@ function getLinkUrlForApiItem(
// Don't bother with heading ID if we are linking to the root item of a document
let headingPostfix = "";
- if (!doesItemRequireOwnDocument(apiItem, config.documentBoundaries)) {
+ if (!doesItemRequireOwnDocument(apiItem, config.hierarchy)) {
const headingId = getHeadingIdForApiItem(apiItem, config);
headingPostfix = `#${headingId}`;
}
@@ -118,110 +103,173 @@ function getLinkUrlForApiItem(
}
/**
- * Gets the path to the document for the specified API item.
- *
- * @remarks
- *
- * In the case of an item that does not get rendered to its own document, this will point to the document
- * of the ancestor item under which the provided item will be rendered.
+ * Walks up the provided API item's hierarchy until and API item is found that matches the provided predicate.
*
- * The generated path is relative to {@link ApiItemTransformationConfiguration.uriRoot}.
+ * @returns The matching item, if one was found. Otherwise, `undefined`.
*
* @param apiItem - The API item for which we are generating a file path.
- * @param config - See {@link ApiItemTransformationConfiguration}.
+ * @param predicate - A function that returns `true` when the desired item is found.
*/
-export function getDocumentPathForApiItem(
+function findInHierarchy(
apiItem: ApiItem,
- config: ApiItemTransformationConfiguration,
-): string {
- const pathSegments = getApiItemPath(apiItem, config);
- return Path.join(...pathSegments);
+ predicate: (item: ApiItem) => boolean,
+): ApiItem | undefined {
+ let current: ApiItem | undefined = apiItem;
+ do {
+ if (predicate(current)) {
+ return current;
+ }
+ current = getFilteredParent(current);
+ } while (current !== undefined);
+
+ return undefined;
}
/**
- * Gets the path to the specified API item, represented as an ordered list of path segments.
+ * Gets the nearest ancestor of the provided item that will have its own rendered document.
+ *
+ * @remarks
+ * This can be useful for determining the file path the item will ultimately be rendered under,
+ * as well as for generating links.
*
* @param apiItem - The API item for which we are generating a file path.
- * @param config - See {@link ApiItemTransformationConfiguration}.
+ * @param hierarchyConfig - See {@link HierarchyConfiguration}
*/
-function getApiItemPath(apiItem: ApiItem, config: ApiItemTransformationConfiguration): string[] {
- const targetDocumentItem = getFirstAncestorWithOwnDocument(apiItem, config.documentBoundaries);
+function getFirstAncestorWithOwnDocument(
+ apiItem: ApiItem,
+ hierarchyConfig: Required,
+): ApiItemWithHierarchy {
+ // Walk parentage until we reach an item kind that gets rendered to its own document.
+ // That is the document we will target with the generated link.
+ const documentItem = findInHierarchy(apiItem, (item) =>
+ doesItemRequireOwnDocument(item, hierarchyConfig),
+ );
- const fileName = getDocumentNameForApiItem(apiItem, config);
+ if (documentItem === undefined) {
+ throw new Error(
+ `No ancestor of API item "${apiItem.displayName}" found that requires its own document.`,
+ );
+ }
- // Filtered ancestry in ascending order
- const documentAncestry = getAncestralHierarchy(targetDocumentItem, (hierarchyItem) =>
- doesItemGenerateHierarchy(hierarchyItem, config.hierarchyBoundaries),
- );
+ const documentItemKind = getApiItemKind(documentItem);
+ const documentHierarchyConfig = hierarchyConfig[documentItemKind];
+ assert(documentHierarchyConfig.kind !== HierarchyKind.Section);
- return [
- fileName,
- ...documentAncestry.map((hierarchyItem) =>
- getDocumentNameForApiItem(hierarchyItem, config),
- ),
- ].reverse();
+ return {
+ apiItem: documentItem,
+ hierarchy: documentHierarchyConfig,
+ };
}
/**
- * Gets the document name for the specified API item.
+ * Gets the path to the document for the specified API item.
*
* @remarks
*
- * In the case of an item that does not get rendered to its own document, this will be the file name for the document
+ * In the case of an item that does not get rendered to its own document, this will point to the document
* of the ancestor item under which the provided item will be rendered.
*
- * Note: This is strictly the name of the file, not a path to that file.
- * To get the path, use {@link getDocumentPathForApiItem}.
+ * The generated path is relative to {@link ApiItemTransformationConfiguration.uriRoot}.
*
* @param apiItem - The API item for which we are generating a file path.
- * @param config - See {@link ApiItemTransformationConfiguration}.
+ * @param hierarchyConfig - See {@link HierarchyConfiguration}.
*/
-function getDocumentNameForApiItem(
+export function getDocumentPathForApiItem(
apiItem: ApiItem,
- config: ApiItemTransformationConfiguration,
+ hierarchyConfig: HierarchyConfiguration,
): string {
- const targetDocumentItem = getFirstAncestorWithOwnDocument(apiItem, config.documentBoundaries);
+ const targetDocument = getFirstAncestorWithOwnDocument(apiItem, hierarchyConfig);
+
+ const documentName = getDocumentNameForItem(targetDocument, hierarchyConfig);
- let unscopedFileName = config.getFileNameForItem(targetDocumentItem);
+ const pathSegments: string[] = [];
- // For items of kinds other than `Model` or `Package` (which are handled specially file-system-wise),
- // append the item kind to disambiguate file names resulting from members whose names may conflict in a
- // casing-agnostic context (e.g. type "Foo" and function "foo").
+ // For the document itself, if its item creates folder-wise hierarchy, we need to refer to the hierarchy config
+ // to determine whether or not it should be placed inside or outside that folder.
if (
- targetDocumentItem.kind !== ApiItemKind.Model &&
- targetDocumentItem.kind !== ApiItemKind.Package
+ targetDocument.hierarchy.kind === HierarchyKind.Folder &&
+ targetDocument.hierarchy.documentPlacement === FolderDocumentPlacement.Inside
) {
- unscopedFileName = `${unscopedFileName}-${targetDocumentItem.kind.toLocaleLowerCase()}`;
+ const folderName = getFolderNameForItem(
+ targetDocument as ApiItemWithHierarchy,
+ hierarchyConfig,
+ );
+ pathSegments.push(`${folderName}/${documentName}`);
+ } else {
+ pathSegments.push(documentName);
}
- // Walk parentage up until we reach the first ancestor which injects directory hierarchy.
- // Qualify generated file name to ensure no conflicts within that directory.
- let hierarchyItem = getFilteredParent(targetDocumentItem);
- if (hierarchyItem === undefined) {
- // If there is no parent item, then we can just return the file name unmodified
- return unscopedFileName;
+ let currentItem: ApiItem | undefined = getFilteredParent(targetDocument.apiItem);
+ while (currentItem !== undefined) {
+ const currentItemKind = getApiItemKind(currentItem);
+ const currentItemHierarchy = hierarchyConfig[currentItemKind];
+ // Push path segments for all folders in the hierarchy
+ if (currentItemHierarchy.kind === HierarchyKind.Folder) {
+ const folderName = getFolderNameForItem(
+ { apiItem: currentItem, hierarchy: currentItemHierarchy },
+ hierarchyConfig,
+ );
+ pathSegments.push(folderName);
+ }
+ currentItem = getFilteredParent(currentItem);
}
- let scopedFileName = unscopedFileName;
- while (
- hierarchyItem.kind !== ApiItemKind.Model &&
- !doesItemGenerateHierarchy(hierarchyItem, config.hierarchyBoundaries)
- ) {
- const segmentName = config.getFileNameForItem(hierarchyItem);
- if (segmentName.length === 0) {
- throw new Error("Segment name must be non-empty.");
- }
+ // Hierarchy is built from the root down, so reverse the segments to get the correct file path ordering
+ pathSegments.reverse();
+
+ return pathSegments.join("/");
+}
- scopedFileName = `${segmentName}-${scopedFileName}`;
+function getDocumentNameForItem(
+ item: ApiItemWithHierarchy,
+ hierarchyConfig: HierarchyConfiguration,
+): string {
+ return (
+ getValueOrDerived(item.hierarchy.documentName, item.apiItem) ??
+ createQualifiedDocumentNameForApiItem(item.apiItem, hierarchyConfig)
+ );
+}
- const parent = getFilteredParent(hierarchyItem);
- if (parent === undefined) {
- break;
- }
- hierarchyItem = parent;
+function getFolderNameForItem(
+ item: ApiItemWithHierarchy,
+ hierarchyConfig: HierarchyConfiguration,
+): string {
+ return (
+ getValueOrDerived(item.hierarchy.folderName, item.apiItem) ??
+ // If no folder name is configured, use the system-default document name
+ createQualifiedDocumentNameForApiItem(item.apiItem, hierarchyConfig)
+ );
+}
+
+function createQualifiedDocumentNameForApiItem(
+ apiItem: ApiItem,
+ hierarchyConfig: HierarchyConfiguration,
+): string {
+ const apiItemKind = getApiItemKind(apiItem);
+ let documentName = getFileSafeNameForApiItem(apiItem);
+ if (apiItemKind !== ApiItemKind.Package) {
+ // If the item is not a package, append its "kind" to the document name to ensure uniqueness.
+ // Packages strictly live at the root of the document hierarchy (beneath the model), and only
+ // packages may appear there, so this information is redundant.
+ const postfix = apiItemKind.toLocaleLowerCase();
+ documentName = `${documentName}-${postfix}`;
}
- return scopedFileName;
+ // Walk up hierarchy until we find the nearest ancestor that yields folder hierarchy (or until we hit the model root).
+ // Qualify the document name with all ancestral items up to that point to ensure document name uniqueness.
+
+ let currentItem: ApiItem | undefined = getFilteredParent(apiItem);
+
+ while (
+ currentItem !== undefined &&
+ currentItem.kind !== "Model" &&
+ hierarchyConfig[getApiItemKind(currentItem)].kind !== HierarchyKind.Folder
+ ) {
+ documentName = `${getFileSafeNameForApiItem(currentItem)}-${documentName}`;
+ currentItem = getFilteredParent(currentItem);
+ }
+
+ return documentName;
}
/**
@@ -241,19 +289,22 @@ export function getHeadingForApiItem(
headingLevel?: number,
): Heading {
// Don't generate an ID for the root heading
- const id = doesItemRequireOwnDocument(apiItem, config.documentBoundaries)
+ const id = doesItemRequireOwnDocument(apiItem, config.hierarchy)
? undefined
: getHeadingIdForApiItem(apiItem, config);
+ const title = config.getHeadingTextForItem(apiItem);
return {
- title: config.getHeadingTextForItem(apiItem),
+ title,
id,
level: headingLevel,
};
}
+// TODO: this doesn't actually return `undefined` for own document. Verify and fix.
/**
- * Generates a unique heading ID for the provided API item.
+ * Generates a heading ID for the provided API item.
+ * Guaranteed to be unique within the document to which the API item is being rendered.
*
* @remarks
* Notes:
@@ -262,7 +313,7 @@ export function getHeadingForApiItem(
* Any links pointing to this item may simply link to the document; no heading ID is needed.
*
* - The resulting ID is context-dependent. In order to guarantee uniqueness, it will need to express
- * hierarchical information up to the ancester item whose document the specified item will ultimately be rendered to.
+ * hierarchical information up to the ancestor item whose document the specified item will ultimately be rendered to.
*
* @param apiItem - The API item for which the heading ID is being generated.
* @param config - See {@link ApiItemTransformationConfiguration}.
@@ -279,7 +330,7 @@ function getHeadingIdForApiItem(
// Walk parentage up until we reach the ancestor into whose document we're being rendered.
// Generate ID information for everything back to that point
let hierarchyItem = apiItem;
- while (!doesItemRequireOwnDocument(hierarchyItem, config.documentBoundaries)) {
+ while (!doesItemRequireOwnDocument(hierarchyItem, config.hierarchy)) {
const qualifiedName = getFileSafeNameForApiItem(hierarchyItem);
// Since we're walking up the tree, we'll build the string from the end for simplicity
@@ -298,159 +349,35 @@ function getHeadingIdForApiItem(
}
/**
- * Gets the ancestral hierarchy of the provided API item by walking up the parentage graph and emitting any items
- * matching the `includePredecate` until it reaches an item that matches the `breakPredecate`.
- *
- * @remarks Notes:
- *
- * - This will not include the provided item itself, even if it matches the `includePredecate`.
- *
- * - This will not include the item matching the `breakPredecate`, even if they match the `includePredecate`.
+ * Determines whether or not the specified API item is one that should be rendered to its own document
+ * (as opposed to being rendered to a section under some ancestor item's document).
*
- * @param apiItem - The API item whose ancestral hierarchy is being queried.
- * @param includePredecate - Predicate to determine which items in the hierarchy should be preserved in the
- * returned list. The provided API item will not be included in the output, even if it would be included by this.
- * @param breakPredicate - Predicate to determine when to break from the traversal and return.
- * The item matching this predicate will not be included, even if it would be included by `includePredicate`.
- *
- * @returns The list of matching ancestor items, provided in *ascending* order.
- */
-export function getAncestralHierarchy(
- apiItem: ApiItem,
- includePredecate: (apiItem: ApiItem) => boolean,
- breakPredicate?: (apiItem: ApiItem) => boolean,
-): ApiItem[] {
- const matches: ApiItem[] = [];
-
- let hierarchyItem: ApiItem | undefined = getFilteredParent(apiItem);
- while (
- hierarchyItem !== undefined &&
- (breakPredicate === undefined || !breakPredicate(hierarchyItem))
- ) {
- if (includePredecate(hierarchyItem)) {
- matches.push(hierarchyItem);
- }
- hierarchyItem = getFilteredParent(hierarchyItem);
- }
- return matches;
-}
-
-/**
- * Determines whether or not the specified API item kind is one that should be rendered to its own document.
- *
- * @remarks This is essentially a wrapper around {@link DocumentationSuiteConfiguration.documentBoundaries}, but also enforces
- * system-wide invariants.
- *
- * Namely...
- *
- * - `Model` and `Package` items are *always* rendered to their own documents, regardless of the specified boundaries.
- *
- * - `EntryPoint` items are *never* rendered to their own documents (as they are completely ignored by this system),
- * regardless of the specified boundaries.
- *
- * @param kind - The kind of API item.
- * @param documentBoundaries - See {@link DocumentBoundaries}
+ * @param apiItem - The API being queried.
+ * @param config - See {@link ApiItemTransformationConfiguration}.
*
- * @returns `true` if the item should be rendered to its own document. `false` otherwise.
+ * @public
*/
export function doesItemKindRequireOwnDocument(
- kind: ValidApiItemKind,
- documentBoundaries: DocumentBoundaries,
+ apiItemKind: ValidApiItemKind,
+ hierarchyConfig: Required,
): boolean {
- if (
- kind === ApiItemKind.EntryPoint ||
- kind === ApiItemKind.Model ||
- kind === ApiItemKind.Package
- ) {
- return true;
- }
- return documentBoundaries.includes(kind);
+ const hierarchy = hierarchyConfig[apiItemKind];
+ return hierarchy.kind !== HierarchyKind.Section;
}
/**
- * Determines whether or not the specified API item is one that should be rendered to its own document.
- *
- * @remarks
- *
- * This is essentially a wrapper around {@link DocumentationSuiteConfiguration.hierarchyBoundaries}, but also enforces
- * system-wide invariants.
- *
- * Namely...
- *
- * - `Package` items are *always* rendered to their own documents, regardless of the specified boundaries.
- *
- * - `EntryPoint` items are *never* rendered to their own documents (as they are completely ignored by this system),
- * regardless of the specified boundaries.
+ * Determines whether or not the specified API item is one that should be rendered to its own document
+ * (as opposed to being rendered to a section under some ancestor item's document).
*
* @param apiItem - The API being queried.
- * @param documentBoundaries - See {@link DocumentBoundaries}
- *
- * @public
+ * @param config - See {@link ApiItemTransformationConfiguration}.
*/
export function doesItemRequireOwnDocument(
apiItem: ApiItem,
- documentBoundaries: DocumentBoundaries,
-): boolean {
- return doesItemKindRequireOwnDocument(getApiItemKind(apiItem), documentBoundaries);
-}
-
-/**
- * Determines whether or not the specified API item kind is one that should generate directory-wise hierarchy
- * in the resulting documentation suite.
- * I.e. whether or not child item documents should be generated under a sub-directory adjacent to the item in question.
- *
- * @remarks
- *
- * This is essentially a wrapper around {@link DocumentationSuiteConfiguration.hierarchyBoundaries}, but also enforces
- * system-wide invariants.
- *
- * Namely...
- *
- * - `Package` items are *always* rendered to their own documents, regardless of the specified boundaries.
- *
- * - `EntryPoint` items are *never* rendered to their own documents (as they are completely ignored by this system),
- * regardless of the specified boundaries.
- *
- * @param kind - The kind of API item.
- * @param hierarchyBoundaries - See {@link HierarchyBoundaries}
- *
- * @returns `true` if the item should contribute to directory-wise hierarchy in the output. `false` otherwise.
- */
-function doesItemKindGenerateHierarchy(
- kind: ValidApiItemKind,
- hierarchyBoundaries: HierarchyBoundaries,
-): boolean {
- if (kind === ApiItemKind.Model) {
- // Model items always yield a document, and never introduce hierarchy
- return false;
- }
-
- if (kind === ApiItemKind.Package) {
- return true;
- }
- if (kind === ApiItemKind.EntryPoint) {
- // The same API item within a package can be included in multiple entry-points, so it doesn't make sense to
- // include it in generated hierarchy.
- return false;
- }
- return hierarchyBoundaries.includes(kind);
-}
-
-/**
- * Determines whether or not the specified API item is one that should generate directory-wise hierarchy
- * in the resulting documentation suite.
- * I.e. whether or not child item documents should be generated under a sub-directory adjacent to the item in question.
- *
- * @remarks This is based on the item's `kind`. See {@link doesItemKindGenerateHierarchy}.
- *
- * @param apiItem - The API item being queried.
- * @param hierarchyBoundaries - See {@link HierarchyBoundaries}
- */
-function doesItemGenerateHierarchy(
- apiItem: ApiItem,
- hierarchyBoundaries: HierarchyBoundaries,
+ hierarchyConfig: Required,
): boolean {
- return doesItemKindGenerateHierarchy(getApiItemKind(apiItem), hierarchyBoundaries);
+ const itemKind = getApiItemKind(apiItem);
+ return doesItemKindRequireOwnDocument(itemKind, hierarchyConfig);
}
/**
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/TransformApiItem.ts b/tools/api-markdown-documenter/src/api-item-transforms/TransformApiItem.ts
index f89c31efa94d..e93de7193b5d 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/TransformApiItem.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/TransformApiItem.ts
@@ -39,7 +39,7 @@ import { createBreadcrumbParagraph, wrapInSection } from "./helpers/index.js";
*
* This should only be called for API item kinds that are intended to be rendered to their own document
* (as opposed to being rendered to the same document as their parent) per the provided `config`
- * (see {@link DocumentationSuiteConfiguration.documentBoundaries}).
+ * (see {@link ApiItemTransformationConfiguration.hierarchy}).
*
* Also note that this should not be called for the following item kinds, which must be handled specially:
*
@@ -72,7 +72,7 @@ export function apiItemToDocument(
);
}
- if (!doesItemRequireOwnDocument(apiItem, config.documentBoundaries)) {
+ if (!doesItemRequireOwnDocument(apiItem, config.hierarchy)) {
throw new Error(
`"apiItemToDocument" called for an API item kind that is not intended to be rendered to its own document. Provided item kind: "${itemKind}".`,
);
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/TransformApiModel.ts b/tools/api-markdown-documenter/src/api-item-transforms/TransformApiModel.ts
index 947a420fa332..1f67c647606a 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/TransformApiModel.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/TransformApiModel.ts
@@ -15,7 +15,7 @@ import type { DocumentNode, SectionNode } from "../documentation-domain/index.js
import { doesItemRequireOwnDocument, shouldItemBeIncluded } from "./ApiItemTransformUtilities.js";
import { apiItemToDocument, apiItemToSections } from "./TransformApiItem.js";
-import { createDocument } from "./Utilities.js";
+import { checkForDuplicateDocumentPaths, createDocument } from "./Utilities.js";
import {
type ApiItemTransformationConfiguration,
type ApiItemTransformationOptions,
@@ -26,18 +26,7 @@ import { createBreadcrumbParagraph, createEntryPointList, wrapInSection } from "
/**
* Renders the provided model and its contents to a series of {@link DocumentNode}s.
*
- * @remarks
- *
- * Which API members get their own documents and which get written to the contents of their parent is
- * determined by {@link DocumentationSuiteConfiguration.documentBoundaries}.
- *
- * The generated nodes' {@link DocumentNode.documentPath}s are determined by the provided output path and the
- * following configuration properties:
- *
- * - {@link DocumentationSuiteConfiguration.documentBoundaries}
- * - {@link DocumentationSuiteConfiguration.hierarchyBoundaries}
- *
- * @param options - Options for transforming API items into {@link DocumentationNode}s.
+ * @param options - Configuration for transforming API items into {@link DocumentationNode}s.
*
* @public
*/
@@ -50,10 +39,10 @@ export function transformApiModel(options: ApiItemTransformationOptions): Docume
// If a package has multiple entry-points, it's possible for the same API item to appear under more than one
// entry-point (i.e., we are traversing a graph, rather than a tree).
// To avoid redundant computation, we will keep a ledger of which API items we have transformed.
- const documents: Map = new Map();
+ const documentsMap: Map = new Map();
// Always render Model document (this is the "root" of the generated documentation suite).
- documents.set(apiModel, createDocumentForApiModel(apiModel, config));
+ documentsMap.set(apiModel, createDocumentForApiModel(apiModel, config));
const packages = apiModel.packages;
@@ -88,42 +77,49 @@ export function transformApiModel(options: ApiItemTransformationOptions): Docume
const entryPoint = packageEntryPoints[0];
- documents.set(
+ documentsMap.set(
packageItem,
createDocumentForSingleEntryPointPackage(packageItem, entryPoint, config),
);
const packageDocumentItems = getDocumentItems(entryPoint, config);
for (const apiItem of packageDocumentItems) {
- if (!documents.has(apiItem)) {
- documents.set(apiItem, apiItemToDocument(apiItem, config));
+ if (!documentsMap.has(apiItem)) {
+ documentsMap.set(apiItem, apiItemToDocument(apiItem, config));
}
}
} else {
// If a package contains multiple entry-points, we will generate a separate document for each.
// The package-level document will enumerate the entry-points.
- documents.set(
+ documentsMap.set(
packageItem,
createDocumentForMultiEntryPointPackage(packageItem, packageEntryPoints, config),
);
for (const entryPoint of packageEntryPoints) {
- documents.set(entryPoint, createDocumentForApiEntryPoint(entryPoint, config));
+ documentsMap.set(entryPoint, createDocumentForApiEntryPoint(entryPoint, config));
const packageDocumentItems = getDocumentItems(entryPoint, config);
for (const apiItem of packageDocumentItems) {
- if (!documents.has(apiItem)) {
- documents.set(apiItem, apiItemToDocument(apiItem, config));
+ if (!documentsMap.has(apiItem)) {
+ documentsMap.set(apiItem, apiItemToDocument(apiItem, config));
}
}
}
}
}
- logger.success("API Model documents generated!");
+ const documents = [...documentsMap.values()];
+
+ try {
+ checkForDuplicateDocumentPaths(documents);
+ } catch (error: unknown) {
+ logger.warning((error as Error).message);
+ }
- return [...documents.values()];
+ logger.success("API Model documents generated!");
+ return documents;
}
/**
@@ -133,13 +129,13 @@ export function transformApiModel(options: ApiItemTransformationOptions): Docume
* @param config - See {@link ApiItemTransformationConfiguration}
*/
function getDocumentItems(apiItem: ApiItem, config: ApiItemTransformationConfiguration): ApiItem[] {
- const { documentBoundaries } = config;
+ const { hierarchy } = config;
const result: ApiItem[] = [];
for (const childItem of apiItem.members) {
if (
shouldItemBeIncluded(childItem, config) &&
- doesItemRequireOwnDocument(childItem, documentBoundaries)
+ doesItemRequireOwnDocument(childItem, hierarchy)
) {
result.push(childItem);
}
@@ -164,7 +160,7 @@ function createDocumentForApiModel(
logger.verbose(`Generating API Model document...`);
- // Note: We don't render the breadcrumb for Model document, as it is always the root of the file hierarchical
+ // Note: We don't render the breadcrumb for Model document, as it is always the root of the file hierarchy.
// Render body contents
const sections = transformations[ApiItemKind.Model](apiModel, config);
@@ -245,7 +241,7 @@ function createDocumentForMultiEntryPointPackage(
sections.push(wrapInSection([createBreadcrumbParagraph(apiPackage, config)]));
}
- // Render list of entry-points
+ // Render list of links to entry-points, each of which will get its own document.
const renderedEntryPointList = createEntryPointList(apiEntryPoints, config);
if (renderedEntryPointList !== undefined) {
sections.push(
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/Utilities.ts b/tools/api-markdown-documenter/src/api-item-transforms/Utilities.ts
index 015e93020ff2..c455eecc7aae 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/Utilities.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/Utilities.ts
@@ -33,15 +33,17 @@ export function createDocument(
sections: SectionNode[],
config: ApiItemTransformationConfiguration,
): DocumentNode {
+ const title = config.getHeadingTextForItem(documentItem);
+
// Wrap sections in a root section if top-level heading is requested.
const contents = config.includeTopLevelDocumentHeading
- ? [wrapInSection(sections, { title: config.getHeadingTextForItem(documentItem) })]
+ ? [wrapInSection(sections, { title })]
: sections;
return new DocumentNode({
apiItem: documentItem,
children: contents,
- documentPath: getDocumentPathForApiItem(documentItem, config),
+ documentPath: getDocumentPathForApiItem(documentItem, config.hierarchy),
});
}
@@ -95,3 +97,44 @@ function resolveSymbolicLink(
return getLinkForApiItem(resolvedReference, config);
}
+
+/**
+ * Checks for duplicate {@link DocumentNode.documentPath}s among the provided set of documents.
+ * @throws If any duplicates are found.
+ */
+export function checkForDuplicateDocumentPaths(documents: readonly DocumentNode[]): void {
+ const documentPathMap = new Map();
+ for (const document of documents) {
+ let entries = documentPathMap.get(document.documentPath);
+ if (entries === undefined) {
+ entries = [];
+ documentPathMap.set(document.documentPath, entries);
+ }
+ entries.push(document);
+ }
+
+ const duplicates = [...documentPathMap.entries()].filter(
+ ([, documentsUnderPath]) => documentsUnderPath.length > 1,
+ );
+
+ if (duplicates.length === 0) {
+ return;
+ }
+
+ const errorMessageLines = ["Duplicate output paths found among the generated documents:"];
+
+ for (const [documentPath, documentsUnderPath] of duplicates) {
+ errorMessageLines.push(`- ${documentPath}`);
+ for (const document of documentsUnderPath) {
+ const errorEntry = document.apiItem
+ ? `${document.apiItem.displayName} (${document.apiItem.kind})`
+ : "(No corresponding API item)";
+ errorMessageLines.push(` - ${errorEntry}`);
+ }
+ }
+ errorMessageLines.push(
+ "Check your configuration to ensure different API items do not result in the same output path.",
+ );
+
+ throw new Error(errorMessageLines.join("\n"));
+}
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/configuration/Configuration.ts b/tools/api-markdown-documenter/src/api-item-transforms/configuration/Configuration.ts
index 4694bd1991b5..b5dfe46f0730 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/configuration/Configuration.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/configuration/Configuration.ts
@@ -12,6 +12,7 @@ import { createSectionForApiItem } from "../default-implementations/index.js";
import {
type DocumentationSuiteConfiguration,
+ type DocumentationSuiteOptions,
getDocumentationSuiteConfigurationWithDefaults,
} from "./DocumentationSuite.js";
import {
@@ -89,7 +90,7 @@ export interface ApiItemTransformationConfiguration
*/
export interface ApiItemTransformationOptions
extends ApiItemTransformationConfigurationBase,
- Partial,
+ DocumentationSuiteOptions,
LoggingConfiguration {
/**
* Optional overrides for the default transformations.
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/configuration/DocumentationSuite.ts b/tools/api-markdown-documenter/src/api-item-transforms/configuration/DocumentationSuite.ts
index b0982296cbc2..b12b3e8f5f54 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/configuration/DocumentationSuite.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/configuration/DocumentationSuite.ts
@@ -12,82 +12,19 @@ import {
} from "@microsoft/api-extractor-model";
import {
- type ApiMemberKind,
getApiItemKind,
getConciseSignature,
- getFileSafeNameForApiItem,
- getFileSafeNameForApiItemName,
getReleaseTag,
getSingleLineExcerptText,
- getUnscopedPackageName,
isDeprecated,
} from "../../utilities/index.js";
-/**
- * List of item kinds for which separate documents should be generated.
- * Items specified will be rendered to their own documents.
- * Items not specified will be rendered into their parent's contents.
- *
- * @remarks Note that `Model` and `Package` items will *always* have separate documents generated for them, even if
- * not specified.
- *
- * Also note that `EntryPoint` items will always be ignored by the system, even if specified here.
- *
- * @example
- *
- * A configuration like the following:
- *
- * ```typescript
- * ...
- * documentBoundaries: [
- * ApiItemKind.Namespace,
- * ],
- * ...
- * ```
- *
- * will result in separate documents being generated for `Namespace` items, but will not for other item kinds
- * (`Classes`, `Interfaces`, etc.).
- *
- * @public
- */
-export type DocumentBoundaries = ApiMemberKind[];
-
-/**
- * List of item kinds for which sub-directories will be generated, and under which child item documents will be created.
- * If not specified for an item kind, any children of items of that kind will be generated adjacent to the parent.
- *
- * @remarks Note that `Package` items will *always* have separate documents generated for them, even if
- * not specified.
- *
- * @example
- *
- * A configuration like the following:
- *
- * ```typescript
- * ...
- * hierarchyBoundaries: [
- * ApiItemKind.Namespace,
- * ],
- * ...
- * ```
- *
- * will result in documents rendered for children of the `Namespace` to be generated in a subdirectory named after
- * the `Namespace` item.
- *
- * So for some namespace `Foo` with children `Bar` and `Baz` (assuming `Bar` and `Baz` are item kinds matching
- * the configured {@link DocumentationSuiteConfiguration.documentBoundaries}), the resulting file structure would look like the
- * following:
- *
- * ```
- * foo.md
- * foo
- * | bar.md
- * | baz.md
- * ```
- *
- * @public
- */
-export type HierarchyBoundaries = ApiMemberKind[];
+import {
+ getHierarchyOptionsWithDefaults,
+ type HierarchyConfiguration,
+ type HierarchyOptions,
+} from "./Hierarchy.js";
+import { trimTrailingSemicolon } from "./Utilities.js";
/**
* Options for configuring the documentation suite generated by the API Item -\> Documentation Domain transformation.
@@ -110,46 +47,14 @@ export interface DocumentationSuiteConfiguration {
*
* @defaultValue `true`
*
- * @remarks Note: `Model` items will never have a breadcrumb rendered, even if this is specfied.
+ * @remarks Note: `Model` items will never have a breadcrumb rendered, even if this is specified.
*/
readonly includeBreadcrumb: boolean;
/**
- * See {@link DocumentBoundaries}.
- *
- * @defaultValue {@link DefaultDocumentationSuiteOptions.defaultDocumentBoundaries}
+ * {@link HierarchyConfiguration} to use for the provided API item.
*/
- readonly documentBoundaries: DocumentBoundaries;
-
- /**
- * See {@link HierarchyBoundaries}.
- *
- * @defaultValue {@link DefaultDocumentationSuiteOptions.defaultHierarchyBoundaries}
- */
- readonly hierarchyBoundaries: HierarchyBoundaries;
-
- /**
- * Generate a file name for the provided `ApiItem`.
- *
- * @remarks
- *
- * Note that this is not the complete file name, but the "leaf" component of the final file name.
- * Additional prefixes and suffixes will be appended to ensure file name collisions do not occur.
- *
- * This also does not contain the file extension.
- *
- * @example
- *
- * We are given a class API item "Bar" in package "Foo", and this returns "foo".
- * The final file name in this case might be something like "foo-bar-class".
- *
- * @param apiItem - The API item for which the pre-modification file name is being generated.
- *
- * @returns The pre-modification file name for the API item.
- *
- * @defaultValue {@link DefaultDocumentationSuiteOptions.defaultGetFileNameForItem}
- */
- readonly getFileNameForItem: (apiItem: ApiItem) => string;
+ readonly hierarchy: HierarchyConfiguration;
/**
* Optionally provide an override for the URI base used in links generated for the provided `ApiItem`.
@@ -174,7 +79,7 @@ export interface DocumentationSuiteConfiguration {
*
* @returns The heading title for the API item.
*
- * @defaultValue {@link DefaultDocumentationSuiteOptions.defaultGetHeadingTextForItem}
+ * @defaultValue {@link DefaultDocumentationSuiteConfiguration.defaultGetHeadingTextForItem}
*/
readonly getHeadingTextForItem: (apiItem: ApiItem) => string;
@@ -185,7 +90,7 @@ export interface DocumentationSuiteConfiguration {
*
* @returns The text to use in the link to the API item.
*
- * @defaultValue {@link DefaultDocumentationSuiteOptions.defaultGetLinkTextForItem}
+ * @defaultValue {@link DefaultDocumentationSuiteConfiguration.defaultGetLinkTextForItem}
*/
readonly getLinkTextForItem: (apiItem: ApiItem) => string;
@@ -196,7 +101,7 @@ export interface DocumentationSuiteConfiguration {
*
* @returns The list of "alert" strings to display.
*
- * @defaultValue {@link DefaultDocumentationSuiteOptions.defaultGetAlertsForItem}
+ * @defaultValue {@link DefaultDocumentationSuiteConfiguration.defaultGetAlertsForItem}
*/
readonly getAlertsForItem: (apiItem: ApiItem) => string[];
@@ -234,66 +139,31 @@ export interface DocumentationSuiteConfiguration {
* releaseLevel: ReleaseTag.Beta
* ```
*/
- readonly minimumReleaseLevel: Omit;
+ readonly minimumReleaseLevel?: Exclude;
}
/**
- * Contains a list of default documentation transformations, used by {@link DocumentationSuiteConfiguration}.
+ * Complete configuration documentation suite generation via the API Item -\> Documentation Domain transformation.
*
* @public
*/
-// eslint-disable-next-line @typescript-eslint/no-namespace
-export namespace DefaultDocumentationSuiteOptions {
+export type DocumentationSuiteOptions = Omit<
+ Partial,
+ "hierarchy"
+> & {
/**
- * Default {@link DocumentationSuiteConfiguration.documentBoundaries}.
- *
- * Generates separate documents for the following API item kinds:
- *
- * - Class
- *
- * - Interface
- *
- * - Namespace
+ * {@inheritDoc DocumentationSuiteConfiguration.hierarchy}
*/
- export const defaultDocumentBoundaries: ApiMemberKind[] = [
- ApiItemKind.Class,
- ApiItemKind.Interface,
- ApiItemKind.Namespace,
- ];
-
- /**
- * Default {@link DocumentationSuiteConfiguration.hierarchyBoundaries}.
- *
- * Creates sub-directories for the following API item kinds:
- *
- * - Namespace
- */
- export const defaultHierarchyBoundaries: ApiMemberKind[] = [ApiItemKind.Namespace];
-
- /**
- * Default {@link DocumentationSuiteConfiguration.getFileNameForItem}.
- *
- * Uses the item's qualified API name, but is handled differently for the following items:
- *
- * - Model: Uses "index".
- *
- * - Package: Uses the unscoped package name.
- */
- export function defaultGetFileNameForItem(apiItem: ApiItem): string {
- const itemKind = getApiItemKind(apiItem);
- switch (itemKind) {
- case ApiItemKind.Model: {
- return "index";
- }
- case ApiItemKind.Package: {
- return getFileSafeNameForApiItemName(getUnscopedPackageName(apiItem as ApiPackage));
- }
- default: {
- return getFileSafeNameForApiItem(apiItem);
- }
- }
- }
+ readonly hierarchy?: HierarchyOptions;
+};
+/**
+ * Contains a list of default {@link DocumentationSuiteConfiguration} functions.
+ *
+ * @public
+ */
+// eslint-disable-next-line @typescript-eslint/no-namespace
+export namespace DefaultDocumentationSuiteConfiguration {
/**
* Default {@link DocumentationSuiteConfiguration.getUriBaseOverrideForItem}.
*
@@ -306,11 +176,15 @@ export namespace DefaultDocumentationSuiteOptions {
/**
* Default {@link DocumentationSuiteConfiguration.getHeadingTextForItem}.
*
- * Uses the item's `displayName`, except for `Model` items, in which case the text "API Overview" is displayed.
+ * Uses the item's qualified API name, but is handled differently for the following items:
+ *
+ * - CallSignature, ConstructSignature, IndexSignature: Uses a cleaned up variation on the type signature.
+ *
+ * - Model: Uses "API Overview".
*/
export function defaultGetHeadingTextForItem(apiItem: ApiItem): string {
- const itemKind = getApiItemKind(apiItem);
- switch (itemKind) {
+ const kind = getApiItemKind(apiItem);
+ switch (kind) {
case ApiItemKind.Model: {
return "API Overview";
}
@@ -356,7 +230,7 @@ export namespace DefaultDocumentationSuiteOptions {
}
/**
- * Default {@link DocumentationSuiteConfiguration.getHeadingTextForItem}.
+ * Default {@link DocumentationSuiteConfiguration.getAlertsForItem}.
*
* Generates alerts for the following tags, if found:
*
@@ -394,17 +268,15 @@ export namespace DefaultDocumentationSuiteOptions {
/**
* Default {@link DocumentationSuiteConfiguration}.
*/
-const defaultDocumentationSuiteConfiguration: DocumentationSuiteConfiguration = {
+const defaultDocumentationSuiteConfiguration: Omit = {
includeTopLevelDocumentHeading: true,
includeBreadcrumb: true,
- documentBoundaries: DefaultDocumentationSuiteOptions.defaultDocumentBoundaries,
- hierarchyBoundaries: DefaultDocumentationSuiteOptions.defaultHierarchyBoundaries,
- getFileNameForItem: DefaultDocumentationSuiteOptions.defaultGetFileNameForItem,
- getUriBaseOverrideForItem: DefaultDocumentationSuiteOptions.defaultGetUriBaseOverrideForItem,
- getHeadingTextForItem: DefaultDocumentationSuiteOptions.defaultGetHeadingTextForItem,
- getLinkTextForItem: DefaultDocumentationSuiteOptions.defaultGetLinkTextForItem,
- getAlertsForItem: DefaultDocumentationSuiteOptions.defaultGetAlertsForItem,
- skipPackage: DefaultDocumentationSuiteOptions.defaultSkipPackage,
+ getUriBaseOverrideForItem:
+ DefaultDocumentationSuiteConfiguration.defaultGetUriBaseOverrideForItem,
+ getHeadingTextForItem: DefaultDocumentationSuiteConfiguration.defaultGetHeadingTextForItem,
+ getLinkTextForItem: DefaultDocumentationSuiteConfiguration.defaultGetLinkTextForItem,
+ getAlertsForItem: DefaultDocumentationSuiteConfiguration.defaultGetAlertsForItem,
+ skipPackage: DefaultDocumentationSuiteConfiguration.defaultSkipPackage,
minimumReleaseLevel: ReleaseTag.Internal, // Include everything in the input model
};
@@ -413,20 +285,12 @@ const defaultDocumentationSuiteConfiguration: DocumentationSuiteConfiguration =
* in the remainder with the documented defaults.
*/
export function getDocumentationSuiteConfigurationWithDefaults(
- options?: Partial,
+ options: DocumentationSuiteOptions,
): DocumentationSuiteConfiguration {
+ const hierarchy: HierarchyConfiguration = getHierarchyOptionsWithDefaults(options.hierarchy);
return {
...defaultDocumentationSuiteConfiguration,
...options,
+ hierarchy,
};
}
-
-/**
- * Trims a trailing semicolon from the provided text, if the text contains one.
- */
-function trimTrailingSemicolon(text: string): string {
- if (text.endsWith(";")) {
- return text.slice(0, text.length - 1);
- }
- return text;
-}
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/configuration/Hierarchy.ts b/tools/api-markdown-documenter/src/api-item-transforms/configuration/Hierarchy.ts
new file mode 100644
index 000000000000..1d4052eaea41
--- /dev/null
+++ b/tools/api-markdown-documenter/src/api-item-transforms/configuration/Hierarchy.ts
@@ -0,0 +1,398 @@
+/*!
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
+ * Licensed under the MIT License.
+ */
+
+import { type ApiItem, ApiItemKind, type ApiPackage } from "@microsoft/api-extractor-model";
+
+import {
+ getApiItemKind,
+ type ValidApiItemKind,
+ type Mutable,
+ getFileSafeNameForApiItemName,
+ getUnscopedPackageName,
+} from "../../utilities/index.js";
+
+/**
+ * Kind of documentation suite hierarchy.
+ *
+ * @public
+ */
+export enum HierarchyKind {
+ /**
+ * The API item gets a section under the document representing an ancestor of the API item.
+ */
+ Section = "section",
+
+ /**
+ * The API item gets its own document, in the folder for an ancestor of the API item.
+ */
+ Document = "document",
+
+ /**
+ * The API item gets its own document, and generates folder hierarchy for all descendent API items.
+ */
+ Folder = "folder",
+}
+
+/**
+ * {@link DocumentationHierarchyConfiguration} base interface.
+ *
+ * @remarks
+ * Not intended for external use.
+ * Only exists to share common properties between hierarchy configuration types.
+ *
+ * @public
+ */
+export interface DocumentationHierarchyConfigurationBase {
+ /**
+ * {@inheritDoc HierarchyKind}
+ */
+ readonly kind: THierarchyKind;
+}
+
+/**
+ * The corresponding API item will be placed in a section under the document representing an ancestor of the API item.
+ *
+ * @public
+ */
+export type SectionHierarchyConfiguration =
+ DocumentationHierarchyConfigurationBase;
+
+/**
+ * {@link HierarchyKind.Document} hierarchy configuration properties.
+ *
+ * @public
+ */
+export interface DocumentHierarchyProperties {
+ /**
+ * Document name to use for the API item.
+ * @remarks `undefined` indicates that the system default should be used.
+ */
+ readonly documentName?: string | undefined | ((apiItem: ApiItem) => string | undefined);
+}
+
+/**
+ * The corresponding API item will get its own document, in the folder for an ancestor of the API item.
+ *
+ * @public
+ */
+export interface DocumentHierarchyConfiguration
+ extends DocumentationHierarchyConfigurationBase,
+ DocumentHierarchyProperties {}
+
+/**
+ * Placement of the API item's document relative to its generated folder.
+ *
+ * @remarks Used by {@link FolderHierarchyProperties}.
+ *
+ * @public
+ */
+export enum FolderDocumentPlacement {
+ /**
+ * The document is placed inside its folder.
+ */
+ Inside = "inside",
+
+ /**
+ * The document is placed outside (adjacent to) its folder.
+ */
+ Outside = "outside",
+}
+
+/**
+ * {@link HierarchyKind.Document} hierarchy configuration properties.
+ *
+ * @public
+ */
+export interface FolderHierarchyProperties extends DocumentHierarchyProperties {
+ /**
+ * Placement of the API item's document relative to its generated folder.
+ * `inside`: The document is placed inside its folder.
+ * `outside`: The document is placed outside (adjacent to) its folder.
+ */
+ readonly documentPlacement:
+ | FolderDocumentPlacement
+ | ((apiItem: ApiItem) => FolderDocumentPlacement);
+
+ /**
+ * Folder name to use for the API item.
+ * @remarks `undefined` indicates that the system default should be used.
+ */
+ readonly folderName: string | undefined | ((apiItem: ApiItem) => string | undefined);
+}
+
+/**
+ * The corresponding API item will get its own document, in the folder for an ancestor of the API item.
+ *
+ * @public
+ */
+export interface FolderHierarchyConfiguration
+ extends DocumentationHierarchyConfigurationBase,
+ FolderHierarchyProperties {}
+
+/**
+ * API item hierarchy configuration.
+ *
+ * @public
+ */
+export type DocumentationHierarchyConfiguration =
+ | SectionHierarchyConfiguration
+ | DocumentHierarchyConfiguration
+ | FolderHierarchyConfiguration;
+
+/**
+ * Default {@link SectionHierarchyConfiguration} used by the system.
+ */
+export const defaultSectionHierarchyConfig: SectionHierarchyConfiguration = {
+ kind: HierarchyKind.Section,
+};
+
+/**
+ * Default {@link DocumentHierarchyProperties.documentName} for non-folder hierarchy documents.
+ *
+ * @remarks
+ * Uses the item's scoped and qualified API name, but is handled differently for the following items:
+ *
+ * - Model: "index"
+ *
+ * - Package: Use the unscoped package name.
+ */
+function defaultDocumentName(apiItem: ApiItem): string | undefined {
+ const kind = getApiItemKind(apiItem);
+ switch (kind) {
+ case ApiItemKind.Model: {
+ return "index";
+ }
+ case ApiItemKind.Package: {
+ return getFileSafeNameForApiItemName(getUnscopedPackageName(apiItem as ApiPackage));
+ }
+ default: {
+ // Let the system generate a unique name that accounts for folder hierarchy.
+ return undefined;
+ }
+ }
+}
+
+/**
+ * Default {@link DocumentHierarchyConfiguration} used by the system.
+ */
+export const defaultDocumentHierarchyConfig: DocumentHierarchyConfiguration = {
+ kind: HierarchyKind.Document,
+ documentName: defaultDocumentName,
+};
+
+/**
+ * Default {@link DocumentHierarchyProperties.documentName} for non-folder hierarchy documents.
+ *
+ * @remarks
+ * Uses the item's scoped and qualified API name, but is handled differently for the following items:
+ *
+ * - Package: Use the unscoped package name.
+ */
+function defaultFolderName(apiItem: ApiItem): string | undefined {
+ const kind = getApiItemKind(apiItem);
+ switch (kind) {
+ case ApiItemKind.Package: {
+ return getFileSafeNameForApiItemName(getUnscopedPackageName(apiItem as ApiPackage));
+ }
+ default: {
+ // Let the system generate a unique name that accounts for folder hierarchy.
+ return undefined;
+ }
+ }
+}
+
+/**
+ * Default {@link FolderHierarchyConfiguration} used by the system.
+ */
+export const defaultFolderHierarchyConfig: FolderHierarchyConfiguration = {
+ kind: HierarchyKind.Folder,
+ documentName: defaultDocumentName,
+ documentPlacement: FolderDocumentPlacement.Outside, // TODO
+ // documentName: "index", // Documents for items that get their own folder are always named "index" by default.
+ folderName: defaultFolderName,
+};
+
+/**
+ * Complete hierarchy configuration by API item kind.
+ *
+ * @public
+ */
+export type HierarchyConfiguration = {
+ /**
+ * Hierarchy configuration for the API item kind.
+ */
+ [Kind in Exclude<
+ ValidApiItemKind,
+ ApiItemKind.Model | ApiItemKind.EntryPoint | ApiItemKind.Package
+ >]: DocumentationHierarchyConfiguration;
+} & {
+ /**
+ * Hierarchy configuration for the `Model` API item kind.
+ *
+ * @remarks
+ * Always its own document. Never introduces folder hierarchy.
+ * This is an important invariant, as it ensures that there is always at least one document in the output.
+ */
+ [ApiItemKind.Model]: DocumentHierarchyConfiguration;
+
+ /**
+ * Hierarchy configuration for the `Package` API item kind.
+ *
+ * @remarks Must be either a folder or document hierarchy configuration.
+ *
+ * @privateRemarks
+ * TODO: Allow all hierarchy configurations for packages.
+ * There isn't a real reason to restrict this, except the way the code is currently structured.
+ */
+ [ApiItemKind.Package]: DocumentHierarchyConfiguration | FolderHierarchyConfiguration;
+
+ /**
+ * Hierarchy configuration for the `EntryPoint` API item kind.
+ *
+ * @remarks
+ * Always its own document, adjacent to the package document.
+ * When a package only has a single entrypoint, this is skipped entirely and entrypoint children are rendered directly to the package document.
+ *
+ * @privateRemarks
+ * TODO: Allow all hierarchy configurations for packages.
+ * There isn't a real reason to restrict this, except the way the code is currently structured.
+ */
+ [ApiItemKind.EntryPoint]: DocumentHierarchyConfiguration;
+};
+
+/**
+ * Input hierarchy options by API item kind.
+ *
+ * @remarks
+ * For each option, you may provide 1 of 2 options:
+ *
+ * - {@link HierarchyKind}: the default configuration for that kind will be used.
+ *
+ * - A complete {@link DocumentationHierarchyConfiguration} to be used in place of any default.
+ *
+ * @public
+ */
+export type HierarchyOptions = {
+ /**
+ * Hierarchy configuration for the API item kind.
+ */
+ [Kind in Exclude<
+ ValidApiItemKind,
+ ApiItemKind.Model | ApiItemKind.EntryPoint | ApiItemKind.Package
+ >]?: HierarchyKind | DocumentationHierarchyConfiguration;
+} & {
+ /**
+ * Hierarchy configuration for the `Model` API item kind.
+ *
+ * @remarks
+ * Always its own document. Never introduces folder hierarchy.
+ * This is an important invariant, as it ensures that there is always at least one document in the output.
+ */
+ [ApiItemKind.Model]?: HierarchyKind.Document | DocumentHierarchyConfiguration;
+
+ /**
+ * Hierarchy configuration for the `Package` API item kind.
+ *
+ * @remarks Must be either a folder or document hierarchy configuration.
+ *
+ * @privateRemarks
+ * TODO: Allow all hierarchy configurations for packages.
+ * There isn't a real reason to restrict this, except the way the code is currently structured.
+ */
+ [ApiItemKind.Package]?:
+ | HierarchyKind.Document
+ | HierarchyKind.Folder
+ | DocumentHierarchyConfiguration
+ | FolderHierarchyConfiguration;
+
+ /**
+ * Hierarchy configuration for the `EntryPoint` API item kind.
+ *
+ * @remarks
+ * Always its own document, adjacent to the package document.
+ * When a package only has a single entrypoint, this is skipped entirely and entrypoint children are rendered directly to the package document.
+ *
+ * @privateRemarks
+ * TODO: Allow all hierarchy configurations for packages.
+ * There isn't a real reason to restrict this, except the way the code is currently structured.
+ */
+ [ApiItemKind.EntryPoint]?: HierarchyKind.Document | DocumentHierarchyConfiguration;
+};
+
+/**
+ * Default {@link HierarchyConfiguration}.
+ */
+const defaultHierarchyConfiguration: HierarchyConfiguration = {
+ [ApiItemKind.Model]: {
+ kind: HierarchyKind.Document,
+ documentName: "index",
+ },
+
+ // Items that introduce folder hierarchy:
+ [ApiItemKind.Namespace]: defaultFolderHierarchyConfig,
+ [ApiItemKind.Package]: defaultFolderHierarchyConfig,
+
+ // Items that get their own document, but do not introduce folder hierarchy:
+ [ApiItemKind.Class]: defaultDocumentHierarchyConfig,
+ [ApiItemKind.Enum]: defaultSectionHierarchyConfig, // TODO: DocumentHierarchyConfig
+ [ApiItemKind.EntryPoint]: defaultDocumentHierarchyConfig,
+ [ApiItemKind.Interface]: defaultDocumentHierarchyConfig,
+ [ApiItemKind.TypeAlias]: defaultSectionHierarchyConfig, // TODO: DocumentHierarchyConfig
+
+ // Items that get a section under the document representing an ancestor of the API item:
+ [ApiItemKind.CallSignature]: defaultSectionHierarchyConfig,
+ [ApiItemKind.Constructor]: defaultSectionHierarchyConfig,
+ [ApiItemKind.ConstructSignature]: defaultSectionHierarchyConfig,
+ [ApiItemKind.EnumMember]: defaultSectionHierarchyConfig,
+ [ApiItemKind.Function]: defaultSectionHierarchyConfig,
+ [ApiItemKind.IndexSignature]: defaultSectionHierarchyConfig,
+ [ApiItemKind.Method]: defaultSectionHierarchyConfig,
+ [ApiItemKind.MethodSignature]: defaultSectionHierarchyConfig,
+ [ApiItemKind.Property]: defaultSectionHierarchyConfig,
+ [ApiItemKind.PropertySignature]: defaultSectionHierarchyConfig,
+ [ApiItemKind.Variable]: defaultSectionHierarchyConfig,
+};
+
+/**
+ * Maps an input option to a complete {@link DocumentationHierarchyConfiguration}.
+ */
+function mapHierarchyOption(
+ option: HierarchyKind | DocumentationHierarchyConfiguration,
+): DocumentationHierarchyConfiguration {
+ switch (option) {
+ case HierarchyKind.Section: {
+ return defaultSectionHierarchyConfig;
+ }
+ case HierarchyKind.Document: {
+ return defaultDocumentHierarchyConfig;
+ }
+ case HierarchyKind.Folder: {
+ return defaultFolderHierarchyConfig;
+ }
+ default: {
+ return option;
+ }
+ }
+}
+
+/**
+ * Gets a complete {@link HierarchyConfiguration} using the provided partial configuration, and filling
+ * in the remainder with defaults.
+ */
+export function getHierarchyOptionsWithDefaults(
+ options?: HierarchyOptions,
+): HierarchyConfiguration {
+ if (options === undefined) {
+ return defaultHierarchyConfiguration;
+ }
+
+ const result: Mutable = { ...defaultHierarchyConfiguration };
+ for (const [key, maybeValue] of Object.entries(options)) {
+ if (maybeValue !== undefined) {
+ result[key] = mapHierarchyOption(maybeValue);
+ }
+ }
+ return result;
+}
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/configuration/Utilities.ts b/tools/api-markdown-documenter/src/api-item-transforms/configuration/Utilities.ts
new file mode 100644
index 000000000000..66ebb0cea6e2
--- /dev/null
+++ b/tools/api-markdown-documenter/src/api-item-transforms/configuration/Utilities.ts
@@ -0,0 +1,14 @@
+/*!
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
+ * Licensed under the MIT License.
+ */
+
+/**
+ * Trims a trailing semicolon from the provided text, if the text contains one.
+ */
+export function trimTrailingSemicolon(text: string): string {
+ if (text.endsWith(";")) {
+ return text.slice(0, text.length - 1);
+ }
+ return text;
+}
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/configuration/index.ts b/tools/api-markdown-documenter/src/api-item-transforms/configuration/index.ts
index 60506fdfc0cf..908eda9902f7 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/configuration/index.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/configuration/index.ts
@@ -9,15 +9,31 @@ export {
type ApiItemTransformationOptions,
getApiItemTransformationConfigurationWithDefaults,
} from "./Configuration.js";
-export type {
- // Consumers should not use this, it exists externally for documentation purposes only.
- DefaultDocumentationSuiteOptions,
- DocumentBoundaries,
- DocumentationSuiteConfiguration,
- HierarchyBoundaries,
+export {
+ type DocumentationSuiteConfiguration,
+ type DefaultDocumentationSuiteConfiguration,
+ type DocumentationSuiteOptions,
+ getDocumentationSuiteConfigurationWithDefaults as getDocumentationSuiteOptionsWithDefaults,
} from "./DocumentationSuite.js";
-export type {
- ApiItemTransformations,
- TransformApiItemWithChildren,
- TransformApiItemWithoutChildren,
+export {
+ type DocumentationHierarchyConfiguration,
+ type DocumentationHierarchyConfigurationBase,
+ type DocumentHierarchyConfiguration,
+ type DocumentHierarchyProperties,
+ FolderDocumentPlacement,
+ type FolderHierarchyConfiguration,
+ type FolderHierarchyProperties,
+ defaultDocumentHierarchyConfig,
+ defaultFolderHierarchyConfig,
+ defaultSectionHierarchyConfig,
+ type HierarchyConfiguration,
+ type HierarchyOptions,
+ HierarchyKind,
+ type SectionHierarchyConfiguration,
+} from "./Hierarchy.js";
+export {
+ type ApiItemTransformations,
+ getApiItemTransformationsWithDefaults,
+ type TransformApiItemWithChildren,
+ type TransformApiItemWithoutChildren,
} from "./Transformations.js";
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/CreateSectionForApiItem.ts b/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/CreateSectionForApiItem.ts
index 7198e0a8fdb3..599d3f00de83 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/CreateSectionForApiItem.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/CreateSectionForApiItem.ts
@@ -116,7 +116,7 @@ export function createSectionForApiItem(
// Add heading to top of section only if this is being rendered to a parent item.
// Document items have their headings handled specially.
- return doesItemRequireOwnDocument(apiItem, config.documentBoundaries)
+ return doesItemRequireOwnDocument(apiItem, config.hierarchy)
? sections
: [wrapInSection(sections, getHeadingForApiItem(apiItem, config))];
}
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiClass.ts b/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiClass.ts
index 084a7c94de1f..f00d1675978f 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiClass.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiClass.ts
@@ -50,7 +50,7 @@ import { createChildDetailsSection, createMemberTables } from "../helpers/index.
*
* - index-signatures
*
- * Details (for any types not rendered to their own documents - see {@link DocumentationSuiteConfiguration.documentBoundaries})
+ * Details (for any types not rendered to their own documents - see {@link ApiItemTransformationOptions.hierarchy})
*
* - constructors
*
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiInterface.ts b/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiInterface.ts
index 5c62c274d4eb..8e8b060c851e 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiInterface.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiInterface.ts
@@ -39,7 +39,7 @@ import { createChildDetailsSection, createMemberTables } from "../helpers/index.
*
* - index-signatures
*
- * Details (for any types not rendered to their own documents - see {@link DocumentationSuiteConfiguration.documentBoundaries})
+ * Details (for any types not rendered to their own documents - see {@link ApiItemTransformationOptions.hierarchy})
*
* - constructor-signatures
*
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiModuleLike.ts b/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiModuleLike.ts
index bc505758b32f..4561fe6319f0 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiModuleLike.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/default-implementations/TransformApiModuleLike.ts
@@ -43,7 +43,7 @@ import { createChildDetailsSection, createMemberTables } from "../helpers/index.
*
* - namespaces
*
- * Details (for any types not rendered to their own documents - see {@link DocumentationSuiteConfiguration.documentBoundaries})
+ * Details (for any types not rendered to their own documents - see {@link ApiItemTransformationOptions.hierarchy})
*
* - interfaces
*
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/helpers/Helpers.ts b/tools/api-markdown-documenter/src/api-item-transforms/helpers/Helpers.ts
index bbc9b513012d..d33a1c23002e 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/helpers/Helpers.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/helpers/Helpers.ts
@@ -29,6 +29,7 @@ import {
} from "@microsoft/tsdoc";
import type { Heading } from "../../Heading.js";
+import type { Link } from "../../Link.js";
import type { Logger } from "../../Logging.js";
import {
type DocumentationNode,
@@ -55,17 +56,14 @@ import {
getDeprecatedBlock,
getExampleBlocks,
getReturnsBlock,
+ getApiItemKind,
type ValidApiItemKind,
+ getFilteredParent,
} from "../../utilities/index.js";
-import {
- doesItemKindRequireOwnDocument,
- doesItemRequireOwnDocument,
- getAncestralHierarchy,
- getLinkForApiItem,
-} from "../ApiItemTransformUtilities.js";
+import { doesItemKindRequireOwnDocument, getLinkForApiItem } from "../ApiItemTransformUtilities.js";
import { transformTsdocSection } from "../TsdocNodeTransforms.js";
import { getTsdocNodeTransformationOptions } from "../Utilities.js";
-import type { ApiItemTransformationConfiguration } from "../configuration/index.js";
+import { HierarchyKind, type ApiItemTransformationConfiguration } from "../configuration/index.js";
import { createParametersSummaryTable, createTypeParametersSummaryTable } from "./TableHelpers.js";
@@ -381,10 +379,10 @@ export function createExcerptSpanWithHyperlinks(
* Renders a simple navigation breadcrumb.
*
* @remarks Displayed as a ` > `-separated list of hierarchical page links.
- * 1 for each element in the provided item's ancestory for which a separate document is generated
- * (see {@link DocumentBoundaries}).
+ * 1 for each element in the provided item's ancestry for which a separate document is generated
+ * (see {@link HierarchyConfiguration}).
*
- * @param apiItem - The API item whose ancestory will be used to generate the breadcrumb.
+ * @param apiItem - The API item whose ancestry will be used to generate the breadcrumb.
* @param config - See {@link ApiItemTransformationConfiguration}.
*
* @public
@@ -393,23 +391,32 @@ export function createBreadcrumbParagraph(
apiItem: ApiItem,
config: ApiItemTransformationConfiguration,
): ParagraphNode {
- // Get ordered ancestry of document items
- const ancestry = getAncestralHierarchy(apiItem, (hierarchyItem) =>
- doesItemRequireOwnDocument(hierarchyItem, config.documentBoundaries),
- ).reverse(); // Reverse from ascending to descending order
+ // #region Get ordered ancestry of document items
- const breadcrumbSeparator = new PlainTextNode(" > ");
+ const breadcrumbLinks: Link[] = [getLinkForApiItem(apiItem, config)];
- const links = ancestry.map((hierarchyItem) =>
- LinkNode.createFromPlainTextLink(getLinkForApiItem(hierarchyItem, config)),
- );
+ let currentItem: ApiItem | undefined = getFilteredParent(apiItem);
+ while (currentItem !== undefined) {
+ const currentItemKind = getApiItemKind(currentItem);
+ const currentItemHierarchy = config.hierarchy[currentItemKind];
+ // Push breadcrumb entries for all files in the hierarchy.
+ if (currentItemHierarchy.kind !== HierarchyKind.Section) {
+ breadcrumbLinks.push(getLinkForApiItem(currentItem, config));
+ }
- // Add link for current document item
- links.push(LinkNode.createFromPlainTextLink(getLinkForApiItem(apiItem, config)));
+ currentItem = getFilteredParent(currentItem);
+ }
+ breadcrumbLinks.reverse(); // Items are populated in ascending order, but we want them in descending order.
+
+ // #endregion
+
+ const renderedLinks = breadcrumbLinks.map((link) => LinkNode.createFromPlainTextLink(link));
+
+ const breadcrumbSeparator = new PlainTextNode(" > ");
// Inject breadcrumb separator between each link
const contents: DocumentationNode[] = injectSeparator(
- links,
+ renderedLinks,
breadcrumbSeparator,
);
@@ -997,7 +1004,7 @@ export function createChildDetailsSection(
// (i.e. it does not get rendered to its own document).
// Also only render the section if it actually has contents to render (to avoid empty headings).
if (
- !doesItemKindRequireOwnDocument(childItem.itemKind, config.documentBoundaries) &&
+ !doesItemKindRequireOwnDocument(childItem.itemKind, config.hierarchy) &&
childItem.items.length > 0
) {
const childContents: DocumentationNode[] = [];
diff --git a/tools/api-markdown-documenter/src/api-item-transforms/index.ts b/tools/api-markdown-documenter/src/api-item-transforms/index.ts
index e09cef05e057..f455ef0cfec9 100644
--- a/tools/api-markdown-documenter/src/api-item-transforms/index.ts
+++ b/tools/api-markdown-documenter/src/api-item-transforms/index.ts
@@ -9,6 +9,7 @@
export {
doesItemRequireOwnDocument,
+ doesItemKindRequireOwnDocument,
filterItems,
getHeadingForApiItem,
getLinkForApiItem,
@@ -19,11 +20,24 @@ export {
type ApiItemTransformationConfigurationBase,
type ApiItemTransformationOptions,
type ApiItemTransformations,
- type DefaultDocumentationSuiteOptions,
+ type DefaultDocumentationSuiteConfiguration,
+ type DocumentHierarchyConfiguration,
+ type DocumentHierarchyProperties,
type DocumentationSuiteConfiguration,
- type DocumentBoundaries,
+ type DocumentationSuiteOptions,
+ FolderDocumentPlacement,
+ type FolderHierarchyConfiguration,
+ type FolderHierarchyProperties,
getApiItemTransformationConfigurationWithDefaults,
- type HierarchyBoundaries,
+ defaultDocumentHierarchyConfig,
+ defaultFolderHierarchyConfig,
+ defaultSectionHierarchyConfig,
+ type DocumentationHierarchyConfiguration,
+ type DocumentationHierarchyConfigurationBase,
+ HierarchyKind,
+ type HierarchyConfiguration,
+ type HierarchyOptions,
+ type SectionHierarchyConfiguration,
type TransformApiItemWithChildren,
type TransformApiItemWithoutChildren,
} from "./configuration/index.js";
@@ -43,3 +57,4 @@ export {
export { transformTsdocNode } from "./TsdocNodeTransforms.js";
export { apiItemToDocument, apiItemToSections } from "./TransformApiItem.js";
export { transformApiModel } from "./TransformApiModel.js";
+export { checkForDuplicateDocumentPaths } from "./Utilities.js";
diff --git a/tools/api-markdown-documenter/src/index.ts b/tools/api-markdown-documenter/src/index.ts
index a359780dc5c1..2e6fd38cc746 100644
--- a/tools/api-markdown-documenter/src/index.ts
+++ b/tools/api-markdown-documenter/src/index.ts
@@ -18,12 +18,22 @@ export {
type ApiItemTransformationConfigurationBase,
type ApiItemTransformationOptions,
type ApiItemTransformations,
- type DefaultDocumentationSuiteOptions,
+ type DefaultDocumentationSuiteConfiguration,
+ type DocumentHierarchyConfiguration,
+ type DocumentHierarchyProperties,
type DocumentationSuiteConfiguration,
- type DocumentBoundaries,
+ type DocumentationSuiteOptions,
+ FolderDocumentPlacement,
+ type FolderHierarchyConfiguration,
+ type FolderHierarchyProperties,
// TODO: remove this once utility APIs can be called with partial configs.
getApiItemTransformationConfigurationWithDefaults,
- type HierarchyBoundaries,
+ type DocumentationHierarchyConfiguration,
+ type DocumentationHierarchyConfigurationBase,
+ HierarchyKind,
+ type HierarchyConfiguration,
+ type HierarchyOptions,
+ type SectionHierarchyConfiguration,
type TransformApiItemWithChildren,
type TransformApiItemWithoutChildren,
transformApiModel,
@@ -68,13 +78,13 @@ export {
type Logger,
verboseConsoleLogger,
} from "./Logging.js";
-export {
- type ApiFunctionLike,
- type ApiMemberKind,
- type ApiModifier,
- type ApiModuleLike,
- type ApiSignatureLike,
- type ValidApiItemKind,
+export type {
+ ApiFunctionLike,
+ ApiMemberKind,
+ ApiModifier,
+ ApiModuleLike,
+ ApiSignatureLike,
+ ValidApiItemKind,
} from "./utilities/index.js";
// #region Scoped exports
diff --git a/tools/api-markdown-documenter/src/test/EndToEndTestUtilities.ts b/tools/api-markdown-documenter/src/test/EndToEndTestUtilities.ts
new file mode 100644
index 000000000000..0238b87c77ed
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/EndToEndTestUtilities.ts
@@ -0,0 +1,169 @@
+/*!
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
+ * Licensed under the MIT License.
+ */
+
+import Path from "node:path";
+import { fileURLToPath } from "node:url";
+
+import { ApiItemKind } from "@microsoft/api-extractor-model";
+import { FileSystem } from "@rushstack/node-core-library";
+import { expect } from "chai";
+import { compare } from "dir-compare";
+
+import { defaultFolderHierarchyConfig } from "../api-item-transforms/index.js";
+import {
+ FolderDocumentPlacement,
+ HierarchyKind,
+ type HierarchyOptions,
+ type FolderHierarchyConfiguration,
+} from "../index.js";
+
+const dirname = Path.dirname(fileURLToPath(import.meta.url));
+
+/**
+ * Temp directory under which all tests that generate files will output their contents.
+ */
+export const testTemporaryDirectoryPath = Path.resolve(dirname, "test_temp");
+
+/**
+ * Snapshot directory to which generated test data will be copied.
+ * @remarks Relative to lib/test
+ */
+export const snapshotsDirectoryPath = Path.resolve(dirname, "..", "..", "src", "test", "snapshots");
+
+/**
+ * Directory containing the end-to-end test models.
+ * @remarks Relative to lib/test
+ */
+export const testDataDirectoryPath = Path.resolve(dirname, "..", "..", "src", "test", "test-data");
+
+/**
+ * Test hierarchy configs
+ *
+ * @privateRemarks TODO: Formalize and export some of these as pre-canned solutions?
+ */
+// eslint-disable-next-line @typescript-eslint/no-namespace
+export namespace HierarchyConfigs {
+ const outsideFolderConfig: FolderHierarchyConfiguration = {
+ kind: HierarchyKind.Folder,
+ documentPlacement: FolderDocumentPlacement.Outside,
+ folderName: defaultFolderHierarchyConfig.folderName,
+ };
+
+ const insideFolderConfig: FolderHierarchyConfiguration = {
+ kind: HierarchyKind.Folder,
+ documentPlacement: FolderDocumentPlacement.Inside,
+ documentName: "index",
+ folderName: defaultFolderHierarchyConfig.folderName,
+ };
+
+ /**
+ * "Flat" hierarchy: Packages get their own documents, and all descendent API items are rendered as sections under that document.
+ * @remarks Results in a small number of documents, but can lead to relatively large documents.
+ */
+ export const flat: HierarchyOptions = {
+ [ApiItemKind.Package]: HierarchyKind.Document,
+
+ [ApiItemKind.CallSignature]: HierarchyKind.Section,
+ [ApiItemKind.Class]: HierarchyKind.Section,
+ [ApiItemKind.Constructor]: HierarchyKind.Section,
+ [ApiItemKind.ConstructSignature]: HierarchyKind.Section,
+ [ApiItemKind.Enum]: HierarchyKind.Section,
+ [ApiItemKind.EnumMember]: HierarchyKind.Section,
+ [ApiItemKind.Function]: HierarchyKind.Section,
+ [ApiItemKind.IndexSignature]: HierarchyKind.Section,
+ [ApiItemKind.Interface]: HierarchyKind.Section,
+ [ApiItemKind.Method]: HierarchyKind.Section,
+ [ApiItemKind.MethodSignature]: HierarchyKind.Section,
+ [ApiItemKind.Namespace]: HierarchyKind.Section,
+ [ApiItemKind.Property]: HierarchyKind.Section,
+ [ApiItemKind.PropertySignature]: HierarchyKind.Section,
+ [ApiItemKind.TypeAlias]: HierarchyKind.Section,
+ [ApiItemKind.Variable]: HierarchyKind.Section,
+ };
+
+ /**
+ * "Sparse" hierarchy: Packages yield folder hierarchy, and all descendent items get their own document under that folder.
+ * @remarks Leads to many documents, but each document is likely to be relatively small.
+ */
+ export const sparse: HierarchyOptions = {
+ [ApiItemKind.Package]: outsideFolderConfig,
+
+ [ApiItemKind.CallSignature]: HierarchyKind.Document,
+ [ApiItemKind.Class]: HierarchyKind.Document,
+ [ApiItemKind.Constructor]: HierarchyKind.Document,
+ [ApiItemKind.ConstructSignature]: HierarchyKind.Document,
+ [ApiItemKind.Enum]: HierarchyKind.Document,
+ [ApiItemKind.EnumMember]: HierarchyKind.Document,
+ [ApiItemKind.Function]: HierarchyKind.Document,
+ [ApiItemKind.IndexSignature]: HierarchyKind.Document,
+ [ApiItemKind.Interface]: HierarchyKind.Document,
+ [ApiItemKind.Method]: HierarchyKind.Document,
+ [ApiItemKind.MethodSignature]: HierarchyKind.Document,
+ [ApiItemKind.Namespace]: HierarchyKind.Document,
+ [ApiItemKind.Property]: HierarchyKind.Document,
+ [ApiItemKind.PropertySignature]: HierarchyKind.Document,
+ [ApiItemKind.TypeAlias]: HierarchyKind.Document,
+ [ApiItemKind.Variable]: HierarchyKind.Document,
+ };
+
+ /**
+ * "Deep" hierarchy: All "parent" API items generate hierarchy. All other items are rendered as documents under their parent hierarchy.
+ * @remarks Leads to many documents, but each document is likely to be relatively small.
+ */
+ export const deep: HierarchyOptions = {
+ // Items that introduce folder hierarchy:
+ [ApiItemKind.Namespace]: insideFolderConfig,
+ [ApiItemKind.Package]: insideFolderConfig,
+ [ApiItemKind.Class]: insideFolderConfig,
+ [ApiItemKind.Enum]: insideFolderConfig,
+ [ApiItemKind.Interface]: insideFolderConfig,
+ [ApiItemKind.TypeAlias]: insideFolderConfig,
+
+ // Items that get their own document, but do not introduce folder hierarchy:
+ [ApiItemKind.CallSignature]: HierarchyKind.Document,
+ [ApiItemKind.Constructor]: HierarchyKind.Document,
+ [ApiItemKind.ConstructSignature]: HierarchyKind.Document,
+ [ApiItemKind.EnumMember]: HierarchyKind.Document,
+ [ApiItemKind.Function]: HierarchyKind.Document,
+ [ApiItemKind.IndexSignature]: HierarchyKind.Document,
+ [ApiItemKind.Method]: HierarchyKind.Document,
+ [ApiItemKind.MethodSignature]: HierarchyKind.Document,
+ [ApiItemKind.Property]: HierarchyKind.Document,
+ [ApiItemKind.PropertySignature]: HierarchyKind.Document,
+ [ApiItemKind.Variable]: HierarchyKind.Document,
+ };
+}
+
+/**
+ * Compares "expected" to "actual" documentation test suite output.
+ * Succeeds the Mocha test if the directory contents match.
+ * Otherwise, fails the test and copies the new output to the snapshot directory so the developer can view the diff
+ * in git, and check in the changes if appropriate.
+ *
+ * @param snapshotDirectoryPath - Resolved path to the directory containing the checked-in assets for the test.
+ * Represents the "expected" test output.
+ *
+ * @param temporaryDirectoryPath - Resolved path to the directory containing the freshly generated test output.
+ * Represents the "actual" test output.
+ */
+export async function compareDocumentationSuiteSnapshot(
+ snapshotDirectoryPath: string,
+ temporaryDirectoryPath: string,
+): Promise {
+ // Verify against expected contents
+ const result = await compare(temporaryDirectoryPath, snapshotDirectoryPath, {
+ compareContent: true,
+ });
+
+ if (!result.same) {
+ await FileSystem.ensureEmptyFolderAsync(snapshotDirectoryPath);
+ await FileSystem.copyFilesAsync({
+ sourcePath: temporaryDirectoryPath,
+ destinationPath: snapshotDirectoryPath,
+ });
+
+ expect.fail(`Snapshot test encountered ${result.differencesFiles} file diffs.`);
+ }
+}
diff --git a/tools/api-markdown-documenter/src/test/EndToEndTests.ts b/tools/api-markdown-documenter/src/test/EndToEndTests.ts
deleted file mode 100644
index ec2c8f93c78f..000000000000
--- a/tools/api-markdown-documenter/src/test/EndToEndTests.ts
+++ /dev/null
@@ -1,233 +0,0 @@
-/*!
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
- * Licensed under the MIT License.
- */
-
-import Path from "node:path";
-
-import type { ApiModel } from "@microsoft/api-extractor-model";
-import { FileSystem } from "@rushstack/node-core-library";
-import { expect } from "chai";
-import { compare } from "dir-compare";
-import type { Suite } from "mocha";
-
-import { loadModel } from "../LoadModel.js";
-import {
- transformApiModel,
- type ApiItemTransformationOptions,
-} from "../api-item-transforms/index.js";
-import type { DocumentNode } from "../documentation-domain/index.js";
-
-/**
- * End-to-end snapshot test configuration.
- *
- * @remarks Generates a test suite with a test for each combination of API Model and test configuration.
- */
-export interface EndToEndSuiteConfig {
- /**
- * Name of the outer test suite.
- */
- readonly suiteName: string;
-
- /**
- * Path to the directory where all suite test output will be written for comparison against checked-in snapshots.
- *
- * @remarks
- * Individual tests' output will be written to `/<{@link ApiModelTestOptions.modelName}>/<{@link ApiItemTransformationTestOptions.configName}>/<{@link RenderTestOptions.configName}>`.
- */
- readonly temporaryOutputDirectoryPath: string;
-
- /**
- * Path to the directory containing the checked-in snapshots for comparison in this suite.
- *
- * @remarks
- * Individual tests' output will be written to `/<{@link ApiModelTestOptions.modelName}>/<{@link ApiItemTransformationTestOptions.configName}>/<{@link RenderTestOptions.configName}>`.
- */
- readonly snapshotsDirectoryPath: string;
-
- /**
- * The end-to-end test scenario to run against the API model.
- * Writes the output to the specified directory for snapshot comparison.
- */
- render(
- document: DocumentNode,
- renderConfig: TRenderConfig,
- outputDirectoryPath: string,
- ): Promise;
-
- /**
- * The models to test.
- */
- readonly apiModels: readonly ApiModelTestOptions[];
-
- /**
- * Test configurations to run against each API Model.
- */
- readonly testConfigs: readonly EndToEndTestConfig[];
-}
-
-/**
- * API Model test options for a test.
- */
-export interface ApiModelTestOptions {
- /**
- * Name of the API Model being tested.
- */
- readonly modelName: string;
-
- /**
- * Path to the directory containing the API Model.
- */
- readonly directoryPath: string;
-}
-
-/**
- * API Item transformation options for a test.
- */
-export interface EndToEndTestConfig {
- /**
- * Test name
- */
- readonly testName: string;
-
- /**
- * The transformation configuration to use.
- */
- readonly transformConfig: Omit;
-
- /**
- * Render configuration.
- */
- readonly renderConfig: TRenderConfig;
-}
-
-/**
- * Generates a test suite that performs end-to-end tests for each test
- * configuration x API Model combination.
- *
- * @remarks
- * The generated test suite will include the following checks:
- *
- * - Basic smoke-test validation of the API Item transformation step, ensuring unique document paths.
- *
- * - Snapshot test comparing the final rendered output against checked-in snapshots.
- */
-export function endToEndTests(
- suiteConfig: EndToEndSuiteConfig,
-): Suite {
- return describe(suiteConfig.suiteName, () => {
- for (const apiModelTestConfig of suiteConfig.apiModels) {
- const { modelName, directoryPath: modelDirectoryPath } = apiModelTestConfig;
- describe(modelName, () => {
- let apiModel: ApiModel;
- before(async () => {
- apiModel = await loadModel({ modelDirectoryPath });
- });
-
- for (const testConfig of suiteConfig.testConfigs) {
- const {
- testName,
- transformConfig: partialTransformConfig,
- renderConfig,
- } = testConfig;
-
- const testOutputPath = Path.join(modelName, testName);
- const temporaryDirectoryPath = Path.resolve(
- suiteConfig.temporaryOutputDirectoryPath,
- testOutputPath,
- );
- const snapshotDirectoryPath = Path.resolve(
- suiteConfig.snapshotsDirectoryPath,
- testOutputPath,
- );
-
- describe(testName, () => {
- let apiItemTransformConfig: ApiItemTransformationOptions;
- before(async () => {
- apiItemTransformConfig = {
- ...partialTransformConfig,
- apiModel,
- };
- });
-
- // Run a sanity check to ensure that the suite did not generate multiple documents with the same
- // output file path. This either indicates a bug in the system, or an bad configuration.
- it("Ensure no duplicate file paths", () => {
- const documents = transformApiModel(apiItemTransformConfig);
-
- const pathMap = new Map();
- for (const document of documents) {
- if (pathMap.has(document.documentPath)) {
- expect.fail(
- `Rendering generated multiple documents to be rendered to the same file path.`,
- );
- } else {
- pathMap.set(document.documentPath, document);
- }
- }
- });
-
- // Perform actual output snapshot comparison test against checked-in test collateral.
- it("Snapshot test", async () => {
- // Ensure the output temp and snapshots directories exists (will create an empty ones if they don't).
- await FileSystem.ensureFolderAsync(temporaryDirectoryPath);
- await FileSystem.ensureFolderAsync(snapshotDirectoryPath);
-
- // Clear any existing test_temp data
- await FileSystem.ensureEmptyFolderAsync(temporaryDirectoryPath);
-
- const documents = transformApiModel(apiItemTransformConfig);
-
- await Promise.all(
- documents.map(async (document) =>
- suiteConfig.render(
- document,
- renderConfig,
- temporaryDirectoryPath,
- ),
- ),
- );
-
- await compareDocumentationSuiteSnapshot(
- snapshotDirectoryPath,
- temporaryDirectoryPath,
- );
- });
- });
- }
- });
- }
- });
-}
-
-/**
- * Compares "expected" to "actual" documentation test suite output.
- * Succeeds the Mocha test if the directory contents match.
- * Otherwise, fails the test and copies the new output to the snapshot directory so the developer can view the diff
- * in git, and check in the changes if appropriate.
- *
- * @param snapshotDirectoryPath - Resolved path to the directory containing the checked-in assets for the test.
- * Represents the "expected" test output.
- *
- * @param temporaryDirectoryPath - Resolved path to the directory containing the freshly generated test output.
- * Represents the "actual" test output.
- */
-async function compareDocumentationSuiteSnapshot(
- snapshotDirectoryPath: string,
- temporaryDirectoryPath: string,
-): Promise {
- // Verify against expected contents
- const result = await compare(temporaryDirectoryPath, snapshotDirectoryPath, {
- compareContent: true,
- });
-
- if (!result.same) {
- await FileSystem.ensureEmptyFolderAsync(snapshotDirectoryPath);
- await FileSystem.copyFilesAsync({
- sourcePath: temporaryDirectoryPath,
- destinationPath: snapshotDirectoryPath,
- });
-
- expect.fail(`Snapshot test encountered ${result.differencesFiles} file diffs.`);
- }
-}
diff --git a/tools/api-markdown-documenter/src/test/HtmlEndToEnd.test.ts b/tools/api-markdown-documenter/src/test/HtmlEndToEnd.test.ts
index 3131207f7587..e87a4253b31f 100644
--- a/tools/api-markdown-documenter/src/test/HtmlEndToEnd.test.ts
+++ b/tools/api-markdown-documenter/src/test/HtmlEndToEnd.test.ts
@@ -3,141 +3,113 @@
* Licensed under the MIT License.
*/
-import * as Path from "node:path";
-import { fileURLToPath } from "node:url";
+import Path from "node:path";
-import { ApiItemKind, ReleaseTag } from "@microsoft/api-extractor-model";
-import { FileSystem, NewlineKind } from "@rushstack/node-core-library";
+import { ReleaseTag, type ApiModel } from "@microsoft/api-extractor-model";
-import type { DocumentNode } from "../documentation-domain/index.js";
-import {
- type RenderDocumentAsHtmlConfiguration,
- renderDocumentAsHtml,
-} from "../renderers/index.js";
+import { HtmlRenderer, loadModel } from "../index.js";
import {
- endToEndTests,
- type ApiModelTestOptions,
- type EndToEndTestConfig,
-} from "./EndToEndTests.js";
-
-const dirname = Path.dirname(fileURLToPath(import.meta.url));
+ compareDocumentationSuiteSnapshot,
+ HierarchyConfigs,
+ snapshotsDirectoryPath as snapshotsDirectoryPathBase,
+ testDataDirectoryPath,
+ testTemporaryDirectoryPath as testTemporaryDirectoryPathBase,
+} from "./EndToEndTestUtilities.js";
/**
* Temp directory under which all tests that generate files will output their contents.
*/
-const testTemporaryDirectoryPath = Path.resolve(dirname, "test_temp", "html");
+const testTemporaryDirectoryPath = Path.resolve(testTemporaryDirectoryPathBase, "html");
/**
* Snapshot directory to which generated test data will be copied.
* Relative to lib/test
*/
-const snapshotsDirectoryPath = Path.resolve(
- dirname,
- "..",
- "..",
- "src",
- "test",
- "snapshots",
- "html",
-);
-
-// Relative to lib/test
-const testDataDirectoryPath = Path.resolve(dirname, "..", "..", "src", "test", "test-data");
-
-const apiModels: ApiModelTestOptions[] = [
- {
- modelName: "simple-suite-test",
- directoryPath: Path.resolve(testDataDirectoryPath, "simple-suite-test"),
- },
- // TODO: add other models
-];
-
-const testConfigs: EndToEndTestConfig[] = [
- /**
- * A sample "flat" configuration, which renders every item kind under a package to the package parent document.
- */
- {
- testName: "default-config",
- transformConfig: {
+const snapshotsDirectoryPath = Path.resolve(snapshotsDirectoryPathBase, "html");
+
+const apiModels: string[] = ["simple-suite-test"];
+
+const testConfigs = new Map<
+ string,
+ Omit
+>([
+ [
+ "default-config",
+ {
uriRoot: ".",
},
- renderConfig: {},
- },
-
- /**
- * A sample "flat" configuration, which renders every item kind under a package to the package parent document.
- */
- {
- testName: "flat-config",
- transformConfig: {
+ ],
+
+ // A sample "flat" configuration, which renders every item kind under a package to the package parent document.
+ [
+ "flat-config",
+ {
uriRoot: "docs",
includeBreadcrumb: true,
includeTopLevelDocumentHeading: false,
- documentBoundaries: [], // Render everything to package documents
- hierarchyBoundaries: [], // No additional hierarchy beyond the package level
+ hierarchy: HierarchyConfigs.flat,
minimumReleaseLevel: ReleaseTag.Beta, // Only include `@public` and `beta` items in the docs suite
},
- renderConfig: {},
- },
-
- /**
- * A sample "sparse" configuration, which renders every item kind to its own document.
- */
- {
- testName: "sparse-config",
- transformConfig: {
+ ],
+
+ // A sample "sparse" configuration, which renders every item kind to its own document.
+ [
+ "sparse-config",
+ {
uriRoot: "docs",
includeBreadcrumb: false,
includeTopLevelDocumentHeading: true,
- // Render everything to its own document
- documentBoundaries: [
- ApiItemKind.CallSignature,
- ApiItemKind.Class,
- ApiItemKind.ConstructSignature,
- ApiItemKind.Constructor,
- ApiItemKind.Enum,
- ApiItemKind.EnumMember,
- ApiItemKind.Function,
- ApiItemKind.IndexSignature,
- ApiItemKind.Interface,
- ApiItemKind.Method,
- ApiItemKind.MethodSignature,
- ApiItemKind.Namespace,
- ApiItemKind.Property,
- ApiItemKind.PropertySignature,
- ApiItemKind.TypeAlias,
- ApiItemKind.Variable,
- ],
- hierarchyBoundaries: [], // No additional hierarchy beyond the package level
+ hierarchy: HierarchyConfigs.sparse,
minimumReleaseLevel: ReleaseTag.Public, // Only include `@public` items in the docs suite
skipPackage: (apiPackage) => apiPackage.name === "test-suite-b", // Skip test-suite-b package
- },
- renderConfig: {
startingHeadingLevel: 2,
},
- },
-];
-
-async function renderDocumentToFile(
- document: DocumentNode,
- renderConfig: RenderDocumentAsHtmlConfiguration,
- outputDirectoryPath: string,
-): Promise {
- const renderedDocument = renderDocumentAsHtml(document, renderConfig);
-
- const filePath = Path.join(outputDirectoryPath, `${document.documentPath}.html`);
- await FileSystem.writeFileAsync(filePath, renderedDocument, {
- convertLineEndings: NewlineKind.Lf,
- ensureFolderExists: true,
- });
-}
-
-endToEndTests({
- suiteName: "Markdown End-to-End Tests",
- temporaryOutputDirectoryPath: testTemporaryDirectoryPath,
- snapshotsDirectoryPath,
- render: renderDocumentToFile,
- apiModels,
- testConfigs,
+ ],
+
+ // A sample "deep" configuration.
+ // All "parent" API items generate hierarchy.
+ // All other items are rendered as documents under their parent hierarchy.
+ [
+ "deep-config",
+ {
+ uriRoot: ".",
+ hierarchy: HierarchyConfigs.deep,
+ },
+ ],
+]);
+
+describe("HTML end-to-end tests", () => {
+ for (const modelName of apiModels) {
+ // Input directory for the model
+ const modelDirectoryPath = Path.join(testDataDirectoryPath, modelName);
+
+ describe(`API model: ${modelName}`, () => {
+ let apiModel: ApiModel;
+ before(async () => {
+ apiModel = await loadModel({ modelDirectoryPath });
+ });
+
+ for (const [configName, inputConfig] of testConfigs) {
+ const temporaryOutputPath = Path.join(
+ testTemporaryDirectoryPath,
+ modelName,
+ configName,
+ );
+ const snapshotPath = Path.join(snapshotsDirectoryPath, modelName, configName);
+
+ it(configName, async () => {
+ const options: HtmlRenderer.RenderApiModelOptions = {
+ ...inputConfig,
+ apiModel,
+ outputDirectoryPath: temporaryOutputPath,
+ };
+
+ await HtmlRenderer.renderApiModel(options);
+
+ await compareDocumentationSuiteSnapshot(snapshotPath, temporaryOutputPath);
+ });
+ }
+ });
+ }
});
diff --git a/tools/api-markdown-documenter/src/test/MarkdownEndToEnd.test.ts b/tools/api-markdown-documenter/src/test/MarkdownEndToEnd.test.ts
index 40d9dfda0a7d..d72107c1142f 100644
--- a/tools/api-markdown-documenter/src/test/MarkdownEndToEnd.test.ts
+++ b/tools/api-markdown-documenter/src/test/MarkdownEndToEnd.test.ts
@@ -3,138 +3,113 @@
* Licensed under the MIT License.
*/
-import * as Path from "node:path";
-import { fileURLToPath } from "node:url";
+import Path from "node:path";
-import { ApiItemKind, ReleaseTag } from "@microsoft/api-extractor-model";
-import { FileSystem, NewlineKind } from "@rushstack/node-core-library";
+import { ReleaseTag, type ApiModel } from "@microsoft/api-extractor-model";
-import type { DocumentNode } from "../documentation-domain/index.js";
-import { type MarkdownRenderConfiguration, renderDocumentAsMarkdown } from "../renderers/index.js";
+import { loadModel, MarkdownRenderer } from "../index.js";
import {
- endToEndTests,
- type ApiModelTestOptions,
- type EndToEndTestConfig,
-} from "./EndToEndTests.js";
-
-const dirname = Path.dirname(fileURLToPath(import.meta.url));
+ compareDocumentationSuiteSnapshot,
+ HierarchyConfigs,
+ snapshotsDirectoryPath as snapshotsDirectoryPathBase,
+ testDataDirectoryPath,
+ testTemporaryDirectoryPath as testTemporaryDirectoryPathBase,
+} from "./EndToEndTestUtilities.js";
/**
* Temp directory under which all tests that generate files will output their contents.
*/
-const testTemporaryDirectoryPath = Path.resolve(dirname, "test_temp", "markdown");
+const testTemporaryDirectoryPath = Path.resolve(testTemporaryDirectoryPathBase, "markdown");
/**
* Snapshot directory to which generated test data will be copied.
* Relative to lib/test
*/
-const snapshotsDirectoryPath = Path.resolve(
- dirname,
- "..",
- "..",
- "src",
- "test",
- "snapshots",
- "markdown",
-);
-
-// Relative to lib/test
-const testDataDirectoryPath = Path.resolve(dirname, "..", "..", "src", "test", "test-data");
-
-const apiModels: ApiModelTestOptions[] = [
- {
- modelName: "simple-suite-test",
- directoryPath: Path.resolve(testDataDirectoryPath, "simple-suite-test"),
- },
- // TODO: add other models
-];
-
-const testConfigs: EndToEndTestConfig[] = [
- /**
- * A sample "flat" configuration, which renders every item kind under a package to the package parent document.
- */
- {
- testName: "default-config",
- transformConfig: {
+const snapshotsDirectoryPath = Path.resolve(snapshotsDirectoryPathBase, "markdown");
+
+const apiModels: string[] = ["simple-suite-test"];
+
+const testConfigs = new Map<
+ string,
+ Omit
+>([
+ [
+ "default-config",
+ {
uriRoot: ".",
},
- renderConfig: {},
- },
-
- /**
- * A sample "flat" configuration, which renders every item kind under a package to the package parent document.
- */
- {
- testName: "flat-config",
- transformConfig: {
+ ],
+
+ // A sample "flat" configuration, which renders every item kind under a package to the package parent document.
+ [
+ "flat-config",
+ {
uriRoot: "docs",
includeBreadcrumb: true,
includeTopLevelDocumentHeading: false,
- documentBoundaries: [], // Render everything to package documents
- hierarchyBoundaries: [], // No additional hierarchy beyond the package level
+ hierarchy: HierarchyConfigs.flat,
minimumReleaseLevel: ReleaseTag.Beta, // Only include `@public` and `beta` items in the docs suite
},
- renderConfig: {},
- },
-
- /**
- * A sample "sparse" configuration, which renders every item kind to its own document.
- */
- {
- testName: "sparse-config",
- transformConfig: {
+ ],
+
+ // A sample "sparse" configuration, which renders every item kind to its own document.
+ [
+ "sparse-config",
+ {
uriRoot: "docs",
includeBreadcrumb: false,
includeTopLevelDocumentHeading: true,
- // Render everything to its own document
- documentBoundaries: [
- ApiItemKind.CallSignature,
- ApiItemKind.Class,
- ApiItemKind.ConstructSignature,
- ApiItemKind.Constructor,
- ApiItemKind.Enum,
- ApiItemKind.EnumMember,
- ApiItemKind.Function,
- ApiItemKind.IndexSignature,
- ApiItemKind.Interface,
- ApiItemKind.Method,
- ApiItemKind.MethodSignature,
- ApiItemKind.Namespace,
- ApiItemKind.Property,
- ApiItemKind.PropertySignature,
- ApiItemKind.TypeAlias,
- ApiItemKind.Variable,
- ],
- hierarchyBoundaries: [], // No additional hierarchy beyond the package level
+ hierarchy: HierarchyConfigs.sparse,
minimumReleaseLevel: ReleaseTag.Public, // Only include `@public` items in the docs suite
skipPackage: (apiPackage) => apiPackage.name === "test-suite-b", // Skip test-suite-b package
- },
- renderConfig: {
startingHeadingLevel: 2,
},
- },
-];
-
-async function renderDocumentToFile(
- document: DocumentNode,
- renderConfig: MarkdownRenderConfiguration,
- outputDirectoryPath: string,
-): Promise {
- const renderedDocument = renderDocumentAsMarkdown(document, renderConfig);
-
- const filePath = Path.join(outputDirectoryPath, `${document.documentPath}.md`);
- await FileSystem.writeFileAsync(filePath, renderedDocument, {
- convertLineEndings: NewlineKind.Lf,
- ensureFolderExists: true,
- });
-}
-
-endToEndTests({
- suiteName: "Markdown End-to-End Tests",
- temporaryOutputDirectoryPath: testTemporaryDirectoryPath,
- snapshotsDirectoryPath,
- render: renderDocumentToFile,
- apiModels,
- testConfigs,
+ ],
+
+ // A sample "deep" configuration.
+ // All "parent" API items generate hierarchy.
+ // All other items are rendered as documents under their parent hierarchy.
+ [
+ "deep-config",
+ {
+ uriRoot: ".",
+ hierarchy: HierarchyConfigs.deep,
+ },
+ ],
+]);
+
+describe("Markdown end-to-end tests", () => {
+ for (const modelName of apiModels) {
+ // Input directory for the model
+ const modelDirectoryPath = Path.join(testDataDirectoryPath, modelName);
+
+ describe(`API model: ${modelName}`, () => {
+ let apiModel: ApiModel;
+ before(async () => {
+ apiModel = await loadModel({ modelDirectoryPath });
+ });
+
+ for (const [configName, inputConfig] of testConfigs) {
+ const temporaryOutputPath = Path.join(
+ testTemporaryDirectoryPath,
+ modelName,
+ configName,
+ );
+ const snapshotPath = Path.join(snapshotsDirectoryPath, modelName, configName);
+
+ it(configName, async () => {
+ const options: MarkdownRenderer.RenderApiModelOptions = {
+ ...inputConfig,
+ apiModel,
+ outputDirectoryPath: temporaryOutputPath,
+ };
+
+ await MarkdownRenderer.renderApiModel(options);
+
+ await compareDocumentationSuiteSnapshot(snapshotPath, temporaryOutputPath);
+ });
+ }
+ });
+ }
});
diff --git a/tools/api-markdown-documenter/src/test/TransformApiModelEndToEnd.test.ts b/tools/api-markdown-documenter/src/test/TransformApiModelEndToEnd.test.ts
new file mode 100644
index 000000000000..0e7eeb34148d
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/TransformApiModelEndToEnd.test.ts
@@ -0,0 +1,77 @@
+/*!
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
+ * Licensed under the MIT License.
+ */
+
+import Path from "node:path";
+
+import { ReleaseTag, type ApiModel } from "@microsoft/api-extractor-model";
+
+import { checkForDuplicateDocumentPaths } from "../api-item-transforms/index.js";
+import { loadModel, transformApiModel, type ApiItemTransformationOptions } from "../index.js";
+
+import { HierarchyConfigs, testDataDirectoryPath } from "./EndToEndTestUtilities.js";
+
+const apiModels: string[] = ["simple-suite-test"];
+
+const testConfigs = new Map>([
+ [
+ "default-config",
+ {
+ uriRoot: ".",
+ },
+ ],
+
+ // A sample "flat" configuration, which renders every item kind under a package to the package parent document.
+ [
+ "flat-config",
+ {
+ uriRoot: "docs",
+ includeBreadcrumb: true,
+ includeTopLevelDocumentHeading: false,
+ hierarchy: HierarchyConfigs.sparse,
+ minimumReleaseLevel: ReleaseTag.Beta, // Only include `@public` and `beta` items in the docs suite
+ },
+ ],
+
+ // A sample "sparse" configuration, which renders every item kind to its own document.
+ [
+ "sparse-config",
+ {
+ uriRoot: "docs",
+ includeBreadcrumb: false,
+ includeTopLevelDocumentHeading: true,
+ hierarchy: HierarchyConfigs.sparse,
+ minimumReleaseLevel: ReleaseTag.Public, // Only include `@public` items in the docs suite
+ skipPackage: (apiPackage) => apiPackage.name === "test-suite-b", // Skip test-suite-b package
+ },
+ ],
+]);
+
+describe("API model transformation end-to-end tests", () => {
+ for (const modelName of apiModels) {
+ // Input directory for the model
+ const modelDirectoryPath = Path.join(testDataDirectoryPath, modelName);
+
+ describe(`API model: ${modelName}`, () => {
+ let apiModel: ApiModel;
+ before(async () => {
+ apiModel = await loadModel({ modelDirectoryPath });
+ });
+
+ describe("Ensure no duplicate document paths", () => {
+ for (const [configName, inputConfig] of testConfigs) {
+ it(configName, async () => {
+ const options: ApiItemTransformationOptions = {
+ ...inputConfig,
+ apiModel,
+ };
+
+ const documents = transformApiModel(options);
+ checkForDuplicateDocumentPaths(documents);
+ });
+ }
+ });
+ });
+ }
+});
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/index.html
new file mode 100644
index 000000000000..e6bc549b6dba
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/index.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/index.html
new file mode 100644
index 000000000000..69b329f3c37e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/index.html
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
+ test-suite-a
+
+
+
+
+
+
This remarks block includes a bulleted list!
+ - Bullet 1
+ - Bullet 2
+ And an ordered list for good measure!
+ 1. List item 1
+ 2. List item 2
+ 3. List item 3
+ Also, here is a link test, including a bad link, because we should have some reasonable support if this happens:
+ - Good link (no alias): TestClass
+ - Good link (with alias): function alias text
+ - Bad link (no alias): InvalidItem
+ - Bad link (with alias): even though I link to an invalid item, I would still like this text to be rendered
+
+
+
+ Example
+
+
A test example
const foo = bar;
+
+
+
+
+
+ Enumerations
+
+
+
+ Enum |
+ Description |
+
+
+
+
+ TestEnum |
+ Test Enum |
+
+
+
+
+
+
+
+ Variables
+
+
+
+ Variable |
+ Alerts |
+ Modifiers |
+ Type |
+ Description |
+
+
+
+
+ testConst |
+ Beta |
+ readonly |
+ |
+ Test Constant |
+
+
+ testConstWithEmptyDeprecatedBlock |
+ Deprecated |
+ readonly |
+ string |
+ I have a @deprecated tag with an empty comment block. |
+
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/_constructor_-constructor.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/_constructor_-constructor.html
new file mode 100644
index 000000000000..01f49f0eac47
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/_constructor_-constructor.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+ (constructor)
+
+
+ This is a {@customTag constructor}.
+
+
+ Signature
protected constructor(privateProperty: number, protectedProperty: TestEnum);
+
+
+ Parameters
+
+
+
+ Parameter |
+ Type |
+ Description |
+
+
+
+
+ privateProperty |
+ number |
+ |
+
+
+ protectedProperty |
+ TestEnum |
+ |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/abstractpropertygetter-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/abstractpropertygetter-property.html
new file mode 100644
index 000000000000..78a68165c32c
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/abstractpropertygetter-property.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ abstractPropertyGetter
+
+
+ A test abstract getter property.
+
+
+ Signature
abstract get abstractPropertyGetter(): TestMappedType;
+ Type: TestMappedType
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/index.html
new file mode 100644
index 000000000000..2d2fba82118e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/index.html
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+ TestAbstractClass
+
+
+ A test abstract class.
+
+
+ Signature
export declare abstract class TestAbstractClass
+
+
+
+
+ Methods
+
+
+
+ Method |
+ Modifiers |
+ Return Type |
+ Description |
+
+
+
+
+ publicAbstractMethod() |
+ |
+ void |
+ A test public abstract method. |
+
+
+ sealedMethod() |
+ sealed |
+ string |
+ A test @sealed method. |
+
+
+ virtualMethod() |
+ virtual |
+ number |
+ A test @virtual method. |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/protectedproperty-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/protectedproperty-property.html
new file mode 100644
index 000000000000..8d4557344f00
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/protectedproperty-property.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ protectedProperty
+
+
+ A test protected property.
+
+
+ Signature
protected readonly protectedProperty: TestEnum;
+ Type: TestEnum
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/publicabstractmethod-method.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/publicabstractmethod-method.html
new file mode 100644
index 000000000000..a592fd8afe94
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/publicabstractmethod-method.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ publicAbstractMethod
+
+
+ A test public abstract method.
+
+
+ Signature
abstract publicAbstractMethod(): void;
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/sealedmethod-method.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/sealedmethod-method.html
new file mode 100644
index 000000000000..3e07abc323ba
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/sealedmethod-method.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ sealedMethod
+
+
+ A test @sealed
method.
+
+
+ Signature
/** @sealed */
protected sealedMethod(): string;
+
+
+ Returns
+ A string!
+ Return type: string
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/virtualmethod-method.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/virtualmethod-method.html
new file mode 100644
index 000000000000..0a0ad7de3210
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/virtualmethod-method.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ virtualMethod
+
+
+ A test @virtual
method.
+
+
+ Signature
/** @virtual */
protected virtualMethod(): number;
+
+
+ Returns
+ A number!
+ Return type: number
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/_constructor_-constructor.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/_constructor_-constructor.html
new file mode 100644
index 000000000000..c1f361e3cbc9
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/_constructor_-constructor.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+ (constructor)
+
+
+ Test class constructor
+
+
+ Signature
constructor(privateProperty: number, protectedProperty: TestEnum, testClassProperty: TTypeParameterB, testClassEventProperty: () => void);
+
+
+
+ Here are some remarks about the constructor
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/abstractpropertygetter-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/abstractpropertygetter-property.html
new file mode 100644
index 000000000000..bb178bcc3ba0
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/abstractpropertygetter-property.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ abstractPropertyGetter
+
+
+ A test abstract getter property.
+
+
+ Signature
get abstractPropertyGetter(): TestMappedType;
+ Type: TestMappedType
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/index.html
new file mode 100644
index 000000000000..917df3feb68c
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/index.html
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+ TestClass
+
+
+
+ Signature
export declare class TestClass<TTypeParameterA, TTypeParameterB> extends TestAbstractClass
+
+
Extends: TestAbstractClass
+
+
+ Type Parameters
+
+
+
+ Parameter |
+ Description |
+
+
+
+
+ TTypeParameterA |
+ A type parameter |
+
+
+ TTypeParameterB |
+ Another type parameter |
+
+
+
+
+
+
+
+
+
+ Here are some remarks about the class
+
+
+
+ Static Properties
+
+
+
+ Property |
+ Type |
+ Description |
+
+
+
+
+ testClassStaticProperty |
+ (foo: number) => string |
+ Test static class property |
+
+
+
+
+
+
+ Events
+
+
+
+ Property |
+ Modifiers |
+ Type |
+ Description |
+
+
+
+
+ testClassEventProperty |
+ readonly |
+ () => void |
+ Test class event property |
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/publicabstractmethod-method.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/publicabstractmethod-method.html
new file mode 100644
index 000000000000..f6b972c7f55e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/publicabstractmethod-method.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ publicAbstractMethod
+
+
+ A test public abstract method.
+
+
+ Signature
publicAbstractMethod(): void;
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclasseventproperty-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclasseventproperty-property.html
new file mode 100644
index 000000000000..c9481deb7915
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclasseventproperty-property.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testClassEventProperty
+
+
+ Test class event property
+
+
+ Signature
readonly testClassEventProperty: () => void;
+ Type: () => void
+
+
+
+ Here are some remarks about the property
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassgetterproperty-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassgetterproperty-property.html
new file mode 100644
index 000000000000..931105145467
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassgetterproperty-property.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testClassGetterProperty
+
+
+ Test class property with both a getter and a setter.
+
+
+ Signature
/** @virtual */
get testClassGetterProperty(): number;
set testClassGetterProperty(newValue: number);
+ Type: number
+
+
+
+ Here are some remarks about the getter-only property
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassmethod-method.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassmethod-method.html
new file mode 100644
index 000000000000..061dfeb57cfd
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassmethod-method.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ testClassMethod
+
+
+
+ Signature
/** @sealed */
testClassMethod(input: TTypeParameterA): TTypeParameterA;
+
+
+
+ Here are some remarks about the method
+
+
+ Parameters
+
+
+
+ Parameter |
+ Type |
+ Description |
+
+
+
+
+ input |
+ TTypeParameterA |
+ |
+
+
+
+
+
+ Returns
+ Return type: TTypeParameterA
+
+
+ Throws
+ Some sort of error in 1 case.
+ Some other sort of error in another case. For example, a case where some thing happens.
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassproperty-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassproperty-property.html
new file mode 100644
index 000000000000..dc1eeaf89412
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassproperty-property.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testClassProperty
+
+
+
+ Signature
readonly testClassProperty: TTypeParameterB;
+ Type: TTypeParameterB
+
+
+
+ Here are some remarks about the property
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticmethod-method.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticmethod-method.html
new file mode 100644
index 000000000000..be05c50d4e8e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticmethod-method.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+ testClassStaticMethod
+
+
+ Test class static method
+
+
+ Signature
static testClassStaticMethod(foo: number): string;
+
+
+ Parameters
+
+
+
+ Parameter |
+ Type |
+ Description |
+
+
+
+
+ foo |
+ number |
+ Some number |
+
+
+
+
+
+ Returns
+ - Some string
+ Return type: string
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticproperty-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticproperty-property.html
new file mode 100644
index 000000000000..460d23903051
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticproperty-property.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ testClassStaticProperty
+
+
+ Test static class property
+
+
+ Signature
static testClassStaticProperty: (foo: number) => string;
+ Type: (foo: number) => string
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/virtualmethod-method.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/virtualmethod-method.html
new file mode 100644
index 000000000000..cd2dc520c6b9
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testclass-class/virtualmethod-method.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ virtualMethod
+
+
+
+ Signature
/** @override */
protected virtualMethod(): number;
+
+
+ Returns
+ Return type: number
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testconst-variable.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testconst-variable.html
new file mode 100644
index 000000000000..0ce147bd98c7
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testconst-variable.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testConst
+
+
+ WARNING: This API is provided as a beta preview and may change without notice. Use at your own risk.
+
+ Signature
testConst = 42
+
+
+
+ Here are some remarks about the variable
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testconstwithemptydeprecatedblock-variable.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testconstwithemptydeprecatedblock-variable.html
new file mode 100644
index 000000000000..abfdf1c3ba7e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testconstwithemptydeprecatedblock-variable.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ testConstWithEmptyDeprecatedBlock
+
+
+ I have a @deprecated
tag with an empty comment block.
+
+
+ WARNING: This API is deprecated and will be removed in a future release.
+
+
+ Signature
testConstWithEmptyDeprecatedBlock: string
+ Type: string
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testemptyinterface-interface/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testemptyinterface-interface/index.html
new file mode 100644
index 000000000000..f5552788ae85
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testemptyinterface-interface/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ TestEmptyInterface
+
+
+
+ Signature
export interface TestEmptyInterface
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/index.html
new file mode 100644
index 000000000000..c5f9b097620b
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/index.html
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+ TestEnum
+
+
+
+ Signature
export declare enum TestEnum
+
+
+
+ Here are some remarks about the enum
+
+
+ Examples
+
+ Example 1
+
+
Some example
const foo = TestEnum.TestEnumValue1
+
+
+
+ Example 2
+
+
Another example
const bar = TestEnum.TestEnumValue2
+
+
+
+
+
+
+ Test enum value 1 (string)
+
+
+ Signature
TestEnumValue1 = "test-enum-value-1"
+
+
+
+ Here are some remarks about the enum value
+
+
+ Test enum value 2 (number)
+
+
+ Signature
TestEnumValue2 = 3
+
+
+
+ Here are some remarks about the enum value
+
+
+ Test enum value 3 (default)
+
+
+ Signature
TestEnumValue3 = 4
+
+
+
+ Here are some remarks about the enum value
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue1-enummember.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue1-enummember.html
new file mode 100644
index 000000000000..57399fb71808
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue1-enummember.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ TestEnumValue1
+
+
+ Test enum value 1 (string)
+
+
+ Signature
TestEnumValue1 = "test-enum-value-1"
+
+
+
+ Here are some remarks about the enum value
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue2-enummember.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue2-enummember.html
new file mode 100644
index 000000000000..ab1e131365cc
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue2-enummember.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ TestEnumValue2
+
+
+ Test enum value 2 (number)
+
+
+ Signature
TestEnumValue2 = 3
+
+
+
+ Here are some remarks about the enum value
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue3-enummember.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue3-enummember.html
new file mode 100644
index 000000000000..2fc410d631bd
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue3-enummember.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ TestEnumValue3
+
+
+ Test enum value 3 (default)
+
+
+ Signature
TestEnumValue3 = 4
+
+
+
+ Here are some remarks about the enum value
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunction-function.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunction-function.html
new file mode 100644
index 000000000000..34889dcf7286
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunction-function.html
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+ testFunction
+
+
+ WARNING: This API is provided as an alpha preview and may change without notice. Use at your own risk.
+
+ Signature
export declare function testFunction<TTypeParameter extends TestInterface = TestInterface>(testParameter: TTypeParameter, testOptionalParameter?: TTypeParameter): TTypeParameter;
+
+
+ Type Parameters
+
+
+
+ Parameter |
+ Constraint |
+ Default |
+ Description |
+
+
+
+
+ TTypeParameter |
+ TestInterface |
+ TestInterface |
+ A test type parameter |
+
+
+
+
+
+
+
+
+ This is a test link to another API member
+
+
+ Parameters
+
+
+
+ Parameter |
+ Modifiers |
+ Type |
+ Description |
+
+
+
+
+ testParameter |
+ |
+ TTypeParameter |
+ A test parameter |
+
+
+ testOptionalParameter |
+ optional |
+ TTypeParameter |
+ |
+
+
+
+
+
+ Returns
+ The provided parameter
+ Return type: TTypeParameter
+
+
+ Throws
+ An Error when something bad happens.
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturninginlinetype-function.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturninginlinetype-function.html
new file mode 100644
index 000000000000..7e7062b3ec7a
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturninginlinetype-function.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testFunctionReturningInlineType
+
+
+ Test function that returns an inline type
+
+
+ Signature
export declare function testFunctionReturningInlineType(): {
foo: number;
bar: TestEnum;
};
+
+
+ Returns
+ An inline type
+ Return type: { foo: number; bar: TestEnum; }
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturningintersectiontype-function.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturningintersectiontype-function.html
new file mode 100644
index 000000000000..25f716239136
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturningintersectiontype-function.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+ testFunctionReturningIntersectionType
+
+
+ Test function that returns an inline type
+
+
+ WARNING: This API is deprecated and will be removed in a future release.
This is a test deprecation notice. Here is a link to something else!
+
+
+ Signature
export declare function testFunctionReturningIntersectionType(): TestEmptyInterface & TestInterfaceWithTypeParameter<number>;
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturninguniontype-function.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturninguniontype-function.html
new file mode 100644
index 000000000000..5a5999633ab7
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testfunctionreturninguniontype-function.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testFunctionReturningUnionType
+
+
+ Test function that returns an inline type
+
+
+ Signature
export declare function testFunctionReturningUnionType(): string | TestInterface;
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call_-callsignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call_-callsignature.html
new file mode 100644
index 000000000000..1bb3cec8d9c6
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call_-callsignature.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ (event: 'testCallSignature', listener: (input: unknown) => void): any
+
+
+ Test interface event call signature
+
+
+ Signature
(event: 'testCallSignature', listener: (input: unknown) => void): any;
+
+
+
+ Here are some remarks about the event call signature
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call__1-callsignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call__1-callsignature.html
new file mode 100644
index 000000000000..1ebbf183381e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call__1-callsignature.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ (event: 'anotherTestCallSignature', listener: (input: number) => string): number
+
+
+ Another example call signature
+
+
+ Signature
(event: 'anotherTestCallSignature', listener: (input: number) => string): number;
+
+
+
+ Here are some remarks about the event call signature
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_new_-constructsignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_new_-constructsignature.html
new file mode 100644
index 000000000000..cacb80c9c0d1
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_new_-constructsignature.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ new (): TestInterface
+
+
+ Test construct signature.
+
+
+ Signature
new (): TestInterface;
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/getterproperty-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/getterproperty-property.html
new file mode 100644
index 000000000000..c24cbf5dc74e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/getterproperty-property.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ getterProperty
+
+
+ A test getter-only interface property.
+
+
+ Signature
get getterProperty(): boolean;
+ Type: boolean
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/index.html
new file mode 100644
index 000000000000..cffec89b7906
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/index.html
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+ TestInterface
+
+
+
+ Signature
export interface TestInterface
+
+
+
+ Here are some remarks about the interface
+
+
+ Construct Signatures
+
+
+
+ Events
+
+
+
+ Property |
+ Modifiers |
+ Type |
+ Description |
+
+
+
+
+ testClassEventProperty |
+ readonly |
+ () => void |
+ Test interface event property |
+
+
+
+
+
+
+ Methods
+
+
+
+ Method |
+ Return Type |
+ Description |
+
+
+
+
+ testInterfaceMethod() |
+ void |
+ Test interface method |
+
+
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/propertywithbadinheritdoctarget-propertysignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/propertywithbadinheritdoctarget-propertysignature.html
new file mode 100644
index 000000000000..4bacb75a530a
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/propertywithbadinheritdoctarget-propertysignature.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ propertyWithBadInheritDocTarget
+
+
+
+ Signature
propertyWithBadInheritDocTarget: boolean;
+ Type: boolean
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/setterproperty-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/setterproperty-property.html
new file mode 100644
index 000000000000..8a170ed0040e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/setterproperty-property.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ setterProperty
+
+
+ A test property with a getter and a setter.
+
+
+ Signature
get setterProperty(): boolean;
set setterProperty(newValue: boolean);
+ Type: boolean
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testclasseventproperty-propertysignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testclasseventproperty-propertysignature.html
new file mode 100644
index 000000000000..cc3e3982f7a2
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testclasseventproperty-propertysignature.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testClassEventProperty
+
+
+ Test interface event property
+
+
+ Signature
readonly testClassEventProperty: () => void;
+ Type: () => void
+
+
+
+ Here are some remarks about the event property
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfacemethod-methodsignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfacemethod-methodsignature.html
new file mode 100644
index 000000000000..488753fe08a4
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfacemethod-methodsignature.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ testInterfaceMethod
+
+
+ Test interface method
+
+
+ Signature
testInterfaceMethod(): void;
+
+
+
+ Here are some remarks about the method
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature.html
new file mode 100644
index 000000000000..78743f3ec621
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testInterfaceProperty
+
+
+ Test interface property
+
+
+ Signature
testInterfaceProperty: number;
+ Type: number
+
+
+
+ Here are some remarks about the property
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature.html
new file mode 100644
index 000000000000..38d4d1e34c97
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ testOptionalInterfaceProperty
+
+
+ Test optional property
+
+
+ Signature
testOptionalInterfaceProperty?: number;
+ Type: number
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/index.html
new file mode 100644
index 000000000000..6d103c866d97
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/index.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ TestInterfaceExtendingOtherInterfaces
+
+
+ Test interface that extends other interfaces
+
+
+
+
+ Here are some remarks about the interface
+
+
+ Methods
+
+
+
+ Method |
+ Return Type |
+ Description |
+
+
+
+
+ testMethod(input) |
+ number |
+ Test interface method accepting a string and returning a number. |
+
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/testmethod-methodsignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/testmethod-methodsignature.html
new file mode 100644
index 000000000000..255cc2a629fd
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/testmethod-methodsignature.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+ testMethod
+
+
+ Test interface method accepting a string and returning a number.
+
+
+ Signature
testMethod(input: string): number;
+
+
+
+ Here are some remarks about the method
+
+
+ Parameters
+
+
+
+ Parameter |
+ Type |
+ Description |
+
+
+
+
+ input |
+ string |
+ A string |
+
+
+
+
+
+ Returns
+ A number
+ Return type: number
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/_indexer_-indexsignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/_indexer_-indexsignature.html
new file mode 100644
index 000000000000..fdd8de4c6fe4
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/_indexer_-indexsignature.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ [foo: number]: { bar: string; }
+
+
+ Test index signature.
+
+
+ Signature
[foo: number]: {
bar: string;
};
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/index.html
new file mode 100644
index 000000000000..f4a88fee87e9
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/index.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+ TestInterfaceWithIndexSignature
+
+
+ An interface with an index signature.
+
+
+ Signature
export interface TestInterfaceWithIndexSignature
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/index.html
new file mode 100644
index 000000000000..113f38820f3a
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/index.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+ TestInterfaceWithTypeParameter
+
+
+ Test interface with generic type parameter
+
+
+ Signature
export interface TestInterfaceWithTypeParameter<T>
+
+
+ Type Parameters
+
+
+
+ Parameter |
+ Description |
+
+
+
+
+ T |
+ A type parameter |
+
+
+
+
+
+
+
+
+ Here are some remarks about the interface
+
+
+ Properties
+
+
+
+ Property |
+ Type |
+ Description |
+
+
+
+
+ testProperty |
+ T |
+ A test interface property using generic type parameter |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/testproperty-propertysignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/testproperty-propertysignature.html
new file mode 100644
index 000000000000..639a4ff429b0
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/testproperty-propertysignature.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ testProperty
+
+
+ A test interface property using generic type parameter
+
+
+ Signature
testProperty: T;
+ Type: T
+
+
+
+ Here are some remarks about the property
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmappedtype-typealias/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmappedtype-typealias/index.html
new file mode 100644
index 000000000000..864c6083ff7b
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmappedtype-typealias/index.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ TestMappedType
+
+
+
+ Signature
export type TestMappedType = {
[K in TestEnum]: boolean;
};
+
+
+
+ Here are some remarks about the mapped type
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/foo-variable.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/foo-variable.html
new file mode 100644
index 000000000000..ca8b80f47e50
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/foo-variable.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ foo
+
+
+ Test constant in module.
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/index.html
new file mode 100644
index 000000000000..96667a9e9517
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/index.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ TestModule
+
+
+ Variables
+
+
+
+ Variable |
+ Modifiers |
+ Type |
+ Description |
+
+
+
+
+ foo |
+ readonly |
+ |
+ Test constant in module. |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/index.html
new file mode 100644
index 000000000000..b58d65593523
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/index.html
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
+ TestNamespace
+
+
+
+ Signature
export declare namespace TestNamespace
+
+
+
+ Here are some remarks about the namespace
+
+
+ Examples
+
+ Example: TypeScript Example
+
+
const foo: Foo = {
bar: "Hello world!";
baz = 42;
};
+
+
+
+ Example: JavaScript Example
+
+
const foo = {
bar: "Hello world!";
baz = 42;
};
+
+
+
+
+ Interfaces
+
+
+
+ Interface |
+ Alerts |
+ Description |
+
+
+
+
+ TestInterface |
+ Alpha |
+ Test interface |
+
+
+
+
+
+ Classes
+
+
+
+ Class |
+ Description |
+
+
+
+
+ TestClass |
+ Test class |
+
+
+
+
+
+ Enumerations
+
+
+
+ Enum |
+ Description |
+
+
+
+
+ TestEnum |
+ Test Enum |
+
+
+
+
+
+ Types
+
+
+
+ TypeAlias |
+ Description |
+
+
+
+
+ TestTypeAlias |
+ Test Type-Alias |
+
+
+
+
+
+
+ Variables
+
+
+
+ Variable |
+ Alerts |
+ Modifiers |
+ Type |
+ Description |
+
+
+
+
+ TestConst |
+ Beta |
+ readonly |
+ |
+ Test Constant |
+
+
+
+
+
+ Namespaces
+
+
+
+ Namespace |
+ Description |
+
+
+
+
+ TestSubNamespace |
+ Test sub-namespace |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/_constructor_-constructor.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/_constructor_-constructor.html
new file mode 100644
index 000000000000..58e53c22695c
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/_constructor_-constructor.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+ (constructor)
+
+
+ Test class constructor
+
+
+ Signature
constructor(testClassProperty: string);
+
+
+ Parameters
+
+
+
+ Parameter |
+ Type |
+ Description |
+
+
+
+
+ testClassProperty |
+ string |
+ See testClassProperty |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/index.html
new file mode 100644
index 000000000000..b488f1d60c02
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/index.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+ TestClass
+
+
+
+ Signature
class TestClass
+
+
+
+ Properties
+
+
+
+ Property |
+ Modifiers |
+ Type |
+ Description |
+
+
+
+
+ testClassProperty |
+ readonly |
+ string |
+ Test interface property |
+
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassmethod-method.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassmethod-method.html
new file mode 100644
index 000000000000..4182400579e8
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassmethod-method.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ testClassMethod
+
+
+
+ Signature
testClassMethod(testParameter: string): Promise<string>;
+
+
+ Parameters
+
+
+
+ Parameter |
+ Type |
+ Description |
+
+
+
+
+ testParameter |
+ string |
+ A string |
+
+
+
+
+
+ Returns
+ A Promise
+ Return type: Promise<string>
+
+
+ Throws
+ An Error when something happens for which an error should be thrown. Except in the cases where another kind of error is thrown. We don't throw this error in those cases.
+
+
A different kind of error when a thing happens, but not when the first kind of error is thrown instead.
+ 😁
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassproperty-property.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassproperty-property.html
new file mode 100644
index 000000000000..601113c407fd
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassproperty-property.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ testClassProperty
+
+
+ Test interface property
+
+
+ Signature
readonly testClassProperty: string;
+ Type: string
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testconst-variable.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testconst-variable.html
new file mode 100644
index 000000000000..881248685062
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testconst-variable.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ TestConst
+
+
+ WARNING: This API is provided as a beta preview and may change without notice. Use at your own risk.
+
+ Signature
TestConst = "Hello world!"
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/index.html
new file mode 100644
index 000000000000..aadd401dd9e2
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/index.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ TestEnum
+
+
+
+ Signature
enum TestEnum
+
+
+
+
+
+ Signature
TestEnumValue1 = 0
+
+
+
+ Signature
TestEnumValue2 = 1
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue1-enummember.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue1-enummember.html
new file mode 100644
index 000000000000..fcda24ca526d
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue1-enummember.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ TestEnumValue1
+
+
+
+ Signature
TestEnumValue1 = 0
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue2-enummember.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue2-enummember.html
new file mode 100644
index 000000000000..f5a95a5acb7c
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue2-enummember.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ TestEnumValue2
+
+
+
+ Signature
TestEnumValue2 = 1
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testfunction-function.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testfunction-function.html
new file mode 100644
index 000000000000..deb8e56b5aec
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testfunction-function.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+ testFunction
+
+
+
+ Signature
function testFunction(testParameter: number): number;
+
+
+ Parameters
+
+
+
+ Parameter |
+ Type |
+ Description |
+
+
+
+
+ testParameter |
+ number |
+ |
+
+
+
+
+
+ Returns
+ A number
+ Return type: number
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/index.html
new file mode 100644
index 000000000000..c5d44d04aded
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/index.html
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+ TestInterface
+
+
+ WARNING: This API is provided as an alpha preview and may change without notice. Use at your own risk.
+
+
+ Properties
+
+
+
+ Property |
+ Alerts |
+ Type |
+ Description |
+
+
+
+
+ testInterfaceProperty |
+ Alpha |
+ boolean |
+ Test interface property |
+
+
+
+
+
+ Methods
+
+
+
+ Method |
+ Alerts |
+ Return Type |
+ Description |
+
+
+
+
+ testInterfaceMethod() |
+ Alpha |
+ void |
+ Test interface method |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfacemethod-methodsignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfacemethod-methodsignature.html
new file mode 100644
index 000000000000..3b489d5671ab
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfacemethod-methodsignature.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ testInterfaceMethod
+
+
+ Test interface method
+
+ WARNING: This API is provided as an alpha preview and may change without notice. Use at your own risk.
+
+ Signature
testInterfaceMethod(): void;
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfaceproperty-propertysignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfaceproperty-propertysignature.html
new file mode 100644
index 000000000000..86286ff0e9c3
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfaceproperty-propertysignature.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+ testInterfaceProperty
+
+
+ Test interface property
+
+ WARNING: This API is provided as an alpha preview and may change without notice. Use at your own risk.
+
+ Signature
testInterfaceProperty: boolean;
+ Type: boolean
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testsubnamespace-namespace/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testsubnamespace-namespace/index.html
new file mode 100644
index 000000000000..48fc6ff9b0d4
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testsubnamespace-namespace/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ TestSubNamespace
+
+
+
+ Signature
namespace TestSubNamespace
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testtypealias-typealias/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testtypealias-typealias/index.html
new file mode 100644
index 000000000000..89c03a3b2c02
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testtypealias-typealias/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ TestTypeAlias
+
+
+
+ Signature
type TestTypeAlias = boolean;
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/typealias-typealias/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/typealias-typealias/index.html
new file mode 100644
index 000000000000..6b10e181bd48
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/typealias-typealias/index.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ TypeAlias
+
+
+
+ Signature
export type TypeAlias = string;
+
+
+
+ Here are some remarks about the type alias
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/foo-interface/bar-propertysignature.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/foo-interface/bar-propertysignature.html
new file mode 100644
index 000000000000..ba0cf8d6a230
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/foo-interface/bar-propertysignature.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ bar
+
+
+
+ Signature
bar: TestEnum;
+ Type: TestEnum
+
+
+
+ Here are some remarks about the enum
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/foo-interface/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/foo-interface/index.html
new file mode 100644
index 000000000000..02971c93289e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/foo-interface/index.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+ Foo
+
+
+
+ Signature
export interface Foo
+
+
+ Properties
+
+
+
+ Property |
+ Type |
+ Description |
+
+
+
+
+ bar |
+ TestEnum |
+ Test Enum |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/index.html b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/index.html
new file mode 100644
index 000000000000..37ab3d58ea5b
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-b/index.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ test-suite-b
+
+
+ Interfaces
+
+
+
+ Interface |
+ Description |
+
+
+
+
+ Foo |
+ Bar |
+
+
+
+
+
+
+
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/index.md
new file mode 100644
index 000000000000..d8ae823a9570
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/index.md
@@ -0,0 +1,8 @@
+# API Overview
+
+## Packages
+
+| Package | Description |
+| --- | --- |
+| [test-suite-a](./test-suite-a/) | Test package |
+| [test-suite-b](./test-suite-b/) | |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/index.md
new file mode 100644
index 000000000000..39d59df9e9ed
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/index.md
@@ -0,0 +1,92 @@
+# test-suite-a
+
+[Packages](./) > [test-suite-a](./test-suite-a/)
+
+Test package
+
+## Remarks {#test-suite-a-remarks}
+
+This remarks block includes a bulleted list!
+
+- Bullet 1
+
+- Bullet 2
+
+And an ordered list for good measure!
+
+1. List item 1
+
+2. List item 2
+
+3. List item 3
+
+Also, here is a link test, including a bad link, because we should have some reasonable support if this happens:
+
+- Good link (no alias): [TestClass](./test-suite-a/testclass-class/)
+
+- Good link (with alias): [function alias text](./test-suite-a/testfunction-function)
+
+- Bad link (no alias): _InvalidItem_
+
+- Bad link (with alias): _even though I link to an invalid item, I would still like this text to be rendered_
+
+## Example {#test-suite-a-example}
+
+A test example
+
+```typescript
+const foo = bar;
+```
+
+## Interfaces
+
+| Interface | Description |
+| --- | --- |
+| [TestEmptyInterface](./test-suite-a/testemptyinterface-interface/) | An empty interface |
+| [TestInterface](./test-suite-a/testinterface-interface/) | Test interface |
+| [TestInterfaceExtendingOtherInterfaces](./test-suite-a/testinterfaceextendingotherinterfaces-interface/) | Test interface that extends other interfaces |
+| [TestInterfaceWithIndexSignature](./test-suite-a/testinterfacewithindexsignature-interface/) | An interface with an index signature. |
+| [TestInterfaceWithTypeParameter](./test-suite-a/testinterfacewithtypeparameter-interface/) | Test interface with generic type parameter |
+
+## Classes
+
+| Class | Description |
+| --- | --- |
+| [TestAbstractClass](./test-suite-a/testabstractclass-class/) | A test abstract class. |
+| [TestClass](./test-suite-a/testclass-class/) | Test class |
+
+## Enumerations
+
+| Enum | Description |
+| --- | --- |
+| [TestEnum](./test-suite-a/testenum-enum/) | Test Enum |
+
+## Types
+
+| TypeAlias | Description |
+| --- | --- |
+| [TestMappedType](./test-suite-a/testmappedtype-typealias/) | Test Mapped Type, using [TestEnum](./test-suite-a/testenum-enum/) |
+| [TypeAlias](./test-suite-a/typealias-typealias/) | Test Type-Alias |
+
+## Functions
+
+| Function | Alerts | Return Type | Description |
+| --- | --- | --- | --- |
+| [testFunction(testParameter, testOptionalParameter)](./test-suite-a/testfunction-function) | `Alpha` | TTypeParameter | Test function |
+| [testFunctionReturningInlineType()](./test-suite-a/testfunctionreturninginlinetype-function) | | { foo: number; bar: [TestEnum](./test-suite-a/testenum-enum/); } | Test function that returns an inline type |
+| [testFunctionReturningIntersectionType()](./test-suite-a/testfunctionreturningintersectiontype-function) | `Deprecated` | [TestEmptyInterface](./test-suite-a/testemptyinterface-interface/) & [TestInterfaceWithTypeParameter](./test-suite-a/testinterfacewithtypeparameter-interface/)<number> | Test function that returns an inline type |
+| [testFunctionReturningUnionType()](./test-suite-a/testfunctionreturninguniontype-function) | | string \| [TestInterface](./test-suite-a/testinterface-interface/) | Test function that returns an inline type |
+
+## Variables
+
+| Variable | Alerts | Modifiers | Type | Description |
+| --- | --- | --- | --- | --- |
+| [testConst](./test-suite-a/testconst-variable) | `Beta` | `readonly` | | Test Constant |
+| [testConstWithEmptyDeprecatedBlock](./test-suite-a/testconstwithemptydeprecatedblock-variable) | `Deprecated` | `readonly` | string | I have a `@deprecated` tag with an empty comment block. |
+
+## Namespaces
+
+| Namespace | Description |
+| --- | --- |
+| [TestModule](./test-suite-a/testmodule-namespace/) | |
+| [TestNamespace](./test-suite-a/testnamespace-namespace/) | Test Namespace |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/_constructor_-constructor.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/_constructor_-constructor.md
new file mode 100644
index 000000000000..e841a169957e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/_constructor_-constructor.md
@@ -0,0 +1,18 @@
+# (constructor)
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestAbstractClass](./test-suite-a/testabstractclass-class/) > [(constructor)(privateProperty, protectedProperty)](./test-suite-a/testabstractclass-class/_constructor_-constructor)
+
+This is a _{@customTag constructor}_.
+
+## Signature {#\_constructor\_-signature}
+
+```typescript
+protected constructor(privateProperty: number, protectedProperty: TestEnum);
+```
+
+## Parameters {#\_constructor\_-parameters}
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| privateProperty | number | |
+| protectedProperty | [TestEnum](./test-suite-a/testenum-enum/) | |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/abstractpropertygetter-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/abstractpropertygetter-property.md
new file mode 100644
index 000000000000..b80f6ae7e538
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/abstractpropertygetter-property.md
@@ -0,0 +1,13 @@
+# abstractPropertyGetter
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestAbstractClass](./test-suite-a/testabstractclass-class/) > [abstractPropertyGetter](./test-suite-a/testabstractclass-class/abstractpropertygetter-property)
+
+A test abstract getter property.
+
+## Signature {#abstractpropertygetter-signature}
+
+```typescript
+abstract get abstractPropertyGetter(): TestMappedType;
+```
+
+**Type:** [TestMappedType](./test-suite-a/testmappedtype-typealias/)
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/index.md
new file mode 100644
index 000000000000..355797f91c4e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/index.md
@@ -0,0 +1,32 @@
+# TestAbstractClass
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestAbstractClass](./test-suite-a/testabstractclass-class/)
+
+A test abstract class.
+
+## Signature {#testabstractclass-signature}
+
+```typescript
+export declare abstract class TestAbstractClass
+```
+
+## Constructors
+
+| Constructor | Description |
+| --- | --- |
+| [(constructor)(privateProperty, protectedProperty)](./test-suite-a/testabstractclass-class/_constructor_-constructor) | This is a _{@customTag constructor}_. |
+
+## Properties
+
+| Property | Modifiers | Type | Description |
+| --- | --- | --- | --- |
+| [abstractPropertyGetter](./test-suite-a/testabstractclass-class/abstractpropertygetter-property) | `readonly` | [TestMappedType](./test-suite-a/testmappedtype-typealias/) | A test abstract getter property. |
+| [protectedProperty](./test-suite-a/testabstractclass-class/protectedproperty-property) | `readonly` | [TestEnum](./test-suite-a/testenum-enum/) | A test protected property. |
+
+## Methods
+
+| Method | Modifiers | Return Type | Description |
+| --- | --- | --- | --- |
+| [publicAbstractMethod()](./test-suite-a/testabstractclass-class/publicabstractmethod-method) | | void | A test public abstract method. |
+| [sealedMethod()](./test-suite-a/testabstractclass-class/sealedmethod-method) | `sealed` | string | A test `@sealed` method. |
+| [virtualMethod()](./test-suite-a/testabstractclass-class/virtualmethod-method) | `virtual` | number | A test `@virtual` method. |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/protectedproperty-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/protectedproperty-property.md
new file mode 100644
index 000000000000..29ad04377551
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/protectedproperty-property.md
@@ -0,0 +1,13 @@
+# protectedProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestAbstractClass](./test-suite-a/testabstractclass-class/) > [protectedProperty](./test-suite-a/testabstractclass-class/protectedproperty-property)
+
+A test protected property.
+
+## Signature {#protectedproperty-signature}
+
+```typescript
+protected readonly protectedProperty: TestEnum;
+```
+
+**Type:** [TestEnum](./test-suite-a/testenum-enum/)
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/publicabstractmethod-method.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/publicabstractmethod-method.md
new file mode 100644
index 000000000000..a4fa120e1ab6
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/publicabstractmethod-method.md
@@ -0,0 +1,11 @@
+# publicAbstractMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestAbstractClass](./test-suite-a/testabstractclass-class/) > [publicAbstractMethod()](./test-suite-a/testabstractclass-class/publicabstractmethod-method)
+
+A test public abstract method.
+
+## Signature {#publicabstractmethod-signature}
+
+```typescript
+abstract publicAbstractMethod(): void;
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/sealedmethod-method.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/sealedmethod-method.md
new file mode 100644
index 000000000000..12d56cb8db70
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/sealedmethod-method.md
@@ -0,0 +1,18 @@
+# sealedMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestAbstractClass](./test-suite-a/testabstractclass-class/) > [sealedMethod()](./test-suite-a/testabstractclass-class/sealedmethod-method)
+
+A test `@sealed` method.
+
+## Signature {#sealedmethod-signature}
+
+```typescript
+/** @sealed */
+protected sealedMethod(): string;
+```
+
+## Returns {#sealedmethod-returns}
+
+A string!
+
+**Return type:** string
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/virtualmethod-method.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/virtualmethod-method.md
new file mode 100644
index 000000000000..09e47b29d7c9
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testabstractclass-class/virtualmethod-method.md
@@ -0,0 +1,18 @@
+# virtualMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestAbstractClass](./test-suite-a/testabstractclass-class/) > [virtualMethod()](./test-suite-a/testabstractclass-class/virtualmethod-method)
+
+A test `@virtual` method.
+
+## Signature {#virtualmethod-signature}
+
+```typescript
+/** @virtual */
+protected virtualMethod(): number;
+```
+
+## Returns {#virtualmethod-returns}
+
+A number!
+
+**Return type:** number
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/_constructor_-constructor.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/_constructor_-constructor.md
new file mode 100644
index 000000000000..900d4e2a0c1e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/_constructor_-constructor.md
@@ -0,0 +1,24 @@
+# (constructor)
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [(constructor)(privateProperty, protectedProperty, testClassProperty, testClassEventProperty)](./test-suite-a/testclass-class/_constructor_-constructor)
+
+Test class constructor
+
+## Signature {#\_constructor\_-signature}
+
+```typescript
+constructor(privateProperty: number, protectedProperty: TestEnum, testClassProperty: TTypeParameterB, testClassEventProperty: () => void);
+```
+
+## Remarks {#\_constructor\_-remarks}
+
+Here are some remarks about the constructor
+
+## Parameters {#\_constructor\_-parameters}
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| privateProperty | number | See [TestAbstractClass](./test-suite-a/testabstractclass-class/)'s constructor. |
+| protectedProperty | [TestEnum](./test-suite-a/testenum-enum/) | Some notes about the parameter.
See protectedProperty.
|
+| testClassProperty | TTypeParameterB | See [testClassProperty](./test-suite-a/testclass-class/testclassproperty-property). |
+| testClassEventProperty | () => void | See [testClassEventProperty](./test-suite-a/testclass-class/testclasseventproperty-property). |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/abstractpropertygetter-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/abstractpropertygetter-property.md
new file mode 100644
index 000000000000..7f04e03f8c49
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/abstractpropertygetter-property.md
@@ -0,0 +1,13 @@
+# abstractPropertyGetter
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [abstractPropertyGetter](./test-suite-a/testclass-class/abstractpropertygetter-property)
+
+A test abstract getter property.
+
+## Signature {#abstractpropertygetter-signature}
+
+```typescript
+get abstractPropertyGetter(): TestMappedType;
+```
+
+**Type:** [TestMappedType](./test-suite-a/testmappedtype-typealias/)
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/index.md
new file mode 100644
index 000000000000..c37ae228439e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/index.md
@@ -0,0 +1,68 @@
+# TestClass
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/)
+
+Test class
+
+## Signature {#testclass-signature}
+
+```typescript
+export declare class TestClass extends TestAbstractClass
+```
+
+**Extends:** [TestAbstractClass](./test-suite-a/testabstractclass-class/)
+
+### Type Parameters
+
+| Parameter | Description |
+| --- | --- |
+| TTypeParameterA | A type parameter |
+| TTypeParameterB | Another type parameter |
+
+## Remarks {#testclass-remarks}
+
+Here are some remarks about the class
+
+## Constructors
+
+| Constructor | Description |
+| --- | --- |
+| [(constructor)(privateProperty, protectedProperty, testClassProperty, testClassEventProperty)](./test-suite-a/testclass-class/_constructor_-constructor) | Test class constructor |
+
+## Static Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [testClassStaticProperty](./test-suite-a/testclass-class/testclassstaticproperty-property) | (foo: number) => string | Test static class property |
+
+## Static Methods
+
+| Method | Return Type | Description |
+| --- | --- | --- |
+| [testClassStaticMethod(foo)](./test-suite-a/testclass-class/testclassstaticmethod-method) | string | Test class static method |
+
+## Events
+
+| Property | Modifiers | Type | Description |
+| --- | --- | --- | --- |
+| [testClassEventProperty](./test-suite-a/testclass-class/testclasseventproperty-property) | `readonly` | () => void | Test class event property |
+
+## Properties
+
+| Property | Modifiers | Type | Description |
+| --- | --- | --- | --- |
+| [abstractPropertyGetter](./test-suite-a/testclass-class/abstractpropertygetter-property) | `readonly` | [TestMappedType](./test-suite-a/testmappedtype-typealias/) | A test abstract getter property. |
+| [testClassGetterProperty](./test-suite-a/testclass-class/testclassgetterproperty-property) | `virtual` | number | Test class property with both a getter and a setter. |
+| [testClassProperty](./test-suite-a/testclass-class/testclassproperty-property) | `readonly` | TTypeParameterB | Test class property |
+
+## Methods
+
+| Method | Modifiers | Return Type | Description |
+| --- | --- | --- | --- |
+| [publicAbstractMethod()](./test-suite-a/testclass-class/publicabstractmethod-method) | | void | A test public abstract method. |
+| [testClassMethod(input)](./test-suite-a/testclass-class/testclassmethod-method) | `sealed` | TTypeParameterA | Test class method |
+| [virtualMethod()](./test-suite-a/testclass-class/virtualmethod-method) | | number | Overrides [virtualMethod()](./test-suite-a/testabstractclass-class/virtualmethod-method). |
+
+## See Also {#testclass-see-also}
+
+[TestAbstractClass](./test-suite-a/testabstractclass-class/)
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/publicabstractmethod-method.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/publicabstractmethod-method.md
new file mode 100644
index 000000000000..7f039a2242a7
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/publicabstractmethod-method.md
@@ -0,0 +1,11 @@
+# publicAbstractMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [publicAbstractMethod()](./test-suite-a/testclass-class/publicabstractmethod-method)
+
+A test public abstract method.
+
+## Signature {#publicabstractmethod-signature}
+
+```typescript
+publicAbstractMethod(): void;
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclasseventproperty-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclasseventproperty-property.md
new file mode 100644
index 000000000000..5309a5bebdc0
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclasseventproperty-property.md
@@ -0,0 +1,17 @@
+# testClassEventProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [testClassEventProperty](./test-suite-a/testclass-class/testclasseventproperty-property)
+
+Test class event property
+
+## Signature {#testclasseventproperty-signature}
+
+```typescript
+readonly testClassEventProperty: () => void;
+```
+
+**Type:** () => void
+
+## Remarks {#testclasseventproperty-remarks}
+
+Here are some remarks about the property
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassgetterproperty-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassgetterproperty-property.md
new file mode 100644
index 000000000000..252f535f42c6
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassgetterproperty-property.md
@@ -0,0 +1,19 @@
+# testClassGetterProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [testClassGetterProperty](./test-suite-a/testclass-class/testclassgetterproperty-property)
+
+Test class property with both a getter and a setter.
+
+## Signature {#testclassgetterproperty-signature}
+
+```typescript
+/** @virtual */
+get testClassGetterProperty(): number;
+set testClassGetterProperty(newValue: number);
+```
+
+**Type:** number
+
+## Remarks {#testclassgetterproperty-remarks}
+
+Here are some remarks about the getter-only property
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassmethod-method.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassmethod-method.md
new file mode 100644
index 000000000000..19b30bd6dd25
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassmethod-method.md
@@ -0,0 +1,32 @@
+# testClassMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [testClassMethod(input)](./test-suite-a/testclass-class/testclassmethod-method)
+
+Test class method
+
+## Signature {#testclassmethod-signature}
+
+```typescript
+/** @sealed */
+testClassMethod(input: TTypeParameterA): TTypeParameterA;
+```
+
+## Remarks {#testclassmethod-remarks}
+
+Here are some remarks about the method
+
+## Parameters {#testclassmethod-parameters}
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| input | TTypeParameterA | |
+
+## Returns {#testclassmethod-returns}
+
+**Return type:** TTypeParameterA
+
+## Throws {#testclassmethod-throws}
+
+Some sort of error in 1 case.
+
+Some other sort of error in another case. For example, a case where some thing happens.
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassproperty-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassproperty-property.md
new file mode 100644
index 000000000000..5ce1e6f7f288
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassproperty-property.md
@@ -0,0 +1,17 @@
+# testClassProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [testClassProperty](./test-suite-a/testclass-class/testclassproperty-property)
+
+Test class property
+
+## Signature {#testclassproperty-signature}
+
+```typescript
+readonly testClassProperty: TTypeParameterB;
+```
+
+**Type:** TTypeParameterB
+
+## Remarks {#testclassproperty-remarks}
+
+Here are some remarks about the property
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticmethod-method.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticmethod-method.md
new file mode 100644
index 000000000000..25859dfec07b
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticmethod-method.md
@@ -0,0 +1,23 @@
+# testClassStaticMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [testClassStaticMethod(foo)](./test-suite-a/testclass-class/testclassstaticmethod-method)
+
+Test class static method
+
+## Signature {#testclassstaticmethod-signature}
+
+```typescript
+static testClassStaticMethod(foo: number): string;
+```
+
+## Parameters {#testclassstaticmethod-parameters}
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| foo | number | Some number |
+
+## Returns {#testclassstaticmethod-returns}
+
+- Some string
+
+**Return type:** string
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticproperty-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticproperty-property.md
new file mode 100644
index 000000000000..6d6001f30f52
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/testclassstaticproperty-property.md
@@ -0,0 +1,13 @@
+# testClassStaticProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [testClassStaticProperty](./test-suite-a/testclass-class/testclassstaticproperty-property)
+
+Test static class property
+
+## Signature {#testclassstaticproperty-signature}
+
+```typescript
+static testClassStaticProperty: (foo: number) => string;
+```
+
+**Type:** (foo: number) => string
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/virtualmethod-method.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/virtualmethod-method.md
new file mode 100644
index 000000000000..7c2df61225ed
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testclass-class/virtualmethod-method.md
@@ -0,0 +1,16 @@
+# virtualMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestClass](./test-suite-a/testclass-class/) > [virtualMethod()](./test-suite-a/testclass-class/virtualmethod-method)
+
+Overrides [virtualMethod()](./test-suite-a/testabstractclass-class/virtualmethod-method).
+
+## Signature {#virtualmethod-signature}
+
+```typescript
+/** @override */
+protected virtualMethod(): number;
+```
+
+## Returns {#virtualmethod-returns}
+
+**Return type:** number
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testconst-variable.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testconst-variable.md
new file mode 100644
index 000000000000..660e92e199d6
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testconst-variable.md
@@ -0,0 +1,17 @@
+# testConst
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [testConst](./test-suite-a/testconst-variable)
+
+Test Constant
+
+**WARNING: This API is provided as a beta preview and may change without notice. Use at your own risk.**
+
+## Signature {#testconst-signature}
+
+```typescript
+testConst = 42
+```
+
+## Remarks {#testconst-remarks}
+
+Here are some remarks about the variable
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testconstwithemptydeprecatedblock-variable.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testconstwithemptydeprecatedblock-variable.md
new file mode 100644
index 000000000000..720e219ac11c
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testconstwithemptydeprecatedblock-variable.md
@@ -0,0 +1,15 @@
+# testConstWithEmptyDeprecatedBlock
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [testConstWithEmptyDeprecatedBlock](./test-suite-a/testconstwithemptydeprecatedblock-variable)
+
+I have a `@deprecated` tag with an empty comment block.
+
+**WARNING: This API is deprecated and will be removed in a future release.**
+
+## Signature {#testconstwithemptydeprecatedblock-signature}
+
+```typescript
+testConstWithEmptyDeprecatedBlock: string
+```
+
+**Type:** string
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testemptyinterface-interface/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testemptyinterface-interface/index.md
new file mode 100644
index 000000000000..d1f8b21536a5
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testemptyinterface-interface/index.md
@@ -0,0 +1,11 @@
+# TestEmptyInterface
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestEmptyInterface](./test-suite-a/testemptyinterface-interface/)
+
+An empty interface
+
+## Signature {#testemptyinterface-signature}
+
+```typescript
+export interface TestEmptyInterface
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/index.md
new file mode 100644
index 000000000000..97691f5456a2
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/index.md
@@ -0,0 +1,77 @@
+# TestEnum
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestEnum](./test-suite-a/testenum-enum/)
+
+Test Enum
+
+## Signature {#testenum-signature}
+
+```typescript
+export declare enum TestEnum
+```
+
+## Remarks {#testenum-remarks}
+
+Here are some remarks about the enum
+
+## Examples {#testenum-examples}
+
+### Example 1 {#testenum-example1}
+
+Some example
+
+```typescript
+const foo = TestEnum.TestEnumValue1
+```
+
+### Example 2 {#testenum-example2}
+
+Another example
+
+```ts
+const bar = TestEnum.TestEnumValue2
+```
+
+## Flags
+
+| Flag | Description |
+| --- | --- |
+| [TestEnumValue1](./test-suite-a/testenum-enum/testenumvalue1-enummember) | Test enum value 1 (string) |
+| [TestEnumValue2](./test-suite-a/testenum-enum/testenumvalue2-enummember) | Test enum value 2 (number) |
+| [TestEnumValue3](./test-suite-a/testenum-enum/testenumvalue3-enummember) | Test enum value 3 (default) |
+
+Test enum value 1 (string)
+
+### Signature {#testenumvalue1-signature}
+
+```typescript
+TestEnumValue1 = "test-enum-value-1"
+```
+
+### Remarks {#testenumvalue1-remarks}
+
+Here are some remarks about the enum value
+
+Test enum value 2 (number)
+
+### Signature {#testenumvalue2-signature}
+
+```typescript
+TestEnumValue2 = 3
+```
+
+### Remarks {#testenumvalue2-remarks}
+
+Here are some remarks about the enum value
+
+Test enum value 3 (default)
+
+### Signature {#testenumvalue3-signature}
+
+```typescript
+TestEnumValue3 = 4
+```
+
+### Remarks {#testenumvalue3-remarks}
+
+Here are some remarks about the enum value
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue1-enummember.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue1-enummember.md
new file mode 100644
index 000000000000..28dc1db6fc13
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue1-enummember.md
@@ -0,0 +1,15 @@
+# TestEnumValue1
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestEnum](./test-suite-a/testenum-enum/) > [TestEnumValue1](./test-suite-a/testenum-enum/testenumvalue1-enummember)
+
+Test enum value 1 (string)
+
+## Signature {#testenumvalue1-signature}
+
+```typescript
+TestEnumValue1 = "test-enum-value-1"
+```
+
+## Remarks {#testenumvalue1-remarks}
+
+Here are some remarks about the enum value
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue2-enummember.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue2-enummember.md
new file mode 100644
index 000000000000..058b0e361279
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue2-enummember.md
@@ -0,0 +1,15 @@
+# TestEnumValue2
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestEnum](./test-suite-a/testenum-enum/) > [TestEnumValue2](./test-suite-a/testenum-enum/testenumvalue2-enummember)
+
+Test enum value 2 (number)
+
+## Signature {#testenumvalue2-signature}
+
+```typescript
+TestEnumValue2 = 3
+```
+
+## Remarks {#testenumvalue2-remarks}
+
+Here are some remarks about the enum value
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue3-enummember.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue3-enummember.md
new file mode 100644
index 000000000000..38d5f92e2c0d
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testenum-enum/testenumvalue3-enummember.md
@@ -0,0 +1,15 @@
+# TestEnumValue3
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestEnum](./test-suite-a/testenum-enum/) > [TestEnumValue3](./test-suite-a/testenum-enum/testenumvalue3-enummember)
+
+Test enum value 3 (default)
+
+## Signature {#testenumvalue3-signature}
+
+```typescript
+TestEnumValue3 = 4
+```
+
+## Remarks {#testenumvalue3-remarks}
+
+Here are some remarks about the enum value
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunction-function.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunction-function.md
new file mode 100644
index 000000000000..5d6630bb2af4
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunction-function.md
@@ -0,0 +1,40 @@
+# testFunction
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [testFunction(testParameter, testOptionalParameter)](./test-suite-a/testfunction-function)
+
+Test function
+
+**WARNING: This API is provided as an alpha preview and may change without notice. Use at your own risk.**
+
+## Signature {#testfunction-signature}
+
+```typescript
+export declare function testFunction(testParameter: TTypeParameter, testOptionalParameter?: TTypeParameter): TTypeParameter;
+```
+
+### Type Parameters
+
+| Parameter | Constraint | Default | Description |
+| --- | --- | --- | --- |
+| TTypeParameter | [TestInterface](./test-suite-a/testinterface-interface/) | [TestInterface](./test-suite-a/testinterface-interface/) | A test type parameter |
+
+## Remarks {#testfunction-remarks}
+
+This is a test [link](./test-suite-a/testinterface-interface/) to another API member
+
+## Parameters {#testfunction-parameters}
+
+| Parameter | Modifiers | Type | Description |
+| --- | --- | --- | --- |
+| testParameter | | TTypeParameter | A test parameter |
+| testOptionalParameter | optional | TTypeParameter | |
+
+## Returns {#testfunction-returns}
+
+The provided parameter
+
+**Return type:** TTypeParameter
+
+## Throws {#testfunction-throws}
+
+An Error when something bad happens.
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturninginlinetype-function.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturninginlinetype-function.md
new file mode 100644
index 000000000000..9d6e2a5fb10c
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturninginlinetype-function.md
@@ -0,0 +1,20 @@
+# testFunctionReturningInlineType
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [testFunctionReturningInlineType()](./test-suite-a/testfunctionreturninginlinetype-function)
+
+Test function that returns an inline type
+
+## Signature {#testfunctionreturninginlinetype-signature}
+
+```typescript
+export declare function testFunctionReturningInlineType(): {
+ foo: number;
+ bar: TestEnum;
+};
+```
+
+## Returns {#testfunctionreturninginlinetype-returns}
+
+An inline type
+
+**Return type:** { foo: number; bar: [TestEnum](./test-suite-a/testenum-enum/); }
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturningintersectiontype-function.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturningintersectiontype-function.md
new file mode 100644
index 000000000000..5725f72cebf6
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturningintersectiontype-function.md
@@ -0,0 +1,21 @@
+# testFunctionReturningIntersectionType
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [testFunctionReturningIntersectionType()](./test-suite-a/testfunctionreturningintersectiontype-function)
+
+Test function that returns an inline type
+
+**WARNING: This API is deprecated and will be removed in a future release.**
+
+_This is a test deprecation notice. Here is a_ [_link_](./test-suite-a/testfunctionreturninguniontype-function) _to something else!_
+
+## Signature {#testfunctionreturningintersectiontype-signature}
+
+```typescript
+export declare function testFunctionReturningIntersectionType(): TestEmptyInterface & TestInterfaceWithTypeParameter;
+```
+
+## Returns {#testfunctionreturningintersectiontype-returns}
+
+an intersection type
+
+**Return type:** [TestEmptyInterface](./test-suite-a/testemptyinterface-interface/) & [TestInterfaceWithTypeParameter](./test-suite-a/testinterfacewithtypeparameter-interface/)<number>
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturninguniontype-function.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturninguniontype-function.md
new file mode 100644
index 000000000000..c5c7ef474ae1
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testfunctionreturninguniontype-function.md
@@ -0,0 +1,17 @@
+# testFunctionReturningUnionType
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [testFunctionReturningUnionType()](./test-suite-a/testfunctionreturninguniontype-function)
+
+Test function that returns an inline type
+
+## Signature {#testfunctionreturninguniontype-signature}
+
+```typescript
+export declare function testFunctionReturningUnionType(): string | TestInterface;
+```
+
+## Returns {#testfunctionreturninguniontype-returns}
+
+A union type
+
+**Return type:** string \| [TestInterface](./test-suite-a/testinterface-interface/)
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call_-callsignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call_-callsignature.md
new file mode 100644
index 000000000000..8ab0989a91c0
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call_-callsignature.md
@@ -0,0 +1,15 @@
+# (event: 'testCallSignature', listener: (input: unknown) => void): any
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [(event: 'testCallSignature', listener: (input: unknown) => void): any](./test-suite-a/testinterface-interface/_call_-callsignature)
+
+Test interface event call signature
+
+## Signature {#\_call\_-signature}
+
+```typescript
+(event: 'testCallSignature', listener: (input: unknown) => void): any;
+```
+
+## Remarks {#\_call\_-remarks}
+
+Here are some remarks about the event call signature
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call__1-callsignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call__1-callsignature.md
new file mode 100644
index 000000000000..b3055d99c94c
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_call__1-callsignature.md
@@ -0,0 +1,15 @@
+# (event: 'anotherTestCallSignature', listener: (input: number) => string): number
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [(event: 'anotherTestCallSignature', listener: (input: number) => string): number](./test-suite-a/testinterface-interface/_call__1-callsignature)
+
+Another example call signature
+
+## Signature {#\_call\_\_1-signature}
+
+```typescript
+(event: 'anotherTestCallSignature', listener: (input: number) => string): number;
+```
+
+## Remarks {#\_call\_\_1-remarks}
+
+Here are some remarks about the event call signature
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_new_-constructsignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_new_-constructsignature.md
new file mode 100644
index 000000000000..5d07085f787a
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/_new_-constructsignature.md
@@ -0,0 +1,15 @@
+# new (): TestInterface
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [new (): TestInterface](./test-suite-a/testinterface-interface/_new_-constructsignature)
+
+Test construct signature.
+
+## Signature {#\_new\_-signature}
+
+```typescript
+new (): TestInterface;
+```
+
+## Returns {#\_new\_-returns}
+
+**Return type:** [TestInterface](./test-suite-a/testinterface-interface/)
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/getterproperty-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/getterproperty-property.md
new file mode 100644
index 000000000000..8ba7a2708f75
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/getterproperty-property.md
@@ -0,0 +1,13 @@
+# getterProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [getterProperty](./test-suite-a/testinterface-interface/getterproperty-property)
+
+A test getter-only interface property.
+
+## Signature {#getterproperty-signature}
+
+```typescript
+get getterProperty(): boolean;
+```
+
+**Type:** boolean
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/index.md
new file mode 100644
index 000000000000..10a1e90a2f7d
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/index.md
@@ -0,0 +1,60 @@
+# TestInterface
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/)
+
+Test interface
+
+## Signature {#testinterface-signature}
+
+```typescript
+export interface TestInterface
+```
+
+## Remarks {#testinterface-remarks}
+
+Here are some remarks about the interface
+
+## Construct Signatures
+
+| ConstructSignature | Return Type | Description |
+| --- | --- | --- |
+| [new (): TestInterface](./test-suite-a/testinterface-interface/_new_-constructsignature) | [TestInterface](./test-suite-a/testinterface-interface/) | Test construct signature. |
+
+## Events
+
+| Property | Modifiers | Type | Description |
+| --- | --- | --- | --- |
+| [testClassEventProperty](./test-suite-a/testinterface-interface/testclasseventproperty-propertysignature) | `readonly` | () => void | Test interface event property |
+
+## Properties
+
+| Property | Modifiers | Default Value | Type | Description |
+| --- | --- | --- | --- | --- |
+| [getterProperty](./test-suite-a/testinterface-interface/getterproperty-property) | `readonly` | | boolean | A test getter-only interface property. |
+| [propertyWithBadInheritDocTarget](./test-suite-a/testinterface-interface/propertywithbadinheritdoctarget-propertysignature) | | | boolean | |
+| [setterProperty](./test-suite-a/testinterface-interface/setterproperty-property) | | | boolean | A test property with a getter and a setter. |
+| [testInterfaceProperty](./test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature) | | | number | Test interface property |
+| [testOptionalInterfaceProperty](./test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature) | `optional` | 0 | number | Test optional property |
+
+## Methods
+
+| Method | Return Type | Description |
+| --- | --- | --- |
+| [testInterfaceMethod()](./test-suite-a/testinterface-interface/testinterfacemethod-methodsignature) | void | Test interface method |
+
+## Call Signatures
+
+| CallSignature | Description |
+| --- | --- |
+| [(event: 'testCallSignature', listener: (input: unknown) => void): any](./test-suite-a/testinterface-interface/_call_-callsignature) | Test interface event call signature |
+| [(event: 'anotherTestCallSignature', listener: (input: number) => string): number](./test-suite-a/testinterface-interface/_call__1-callsignature) | Another example call signature |
+
+## See Also {#testinterface-see-also}
+
+[testInterfaceMethod()](./test-suite-a/testinterface-interface/testinterfacemethod-methodsignature)
+
+[testInterfaceProperty](./test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature)
+
+[testOptionalInterfaceProperty](./test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature)
+
+[testClassEventProperty](./test-suite-a/testinterface-interface/testclasseventproperty-propertysignature)
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/propertywithbadinheritdoctarget-propertysignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/propertywithbadinheritdoctarget-propertysignature.md
new file mode 100644
index 000000000000..e81429daac44
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/propertywithbadinheritdoctarget-propertysignature.md
@@ -0,0 +1,11 @@
+# propertyWithBadInheritDocTarget
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [propertyWithBadInheritDocTarget](./test-suite-a/testinterface-interface/propertywithbadinheritdoctarget-propertysignature)
+
+## Signature {#propertywithbadinheritdoctarget-signature}
+
+```typescript
+propertyWithBadInheritDocTarget: boolean;
+```
+
+**Type:** boolean
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/setterproperty-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/setterproperty-property.md
new file mode 100644
index 000000000000..00f56367f160
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/setterproperty-property.md
@@ -0,0 +1,14 @@
+# setterProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [setterProperty](./test-suite-a/testinterface-interface/setterproperty-property)
+
+A test property with a getter and a setter.
+
+## Signature {#setterproperty-signature}
+
+```typescript
+get setterProperty(): boolean;
+set setterProperty(newValue: boolean);
+```
+
+**Type:** boolean
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testclasseventproperty-propertysignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testclasseventproperty-propertysignature.md
new file mode 100644
index 000000000000..85d8d5b93b2f
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testclasseventproperty-propertysignature.md
@@ -0,0 +1,17 @@
+# testClassEventProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [testClassEventProperty](./test-suite-a/testinterface-interface/testclasseventproperty-propertysignature)
+
+Test interface event property
+
+## Signature {#testclasseventproperty-signature}
+
+```typescript
+readonly testClassEventProperty: () => void;
+```
+
+**Type:** () => void
+
+## Remarks {#testclasseventproperty-remarks}
+
+Here are some remarks about the event property
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfacemethod-methodsignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfacemethod-methodsignature.md
new file mode 100644
index 000000000000..211fdfa3ddb2
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfacemethod-methodsignature.md
@@ -0,0 +1,15 @@
+# testInterfaceMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [testInterfaceMethod()](./test-suite-a/testinterface-interface/testinterfacemethod-methodsignature)
+
+Test interface method
+
+## Signature {#testinterfacemethod-signature}
+
+```typescript
+testInterfaceMethod(): void;
+```
+
+## Remarks {#testinterfacemethod-remarks}
+
+Here are some remarks about the method
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature.md
new file mode 100644
index 000000000000..e09fcb713294
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature.md
@@ -0,0 +1,17 @@
+# testInterfaceProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [testInterfaceProperty](./test-suite-a/testinterface-interface/testinterfaceproperty-propertysignature)
+
+Test interface property
+
+## Signature {#testinterfaceproperty-signature}
+
+```typescript
+testInterfaceProperty: number;
+```
+
+**Type:** number
+
+## Remarks {#testinterfaceproperty-remarks}
+
+Here are some remarks about the property
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature.md
new file mode 100644
index 000000000000..c037d5610e6a
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature.md
@@ -0,0 +1,13 @@
+# testOptionalInterfaceProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterface](./test-suite-a/testinterface-interface/) > [testOptionalInterfaceProperty](./test-suite-a/testinterface-interface/testoptionalinterfaceproperty-propertysignature)
+
+Test optional property
+
+## Signature {#testoptionalinterfaceproperty-signature}
+
+```typescript
+testOptionalInterfaceProperty?: number;
+```
+
+**Type:** number
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/index.md
new file mode 100644
index 000000000000..704342163ce8
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/index.md
@@ -0,0 +1,31 @@
+# TestInterfaceExtendingOtherInterfaces
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterfaceExtendingOtherInterfaces](./test-suite-a/testinterfaceextendingotherinterfaces-interface/)
+
+Test interface that extends other interfaces
+
+## Signature {#testinterfaceextendingotherinterfaces-signature}
+
+```typescript
+export interface TestInterfaceExtendingOtherInterfaces extends TestInterface, TestMappedType, TestInterfaceWithTypeParameter
+```
+
+**Extends:** [TestInterface](./test-suite-a/testinterface-interface/), [TestMappedType](./test-suite-a/testmappedtype-typealias/), [TestInterfaceWithTypeParameter](./test-suite-a/testinterfacewithtypeparameter-interface/)<number>
+
+## Remarks {#testinterfaceextendingotherinterfaces-remarks}
+
+Here are some remarks about the interface
+
+## Methods
+
+| Method | Return Type | Description |
+| --- | --- | --- |
+| [testMethod(input)](./test-suite-a/testinterfaceextendingotherinterfaces-interface/testmethod-methodsignature) | number | Test interface method accepting a string and returning a number. |
+
+## See Also {#testinterfaceextendingotherinterfaces-see-also}
+
+- [TestInterface](./test-suite-a/testinterface-interface/)
+
+- [TestInterfaceWithTypeParameter](./test-suite-a/testinterfacewithtypeparameter-interface/)
+
+- [TestMappedType](./test-suite-a/testmappedtype-typealias/)
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/testmethod-methodsignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/testmethod-methodsignature.md
new file mode 100644
index 000000000000..8c0dd32030f8
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfaceextendingotherinterfaces-interface/testmethod-methodsignature.md
@@ -0,0 +1,27 @@
+# testMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterfaceExtendingOtherInterfaces](./test-suite-a/testinterfaceextendingotherinterfaces-interface/) > [testMethod(input)](./test-suite-a/testinterfaceextendingotherinterfaces-interface/testmethod-methodsignature)
+
+Test interface method accepting a string and returning a number.
+
+## Signature {#testmethod-signature}
+
+```typescript
+testMethod(input: string): number;
+```
+
+## Remarks {#testmethod-remarks}
+
+Here are some remarks about the method
+
+## Parameters {#testmethod-parameters}
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| input | string | A string |
+
+## Returns {#testmethod-returns}
+
+A number
+
+**Return type:** number
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/_indexer_-indexsignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/_indexer_-indexsignature.md
new file mode 100644
index 000000000000..dcfa5215c972
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/_indexer_-indexsignature.md
@@ -0,0 +1,13 @@
+# \[foo: number\]: { bar: string; }
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterfaceWithIndexSignature](./test-suite-a/testinterfacewithindexsignature-interface/) > [\[foo: number\]: { bar: string; }](./test-suite-a/testinterfacewithindexsignature-interface/_indexer_-indexsignature)
+
+Test index signature.
+
+## Signature {#\_indexer\_-signature}
+
+```typescript
+[foo: number]: {
+ bar: string;
+ };
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/index.md
new file mode 100644
index 000000000000..a3bd5063e563
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithindexsignature-interface/index.md
@@ -0,0 +1,17 @@
+# TestInterfaceWithIndexSignature
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterfaceWithIndexSignature](./test-suite-a/testinterfacewithindexsignature-interface/)
+
+An interface with an index signature.
+
+## Signature {#testinterfacewithindexsignature-signature}
+
+```typescript
+export interface TestInterfaceWithIndexSignature
+```
+
+## Index Signatures
+
+| IndexSignature | Description |
+| --- | --- |
+| [\[foo: number\]: { bar: string; }](./test-suite-a/testinterfacewithindexsignature-interface/_indexer_-indexsignature) | Test index signature. |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/index.md
new file mode 100644
index 000000000000..63d540c7ea65
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/index.md
@@ -0,0 +1,27 @@
+# TestInterfaceWithTypeParameter
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterfaceWithTypeParameter](./test-suite-a/testinterfacewithtypeparameter-interface/)
+
+Test interface with generic type parameter
+
+## Signature {#testinterfacewithtypeparameter-signature}
+
+```typescript
+export interface TestInterfaceWithTypeParameter
+```
+
+### Type Parameters
+
+| Parameter | Description |
+| --- | --- |
+| T | A type parameter |
+
+## Remarks {#testinterfacewithtypeparameter-remarks}
+
+Here are some remarks about the interface
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [testProperty](./test-suite-a/testinterfacewithtypeparameter-interface/testproperty-propertysignature) | T | A test interface property using generic type parameter |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/testproperty-propertysignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/testproperty-propertysignature.md
new file mode 100644
index 000000000000..8879124e471a
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testinterfacewithtypeparameter-interface/testproperty-propertysignature.md
@@ -0,0 +1,17 @@
+# testProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestInterfaceWithTypeParameter](./test-suite-a/testinterfacewithtypeparameter-interface/) > [testProperty](./test-suite-a/testinterfacewithtypeparameter-interface/testproperty-propertysignature)
+
+A test interface property using generic type parameter
+
+## Signature {#testproperty-signature}
+
+```typescript
+testProperty: T;
+```
+
+**Type:** T
+
+## Remarks {#testproperty-remarks}
+
+Here are some remarks about the property
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmappedtype-typealias/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmappedtype-typealias/index.md
new file mode 100644
index 000000000000..07b38df823d8
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmappedtype-typealias/index.md
@@ -0,0 +1,17 @@
+# TestMappedType
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestMappedType](./test-suite-a/testmappedtype-typealias/)
+
+Test Mapped Type, using [TestEnum](./test-suite-a/testenum-enum/)
+
+## Signature {#testmappedtype-signature}
+
+```typescript
+export type TestMappedType = {
+ [K in TestEnum]: boolean;
+};
+```
+
+## Remarks {#testmappedtype-remarks}
+
+Here are some remarks about the mapped type
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/foo-variable.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/foo-variable.md
new file mode 100644
index 000000000000..412aab1038d9
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/foo-variable.md
@@ -0,0 +1,11 @@
+# foo
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestModule](./test-suite-a/testmodule-namespace/) > [foo](./test-suite-a/testmodule-namespace/foo-variable)
+
+Test constant in module.
+
+## Signature {#foo-signature}
+
+```typescript
+foo = 2
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/index.md
new file mode 100644
index 000000000000..1d7718103821
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testmodule-namespace/index.md
@@ -0,0 +1,9 @@
+# TestModule
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestModule](./test-suite-a/testmodule-namespace/)
+
+## Variables
+
+| Variable | Modifiers | Type | Description |
+| --- | --- | --- | --- |
+| [foo](./test-suite-a/testmodule-namespace/foo-variable) | `readonly` | | Test constant in module. |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/index.md
new file mode 100644
index 000000000000..968d10a5bf40
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/index.md
@@ -0,0 +1,77 @@
+# TestNamespace
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/)
+
+Test Namespace
+
+## Signature {#testnamespace-signature}
+
+```typescript
+export declare namespace TestNamespace
+```
+
+## Remarks {#testnamespace-remarks}
+
+Here are some remarks about the namespace
+
+## Examples {#testnamespace-examples}
+
+### Example: TypeScript Example {#testnamespace-example1}
+
+```typescript
+const foo: Foo = {
+ bar: "Hello world!";
+ baz = 42;
+};
+```
+
+### Example: JavaScript Example {#testnamespace-example2}
+
+```javascript
+const foo = {
+ bar: "Hello world!";
+ baz = 42;
+};
+```
+
+## Interfaces
+
+| Interface | Alerts | Description |
+| --- | --- | --- |
+| [TestInterface](./test-suite-a/testnamespace-namespace/testinterface-interface/) | `Alpha` | Test interface |
+
+## Classes
+
+| Class | Description |
+| --- | --- |
+| [TestClass](./test-suite-a/testnamespace-namespace/testclass-class/) | Test class |
+
+## Enumerations
+
+| Enum | Description |
+| --- | --- |
+| [TestEnum](./test-suite-a/testnamespace-namespace/testenum-enum/) | Test Enum |
+
+## Types
+
+| TypeAlias | Description |
+| --- | --- |
+| [TestTypeAlias](./test-suite-a/testnamespace-namespace/testtypealias-typealias/) | Test Type-Alias |
+
+## Functions
+
+| Function | Return Type | Description |
+| --- | --- | --- |
+| [testFunction(testParameter)](./test-suite-a/testnamespace-namespace/testfunction-function) | number | Test function |
+
+## Variables
+
+| Variable | Alerts | Modifiers | Type | Description |
+| --- | --- | --- | --- | --- |
+| [TestConst](./test-suite-a/testnamespace-namespace/testconst-variable) | `Beta` | `readonly` | | Test Constant |
+
+## Namespaces
+
+| Namespace | Description |
+| --- | --- |
+| [TestSubNamespace](./test-suite-a/testnamespace-namespace/testsubnamespace-namespace/) | Test sub-namespace |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/_constructor_-constructor.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/_constructor_-constructor.md
new file mode 100644
index 000000000000..f3db36a74d71
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/_constructor_-constructor.md
@@ -0,0 +1,17 @@
+# (constructor)
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestClass](./test-suite-a/testnamespace-namespace/testclass-class/) > [(constructor)(testClassProperty)](./test-suite-a/testnamespace-namespace/testclass-class/_constructor_-constructor)
+
+Test class constructor
+
+## Signature {#\_constructor\_-signature}
+
+```typescript
+constructor(testClassProperty: string);
+```
+
+## Parameters {#\_constructor\_-parameters}
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| testClassProperty | string | See [testClassProperty](./test-suite-a/testclass-class/testclassproperty-property) |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/index.md
new file mode 100644
index 000000000000..a2a163202e9a
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/index.md
@@ -0,0 +1,29 @@
+# TestClass
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestClass](./test-suite-a/testnamespace-namespace/testclass-class/)
+
+Test class
+
+## Signature {#testclass-signature}
+
+```typescript
+class TestClass
+```
+
+## Constructors
+
+| Constructor | Description |
+| --- | --- |
+| [(constructor)(testClassProperty)](./test-suite-a/testnamespace-namespace/testclass-class/_constructor_-constructor) | Test class constructor |
+
+## Properties
+
+| Property | Modifiers | Type | Description |
+| --- | --- | --- | --- |
+| [testClassProperty](./test-suite-a/testnamespace-namespace/testclass-class/testclassproperty-property) | `readonly` | string | Test interface property |
+
+## Methods
+
+| Method | Return Type | Description |
+| --- | --- | --- |
+| [testClassMethod(testParameter)](./test-suite-a/testnamespace-namespace/testclass-class/testclassmethod-method) | Promise<string> | Test class method |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassmethod-method.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassmethod-method.md
new file mode 100644
index 000000000000..66a8a38f9e22
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassmethod-method.md
@@ -0,0 +1,31 @@
+# testClassMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestClass](./test-suite-a/testnamespace-namespace/testclass-class/) > [testClassMethod(testParameter)](./test-suite-a/testnamespace-namespace/testclass-class/testclassmethod-method)
+
+Test class method
+
+## Signature {#testclassmethod-signature}
+
+```typescript
+testClassMethod(testParameter: string): Promise;
+```
+
+## Parameters {#testclassmethod-parameters}
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| testParameter | string | A string |
+
+## Returns {#testclassmethod-returns}
+
+A Promise
+
+**Return type:** Promise<string>
+
+## Throws {#testclassmethod-throws}
+
+An Error when something happens for which an error should be thrown. Except in the cases where another kind of error is thrown. We don't throw this error in those cases.
+
+A different kind of error when a thing happens, but not when the first kind of error is thrown instead.
+
+😁
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassproperty-property.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassproperty-property.md
new file mode 100644
index 000000000000..9c993b1ff6d9
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testclass-class/testclassproperty-property.md
@@ -0,0 +1,13 @@
+# testClassProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestClass](./test-suite-a/testnamespace-namespace/testclass-class/) > [testClassProperty](./test-suite-a/testnamespace-namespace/testclass-class/testclassproperty-property)
+
+Test interface property
+
+## Signature {#testclassproperty-signature}
+
+```typescript
+readonly testClassProperty: string;
+```
+
+**Type:** string
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testconst-variable.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testconst-variable.md
new file mode 100644
index 000000000000..343608f24e1c
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testconst-variable.md
@@ -0,0 +1,13 @@
+# TestConst
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestConst](./test-suite-a/testnamespace-namespace/testconst-variable)
+
+Test Constant
+
+**WARNING: This API is provided as a beta preview and may change without notice. Use at your own risk.**
+
+## Signature {#testconst-signature}
+
+```typescript
+TestConst = "Hello world!"
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/index.md
new file mode 100644
index 000000000000..18920c2edba3
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/index.md
@@ -0,0 +1,34 @@
+# TestEnum
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestEnum](./test-suite-a/testnamespace-namespace/testenum-enum/)
+
+Test Enum
+
+## Signature {#testenum-signature}
+
+```typescript
+enum TestEnum
+```
+
+## Flags
+
+| Flag | Description |
+| --- | --- |
+| [TestEnumValue1](./test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue1-enummember) | Test enum value 1 |
+| [TestEnumValue2](./test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue2-enummember) | Test enum value 2 |
+
+Test enum value 1
+
+### Signature {#testenumvalue1-signature}
+
+```typescript
+TestEnumValue1 = 0
+```
+
+Test enum value 2
+
+### Signature {#testenumvalue2-signature}
+
+```typescript
+TestEnumValue2 = 1
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue1-enummember.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue1-enummember.md
new file mode 100644
index 000000000000..17fc20c60c5e
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue1-enummember.md
@@ -0,0 +1,11 @@
+# TestEnumValue1
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestEnum](./test-suite-a/testnamespace-namespace/testenum-enum/) > [TestEnumValue1](./test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue1-enummember)
+
+Test enum value 1
+
+## Signature {#testenumvalue1-signature}
+
+```typescript
+TestEnumValue1 = 0
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue2-enummember.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue2-enummember.md
new file mode 100644
index 000000000000..cc0f1df5018d
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue2-enummember.md
@@ -0,0 +1,11 @@
+# TestEnumValue2
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestEnum](./test-suite-a/testnamespace-namespace/testenum-enum/) > [TestEnumValue2](./test-suite-a/testnamespace-namespace/testenum-enum/testenumvalue2-enummember)
+
+Test enum value 2
+
+## Signature {#testenumvalue2-signature}
+
+```typescript
+TestEnumValue2 = 1
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testfunction-function.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testfunction-function.md
new file mode 100644
index 000000000000..29bb76f19c72
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testfunction-function.md
@@ -0,0 +1,27 @@
+# testFunction
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [testFunction(testParameter)](./test-suite-a/testnamespace-namespace/testfunction-function)
+
+Test function
+
+## Signature {#testfunction-signature}
+
+```typescript
+function testFunction(testParameter: number): number;
+```
+
+## Parameters {#testfunction-parameters}
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| testParameter | number | |
+
+## Returns {#testfunction-returns}
+
+A number
+
+**Return type:** number
+
+## Throws {#testfunction-throws}
+
+An Error
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/index.md
new file mode 100644
index 000000000000..33639ebe1a9a
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/index.md
@@ -0,0 +1,27 @@
+# TestInterface
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestInterface](./test-suite-a/testnamespace-namespace/testinterface-interface/)
+
+Test interface
+
+**WARNING: This API is provided as an alpha preview and may change without notice. Use at your own risk.**
+
+## Signature {#testinterface-signature}
+
+```typescript
+interface TestInterface extends TestInterfaceWithTypeParameter
+```
+
+**Extends:** [TestInterfaceWithTypeParameter](./test-suite-a/testinterfacewithtypeparameter-interface/)<[TestEnum](./test-suite-a/testnamespace-namespace/testenum-enum/)>
+
+## Properties
+
+| Property | Alerts | Type | Description |
+| --- | --- | --- | --- |
+| [testInterfaceProperty](./test-suite-a/testnamespace-namespace/testinterface-interface/testinterfaceproperty-propertysignature) | `Alpha` | boolean | Test interface property |
+
+## Methods
+
+| Method | Alerts | Return Type | Description |
+| --- | --- | --- | --- |
+| [testInterfaceMethod()](./test-suite-a/testnamespace-namespace/testinterface-interface/testinterfacemethod-methodsignature) | `Alpha` | void | Test interface method |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfacemethod-methodsignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfacemethod-methodsignature.md
new file mode 100644
index 000000000000..430c8bcc5eb2
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfacemethod-methodsignature.md
@@ -0,0 +1,13 @@
+# testInterfaceMethod
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestInterface](./test-suite-a/testnamespace-namespace/testinterface-interface/) > [testInterfaceMethod()](./test-suite-a/testnamespace-namespace/testinterface-interface/testinterfacemethod-methodsignature)
+
+Test interface method
+
+**WARNING: This API is provided as an alpha preview and may change without notice. Use at your own risk.**
+
+## Signature {#testinterfacemethod-signature}
+
+```typescript
+testInterfaceMethod(): void;
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfaceproperty-propertysignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfaceproperty-propertysignature.md
new file mode 100644
index 000000000000..0ed96d9bc24f
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testinterface-interface/testinterfaceproperty-propertysignature.md
@@ -0,0 +1,15 @@
+# testInterfaceProperty
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestInterface](./test-suite-a/testnamespace-namespace/testinterface-interface/) > [testInterfaceProperty](./test-suite-a/testnamespace-namespace/testinterface-interface/testinterfaceproperty-propertysignature)
+
+Test interface property
+
+**WARNING: This API is provided as an alpha preview and may change without notice. Use at your own risk.**
+
+## Signature {#testinterfaceproperty-signature}
+
+```typescript
+testInterfaceProperty: boolean;
+```
+
+**Type:** boolean
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testsubnamespace-namespace/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testsubnamespace-namespace/index.md
new file mode 100644
index 000000000000..55e0cbb15b66
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testsubnamespace-namespace/index.md
@@ -0,0 +1,11 @@
+# TestSubNamespace
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestSubNamespace](./test-suite-a/testnamespace-namespace/testsubnamespace-namespace/)
+
+Test sub-namespace
+
+## Signature {#testsubnamespace-signature}
+
+```typescript
+namespace TestSubNamespace
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testtypealias-typealias/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testtypealias-typealias/index.md
new file mode 100644
index 000000000000..6040f34e8a83
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/testtypealias-typealias/index.md
@@ -0,0 +1,11 @@
+# TestTypeAlias
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TestNamespace](./test-suite-a/testnamespace-namespace/) > [TestTypeAlias](./test-suite-a/testnamespace-namespace/testtypealias-typealias/)
+
+Test Type-Alias
+
+## Signature {#testtypealias-signature}
+
+```typescript
+type TestTypeAlias = boolean;
+```
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/typealias-typealias/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/typealias-typealias/index.md
new file mode 100644
index 000000000000..f7d3a9bb916b
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-a/typealias-typealias/index.md
@@ -0,0 +1,15 @@
+# TypeAlias
+
+[Packages](./) > [test-suite-a](./test-suite-a/) > [TypeAlias](./test-suite-a/typealias-typealias/)
+
+Test Type-Alias
+
+## Signature {#typealias-signature}
+
+```typescript
+export type TypeAlias = string;
+```
+
+## Remarks {#typealias-remarks}
+
+Here are some remarks about the type alias
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/foo-interface/bar-propertysignature.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/foo-interface/bar-propertysignature.md
new file mode 100644
index 000000000000..d5f9594c2ebe
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/foo-interface/bar-propertysignature.md
@@ -0,0 +1,17 @@
+# bar
+
+[Packages](./) > [test-suite-b](./test-suite-b/) > [Foo](./test-suite-b/foo-interface/) > [bar](./test-suite-b/foo-interface/bar-propertysignature)
+
+Test Enum
+
+## Signature {#bar-signature}
+
+```typescript
+bar: TestEnum;
+```
+
+**Type:** [TestEnum](./test-suite-a/testenum-enum/)
+
+## Remarks {#bar-remarks}
+
+Here are some remarks about the enum
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/foo-interface/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/foo-interface/index.md
new file mode 100644
index 000000000000..9f9671ba3479
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/foo-interface/index.md
@@ -0,0 +1,17 @@
+# Foo
+
+[Packages](./) > [test-suite-b](./test-suite-b/) > [Foo](./test-suite-b/foo-interface/)
+
+Bar
+
+## Signature {#foo-signature}
+
+```typescript
+export interface Foo
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [bar](./test-suite-b/foo-interface/bar-propertysignature) | [TestEnum](./test-suite-a/testenum-enum/) | Test Enum |
diff --git a/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/index.md b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/index.md
new file mode 100644
index 000000000000..ad85c0991f22
--- /dev/null
+++ b/tools/api-markdown-documenter/src/test/snapshots/markdown/simple-suite-test/deep-config/test-suite-b/index.md
@@ -0,0 +1,9 @@
+# test-suite-b
+
+[Packages](./) > [test-suite-b](./test-suite-b/)
+
+## Interfaces
+
+| Interface | Description |
+| --- | --- |
+| [Foo](./test-suite-b/foo-interface/) | Bar |
diff --git a/tools/api-markdown-documenter/src/utilities/TypeUtilities.ts b/tools/api-markdown-documenter/src/utilities/TypeUtilities.ts
new file mode 100644
index 000000000000..c6d3db8c28b7
--- /dev/null
+++ b/tools/api-markdown-documenter/src/utilities/TypeUtilities.ts
@@ -0,0 +1,29 @@
+/*!
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
+ * Licensed under the MIT License.
+ */
+
+/**
+ * Type that removes `readonly` from fields.
+ */
+export type Mutable = { -readonly [P in keyof T]: T[P] };
+
+/**
+ * Represents a value that can be either a direct value of type `T` or a function that returns a value of type `T` given some parameters.
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export type ValueOrDerived = T | ((..._arguments: TArguments) => T);
+
+/**
+ * Returns the value of a `ValueOrDerived` object, either by directly returning the value or by calling the function with the provided arguments.
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function getValueOrDerived(
+ valueOrDerived: ValueOrDerived,
+ ..._arguments: TArguments
+): T {
+ if (typeof valueOrDerived === "function") {
+ return (valueOrDerived as (..._arguments: TArguments) => T)(..._arguments);
+ }
+ return valueOrDerived;
+}
diff --git a/tools/api-markdown-documenter/src/utilities/index.ts b/tools/api-markdown-documenter/src/utilities/index.ts
index bec47e1e4f08..d3e4969ef77e 100644
--- a/tools/api-markdown-documenter/src/utilities/index.ts
+++ b/tools/api-markdown-documenter/src/utilities/index.ts
@@ -3,7 +3,8 @@
* Licensed under the MIT License.
*/
-// All of the utilities here are meant to be used outside of this directory.
-// eslint-disable-next-line no-restricted-syntax
+/* eslint-disable no-restricted-syntax */
+
export * from "./ApiItemUtilities.js";
-export { injectSeparator } from "./ArrayUtilities.js";
+export * from "./ArrayUtilities.js";
+export * from "./TypeUtilities.js";