Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(api-markdown-documenter): Unify "file-safe-name" helper utilities #23394

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions tools/api-markdown-documenter/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ await MarkdownRenderer.renderApiModel({
- `RenderHtmlConfig` -> `RenderHtmlConfiguration`
- `ToHtmlConfig` -> `ToHtmlConfiguration`

#### Utility function renames

- `ApiItemUtilities.getQualifiedApiItemName` -> `ApiItemUtilities.getFileSafeNameForApiItem`

#### Configuration properties made `readonly`

- `ApiItemTransformations`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ declare namespace ApiItemUtilities {
getDefaultValueBlock,
getDeprecatedBlock,
getExampleBlocks,
getFileSafeNameForApiItem,
getModifiers,
getModifierTags,
getQualifiedApiItemName,
getReleaseTag,
getReturnsBlock,
getSeeBlocks,
Expand Down Expand Up @@ -395,6 +395,9 @@ function getDeprecatedBlock(apiItem: ApiItem): DocSection | undefined;
// @public
function getExampleBlocks(apiItem: ApiItem): readonly DocSection[] | undefined;

// @public
function getFileSafeNameForApiItem(apiItem: ApiItem): string;

// @public
function getHeadingForApiItem(apiItem: ApiItem, config: ApiItemTransformationConfiguration, headingLevel?: number): Heading;

Expand All @@ -407,9 +410,6 @@ function getModifiers(apiItem: ApiItem, modifiersToOmit?: ApiModifier[]): ApiMod
// @public
function getModifierTags(apiItem: ApiItem): ReadonlySet<string>;

// @public
function getQualifiedApiItemName(apiItem: ApiItem): string;

// @public
function getReleaseTag(apiItem: ApiItem): ReleaseTag | undefined;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ declare namespace ApiItemUtilities {
getDefaultValueBlock,
getDeprecatedBlock,
getExampleBlocks,
getFileSafeNameForApiItem,
getModifiers,
getModifierTags,
getQualifiedApiItemName,
getReleaseTag,
getReturnsBlock,
getSeeBlocks,
Expand Down Expand Up @@ -395,6 +395,9 @@ function getDeprecatedBlock(apiItem: ApiItem): DocSection | undefined;
// @public
function getExampleBlocks(apiItem: ApiItem): readonly DocSection[] | undefined;

// @public
function getFileSafeNameForApiItem(apiItem: ApiItem): string;

// @public
function getHeadingForApiItem(apiItem: ApiItem, config: ApiItemTransformationConfiguration, headingLevel?: number): Heading;

Expand All @@ -407,9 +410,6 @@ function getModifiers(apiItem: ApiItem, modifiersToOmit?: ApiModifier[]): ApiMod
// @public
function getModifierTags(apiItem: ApiItem): ReadonlySet<string>;

// @public
function getQualifiedApiItemName(apiItem: ApiItem): string;

// @public
function getReleaseTag(apiItem: ApiItem): ReleaseTag | undefined;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ declare namespace ApiItemUtilities {
getDefaultValueBlock,
getDeprecatedBlock,
getExampleBlocks,
getFileSafeNameForApiItem,
getModifiers,
getModifierTags,
getQualifiedApiItemName,
getReleaseTag,
getReturnsBlock,
getSeeBlocks,
Expand Down Expand Up @@ -395,6 +395,9 @@ function getDeprecatedBlock(apiItem: ApiItem): DocSection | undefined;
// @public
function getExampleBlocks(apiItem: ApiItem): readonly DocSection[] | undefined;

// @public
function getFileSafeNameForApiItem(apiItem: ApiItem): string;

// @public
function getHeadingForApiItem(apiItem: ApiItem, config: ApiItemTransformationConfiguration, headingLevel?: number): Heading;

Expand All @@ -407,9 +410,6 @@ function getModifiers(apiItem: ApiItem, modifiersToOmit?: ApiModifier[]): ApiMod
// @public
function getModifierTags(apiItem: ApiItem): ReadonlySet<string>;

// @public
function getQualifiedApiItemName(apiItem: ApiItem): string;

// @public
function getReleaseTag(apiItem: ApiItem): ReleaseTag | undefined;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ export {
getDefaultValueBlock,
getDeprecatedBlock,
getExampleBlocks,
getFileSafeNameForApiItem,
getModifiers,
getModifierTags,
getQualifiedApiItemName,
getReleaseTag,
getReturnsBlock,
getSeeBlocks,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { type ApiItem, ApiItemKind, ReleaseTag } from "@microsoft/api-extractor-
import type { Heading } from "../Heading.js";
import type { Link } from "../Link.js";
import {
getQualifiedApiItemName,
getFileSafeNameForApiItem,
getReleaseTag,
getApiItemKind,
type ValidApiItemKind,
Expand Down Expand Up @@ -280,7 +280,7 @@ function getHeadingIdForApiItem(
// Generate ID information for everything back to that point
let hierarchyItem = apiItem;
while (!doesItemRequireOwnDocument(hierarchyItem, config.documentBoundaries)) {
const qualifiedName = getQualifiedApiItemName(hierarchyItem);
const qualifiedName = getFileSafeNameForApiItem(hierarchyItem);

// Since we're walking up the tree, we'll build the string from the end for simplicity
baseName = baseName === undefined ? qualifiedName : `${qualifiedName}-${baseName}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import {

import {
type ApiMemberKind,
getQualifiedApiItemName,
getUnscopedPackageName,
getSafeFilenameForName,
getApiItemKind,
getConciseSignature,
getFileSafeNameForApiItem,
getFileSafeNameForApiItemName,
getReleaseTag,
getSingleLineExcerptText,
getUnscopedPackageName,
isDeprecated,
getReleaseTag,
getApiItemKind,
} from "../../utilities/index.js";

/**
Expand Down Expand Up @@ -286,10 +286,10 @@ export namespace DefaultDocumentationSuiteOptions {
return "index";
}
case ApiItemKind.Package: {
return getSafeFilenameForName(getUnscopedPackageName(apiItem as ApiPackage));
return getFileSafeNameForApiItemName(getUnscopedPackageName(apiItem as ApiPackage));
}
default: {
return getQualifiedApiItemName(apiItem);
return getFileSafeNameForApiItem(apiItem);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {
import {
type ApiFunctionLike,
injectSeparator,
getQualifiedApiItemName,
getFileSafeNameForApiItem,
getSeeBlocks,
getThrowsBlocks,
getDeprecatedBlock,
Expand Down Expand Up @@ -101,7 +101,7 @@ export function createSignatureSection(

return wrapInSection(contents, {
title: "Signature",
id: `${getQualifiedApiItemName(apiItem)}-signature`,
id: `${getFileSafeNameForApiItem(apiItem)}-signature`,
});
}
}
Expand Down Expand Up @@ -138,7 +138,7 @@ export function createSeeAlsoSection(

return wrapInSection(contents, {
title: "See Also",
id: `${getQualifiedApiItemName(apiItem)}-see-also`,
id: `${getFileSafeNameForApiItem(apiItem)}-see-also`,
});
}

Expand Down Expand Up @@ -489,7 +489,7 @@ export function createRemarksSection(
tsdocNodeTransformOptions,
),
],
{ title: "Remarks", id: `${getQualifiedApiItemName(apiItem)}-remarks` },
{ title: "Remarks", id: `${getFileSafeNameForApiItem(apiItem)}-remarks` },
);
}

Expand Down Expand Up @@ -525,7 +525,7 @@ export function createThrowsSection(

return wrapInSection(paragraphs, {
title: headingText,
id: `${getQualifiedApiItemName(apiItem)}-throws`,
id: `${getFileSafeNameForApiItem(apiItem)}-throws`,
});
}

Expand Down Expand Up @@ -609,7 +609,7 @@ export function createExamplesSection(

return wrapInSection(exampleSections, {
title: headingText,
id: `${getQualifiedApiItemName(apiItem)}-examples`,
id: `${getFileSafeNameForApiItem(apiItem)}-examples`,
});
}

Expand Down Expand Up @@ -727,7 +727,7 @@ function createExampleSection(
exampleParagraph = stripTitleFromParagraph(exampleParagraph, exampleTitle, logger);
}

const headingId = `${getQualifiedApiItemName(example.apiItem)}-example${
const headingId = `${getFileSafeNameForApiItem(example.apiItem)}-example${
example.exampleNumber ?? ""
}`;

Expand Down Expand Up @@ -885,7 +885,7 @@ export function createParametersSection(
[createParametersSummaryTable(apiFunctionLike.parameters, apiFunctionLike, config)],
{
title: "Parameters",
id: `${getQualifiedApiItemName(apiFunctionLike)}-parameters`,
id: `${getFileSafeNameForApiItem(apiFunctionLike)}-parameters`,
},
);
}
Expand Down Expand Up @@ -944,7 +944,7 @@ export function createReturnsSection(
? undefined
: wrapInSection(children, {
title: "Returns",
id: `${getQualifiedApiItemName(apiItem)}-returns`,
id: `${getFileSafeNameForApiItem(apiItem)}-returns`,
});
}

Expand Down
59 changes: 38 additions & 21 deletions tools/api-markdown-documenter/src/utilities/ApiItemUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,11 @@ export function getFilteredParent(apiItem: ApiItem): ApiItem | undefined {
}

/**
* Adjusts the name of the item as needed.
* Accounts for method overloads by adding a suffix such as "myMethod_2".
*
* @param apiItem - The API item for which the qualified name is being queried.
*
* @public
* Gets a qualified representation of the API item's display name, accounting for function/method overloads
* by adding a suffix (such as "myMethod_2") as needed to guarantee uniqueness.
*/
export function getQualifiedApiItemName(apiItem: ApiItem): string {
let qualifiedName: string = getSafeFilenameForName(apiItem.displayName);
function getQualifiedDisplayName(apiItem: ApiItem): string {
let qualifiedName: string = apiItem.displayName;
if (ApiParameterListMixin.isBaseClassOf(apiItem) && apiItem.overloadIndex > 1) {
// Subtract one for compatibility with earlier releases of API Documenter.
// (This will get revamped when we fix GitHub issue #1308)
Expand All @@ -183,6 +179,40 @@ export function getQualifiedApiItemName(apiItem: ApiItem): string {
return qualifiedName;
}

/**
* Gets a filename-safe representation of the provided API item name.
*
* @remarks
* - Handles invalid filename characters.
*/
export function getFileSafeNameForApiItemName(apiItemName: string): string {
// eslint-disable-next-line unicorn/better-regex, no-useless-escape
const badFilenameCharsRegExp: RegExp = /[^a-z0-9_\-\.]/gi;

// Note: This can introduce naming collisions.
// TODO: once the following issue has been resolved in api-extractor, we may be able to clean this up:
// https://github.com/microsoft/rushstack/issues/1308
return apiItemName.replace(badFilenameCharsRegExp, "_").toLowerCase();
}

/**
* Gets a filename-safe representation of the API item's display name.
*
* @remarks
* - Handles invalid filename characters.
*
* - Qualifies the API item's name, accounting for function/method overloads by adding a suffix (such as "myMethod_2")
* as needed to guarantee uniqueness.
*
* @param apiItem - The API item for which the qualified name is being queried.
*
* @public
*/
export function getFileSafeNameForApiItem(apiItem: ApiItem): string {
const qualifiedDisplayName = getQualifiedDisplayName(apiItem);
return getFileSafeNameForApiItemName(qualifiedDisplayName);
}

/**
* Gets the unscoped version of the provided package's name.
*
Expand Down Expand Up @@ -550,19 +580,6 @@ export function getConciseSignature(apiItem: ApiItem): string {
return apiItem.displayName;
}

/**
* Converts bad filename characters to underscores.
*/
export function getSafeFilenameForName(apiItemName: string): string {
// eslint-disable-next-line unicorn/better-regex, no-useless-escape
const badFilenameCharsRegExp: RegExp = /[^a-z0-9_\-\.]/gi;

// Note: This can introduce naming collisions.
// TODO: once the following issue has been resolved in api-extractor, we may be able to clean this up:
// https://github.com/microsoft/rushstack/issues/1308
return apiItemName.replace(badFilenameCharsRegExp, "_").toLowerCase();
}

/**
* Extracts the text from the provided excerpt and adjusts it to be on a single line.
*
Expand Down
Loading