feat(api-markdown-documenter): Add `lintApiModel` API (#22250)
See the documentation updates for more details.
This commit is contained in:
Родитель
ecd60634c3
Коммит
d25f328779
|
@ -5,6 +5,14 @@
|
|||
- Added the following new utility function to `ApiItemUtilities`:
|
||||
1. `ancestryHasModifierTag`: Checks if the provided API item or ancestor items are tagged with the specified [modifier tag](https://tsdoc.org/pages/spec/tag_kinds/#modifier-tags).
|
||||
|
||||
### Beta
|
||||
|
||||
- Adds prototype functionality for "linting" an API Model (i.e., the set of packages whose docs are published as a single "suite").
|
||||
Can be invoked by importing `lintApiModel` from `@fluid-tools/api-markdown-documenter/beta`.
|
||||
Returns a set of TSDoc-related "errors" discovered while walking the API Model.
|
||||
- The primary goal of this tool is to detect issues that `API-Extractor` cannot validate on a per-package basis when generating API reports.
|
||||
For now, this is limited to validating `@link` and `@inheritDoc` tags to ensure that symbolic references are valid within the API Model.
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
- Updated `loadModel` to take a configuration object, rather than individual parameters.
|
||||
|
|
|
@ -16,7 +16,7 @@ One may be added in the future, but for now this library is intended to be consu
|
|||
The following terms are leveraged heavily in this package's APIs and documentation.
|
||||
|
||||
- **API Model**: Refers to a complete API suite, comprised of one or more packages.
|
||||
This often corresponds to all of the packages in the mono-repo, or a series of packages that are published together.
|
||||
This often corresponds to all of the packages in the mono-repo, or a series of packages whose API docs are published together.
|
||||
It is generally represented via the [ApiModel][] type, from the [@microsoft/api-extractor-model](https://github.com/microsoft/rushstack/tree/main/libraries/api-extractor-model) library.
|
||||
- In some places, this library refers to an `API Model` in terms of a directory or directory path.
|
||||
In these cases, it is referring to a directory that contains the set of `.api.json` files (generated per-package by `API-Extractor`).
|
||||
|
@ -203,29 +203,41 @@ If you would like to add rendering support for a custom `Documentation Domain` n
|
|||
|
||||
If you would like to change any or all of this library's default rendering policies, you may simply override the default policies for the desired `type`s.
|
||||
|
||||
## ToHtml Transformation
|
||||
|
||||
This library now includes preview APIs for transforming `Documentation Domain` trees to HTML syntax trees using [hast](https://github.com/syntax-tree/hast).
|
||||
The main entry-point for this functionality is `documentToHtml`.
|
||||
|
||||
## HtmlRenderer
|
||||
|
||||
This library now includes preview APIs for HTML rendering.
|
||||
|
||||
Like the [MarkdownRenderer](#markdownrenderer), we offer a `HtmlRenderer.renderApiModel` function that operates in much the same way, but outputs `HTML`-formatted documents instead of Markdown.
|
||||
|
||||
These APIs are still in preview, and may change without notice.
|
||||
## Preview APIs
|
||||
|
||||
The following APIs are still in preview, and may change without notice.
|
||||
Use at your own risk.
|
||||
|
||||
## ToHtml Transformation
|
||||
|
||||
This library now includes preview APIs for transforming `Documentation Domain` trees to HTML syntax trees using [hast](https://github.com/syntax-tree/hast).
|
||||
|
||||
To use, import the `documentToHtml` function from `@fluid-tools/api-markdown-documenter/beta`.
|
||||
|
||||
### lintApiModel
|
||||
|
||||
This library includes a preview API for "linting" an API Model.
|
||||
|
||||
To use, import the `lintApiModel` function from `@fluid-tools/api-markdown-documenter/beta`.
|
||||
|
||||
This function returns a set of TSDoc-related "errors" discovered while walking the API Model.
|
||||
|
||||
The primary goal of this tool is to detect issues that `API-Extractor` cannot validate on a per-package basis when generating API reports.
|
||||
|
||||
For now, this is limited to validating `@link` and `@inheritDoc` tags to ensure that symbolic references are valid within the API Model.
|
||||
Other validation may be added in the future as needed.
|
||||
|
||||
## Upcoming Work
|
||||
|
||||
- Add extensibility options for `DocNode` transformations
|
||||
- If a consumer has a custom tsdoc config associated with their API-Extractor setup, this will be needed.
|
||||
|
||||
### Known Bugs
|
||||
|
||||
- Types that extend or implement types with generic parameters result in signatures rendered with missing closing `>`s.
|
||||
|
||||
### Documentation Improvements
|
||||
|
||||
- Intro sandbox (api report)
|
||||
|
@ -247,8 +259,8 @@ Use at your own risk.
|
|||
|
||||
- Support placing documents _within_ their own hierarchy (support for the "index" model used by systems like DocFX)
|
||||
- Pre-canned policies (flat, index, adjacency)
|
||||
- Handle multiple package entry-points
|
||||
- Add separate HTML transformation path, for consumers that want to go straight to HTML
|
||||
- Add `documentToHtml` API that generates `mdast` output.
|
||||
- Update rendering APIs to leverage the `mdast` and `hast` domain outputs.
|
||||
|
||||
<!-- AUTO-GENERATED-CONTENT:START (README_FOOTER) -->
|
||||
|
||||
|
|
|
@ -516,6 +516,28 @@ export class LinkNode extends DocumentationParentNodeBase<SingleLineDocumentatio
|
|||
readonly type = DocumentationNodeType.Link;
|
||||
}
|
||||
|
||||
// @beta
|
||||
export function lintApiModel(configuration: LintApiModelConfiguration): Promise<LinterErrors | undefined>;
|
||||
|
||||
// @beta
|
||||
export interface LintApiModelConfiguration extends ConfigurationBase {
|
||||
apiModel: ApiModel;
|
||||
}
|
||||
|
||||
// @beta
|
||||
export interface LinterErrors {
|
||||
readonly referenceErrors: ReadonlySet<LinterReferenceError>;
|
||||
}
|
||||
|
||||
// @beta
|
||||
export interface LinterReferenceError {
|
||||
readonly linkText: string | undefined;
|
||||
readonly packageName: string;
|
||||
readonly referenceTarget: string;
|
||||
readonly sourceItem: string;
|
||||
readonly tagName: string;
|
||||
}
|
||||
|
||||
// @public
|
||||
export function loadModel(options: LoadModelOptions): Promise<ApiModel>;
|
||||
|
||||
|
|
|
@ -488,6 +488,28 @@ export class LinkNode extends DocumentationParentNodeBase<SingleLineDocumentatio
|
|||
readonly type = DocumentationNodeType.Link;
|
||||
}
|
||||
|
||||
// @beta
|
||||
export function lintApiModel(configuration: LintApiModelConfiguration): Promise<LinterErrors | undefined>;
|
||||
|
||||
// @beta
|
||||
export interface LintApiModelConfiguration extends ConfigurationBase {
|
||||
apiModel: ApiModel;
|
||||
}
|
||||
|
||||
// @beta
|
||||
export interface LinterErrors {
|
||||
readonly referenceErrors: ReadonlySet<LinterReferenceError>;
|
||||
}
|
||||
|
||||
// @beta
|
||||
export interface LinterReferenceError {
|
||||
readonly linkText: string | undefined;
|
||||
readonly packageName: string;
|
||||
readonly referenceTarget: string;
|
||||
readonly sourceItem: string;
|
||||
readonly tagName: string;
|
||||
}
|
||||
|
||||
// @public
|
||||
export function loadModel(options: LoadModelOptions): Promise<ApiModel>;
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ import type { ConfigurationBase } from "./ConfigurationBase.js";
|
|||
|
||||
/**
|
||||
* {@link lintApiModel} configuration.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export interface LintApiModelConfiguration extends ConfigurationBase {
|
||||
/**
|
||||
|
@ -45,8 +47,10 @@ const defaultLintApiModelConfiguration: Required<Omit<LintApiModelConfiguration,
|
|||
|
||||
/**
|
||||
* An error resulting from a reference tag (e.g., `link` or `inheritDoc` tags) with an invalid target.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export interface ReferenceError {
|
||||
export interface LinterReferenceError {
|
||||
/**
|
||||
* The tag name with the invalid reference.
|
||||
*/
|
||||
|
@ -58,7 +62,7 @@ export interface ReferenceError {
|
|||
readonly sourceItem: string;
|
||||
|
||||
/**
|
||||
* The name of the package that the {@link ReferenceError.sourceItem} belongs to.
|
||||
* The name of the package that the {@link LinterReferenceError.sourceItem} belongs to.
|
||||
*/
|
||||
readonly packageName: string;
|
||||
|
||||
|
@ -78,11 +82,13 @@ export interface ReferenceError {
|
|||
* @remarks Used while walking the API model to accumulate errors, and converted to {@link LinterErrors} to return to the caller.
|
||||
*/
|
||||
interface MutableLinterErrors {
|
||||
readonly referenceErrors: Set<ReferenceError>;
|
||||
readonly referenceErrors: Set<LinterReferenceError>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Errors found during linting.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export interface LinterErrors {
|
||||
// TODO: malformed tag errors
|
||||
|
@ -90,7 +96,7 @@ export interface LinterErrors {
|
|||
/**
|
||||
* Errors related to reference tags (e.g., `link` or `inheritDoc` tags) with invalid targets.
|
||||
*/
|
||||
readonly referenceErrors: ReadonlySet<ReferenceError>;
|
||||
readonly referenceErrors: ReadonlySet<LinterReferenceError>;
|
||||
|
||||
// TODO: add other error kinds as needed.
|
||||
}
|
||||
|
@ -100,6 +106,8 @@ export interface LinterErrors {
|
|||
*
|
||||
* @returns The set of errors encountered during linting, if any were found.
|
||||
* Otherwise, `undefined`.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export async function lintApiModel(
|
||||
configuration: LintApiModelConfiguration,
|
||||
|
@ -113,7 +121,7 @@ export async function lintApiModel(
|
|||
logger.verbose("Linting API model...");
|
||||
|
||||
const errors: MutableLinterErrors = {
|
||||
referenceErrors: new Set<ReferenceError>(),
|
||||
referenceErrors: new Set<LinterReferenceError>(),
|
||||
};
|
||||
lintApiItem(apiModel, apiModel, optionsWithDefaults, errors);
|
||||
const anyErrors = errors.referenceErrors.size > 0;
|
||||
|
@ -291,7 +299,7 @@ function checkLinkTag(
|
|||
linkTag: DocLinkTag,
|
||||
apiItem: ApiItem,
|
||||
apiModel: ApiModel,
|
||||
): ReferenceError | undefined {
|
||||
): LinterReferenceError | undefined {
|
||||
// If the link tag was parsed correctly (which we know it was in this case, because we have a `DocLinkTag`), then we don't have to worry about syntax validation.
|
||||
|
||||
// If the link points to some external URL, no-op.
|
||||
|
@ -331,7 +339,7 @@ function checkInheritDocTag(
|
|||
inheritDocTag: DocInheritDocTag,
|
||||
associatedItem: ApiDocumentedItem,
|
||||
apiModel: ApiModel,
|
||||
): ReferenceError | undefined {
|
||||
): LinterReferenceError | undefined {
|
||||
if (inheritDocTag?.declarationReference === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,12 @@ export type { ConfigurationBase } from "./ConfigurationBase.js";
|
|||
export type { FileSystemConfiguration } from "./FileSystemConfiguration.js";
|
||||
export type { Heading } from "./Heading.js";
|
||||
export type { Link, UrlTarget } from "./Link.js";
|
||||
export {
|
||||
lintApiModel,
|
||||
type LintApiModelConfiguration,
|
||||
type LinterErrors,
|
||||
type LinterReferenceError,
|
||||
} from "./LintApiModel.js";
|
||||
export { loadModel, type LoadModelOptions } from "./LoadModel.js";
|
||||
export {
|
||||
defaultConsoleLogger,
|
||||
|
|
Загрузка…
Ссылка в новой задаче