Skip to content
Open
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
106 changes: 0 additions & 106 deletions docs/infra/api-markdown-documenter/admonition-node.mjs

This file was deleted.

48 changes: 48 additions & 0 deletions docs/infra/api-markdown-documenter/admonition.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/

//@ts-check
/** @typedef {import("mdast").BlockContent} BlockContent */
/** @typedef {import("mdast-util-directive").ContainerDirective} ContainerDirective */
/** @typedef {import("mdast").PhrasingContent} PhrasingContent */
/** @typedef {"note" | "tip" | "info" | "warning" | "danger"} AdmonitionKind */

/**
* Generates Markdown representing a Docusaurus Admonition.
*
* @param {BlockContent[]} body - Admonition body content.
* @param {AdmonitionKind} admonitionKind - The kind of admonition. See {@link https://docusaurus.io/docs/markdown-features/admonitions}.
* @param {string | undefined} title - (Optional) Title text for the admonition.
*
* @returns {ContainerDirective} The Markdown AST representing the admonition.
*/
export function createAdmonition(body, admonitionKind, title) {
/** @type {BlockContent[]} */
const children = [];

// If the admonition has a title, prepend it to the list of children with the `directiveLabel` property set.
if (title !== undefined) {
children.push({
type: "paragraph",
data: {
directiveLabel: true,
},
children: [
{
type: "text",
value: title,
},
],
});
}

children.push(...body);

return {
type: "containerDirective",
name: admonitionKind,
children,
};
}
125 changes: 68 additions & 57 deletions docs/infra/api-markdown-documenter/api-documentation-layout.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,75 +6,86 @@
//@ts-check
/** @typedef {import("@fluid-tools/api-markdown-documenter").ApiItem} ApiItem */
/** @typedef {import("@fluid-tools/api-markdown-documenter").ApiItemTransformationConfiguration} ApiItemTransformationConfiguration */
/** @typedef {import("@fluid-tools/api-markdown-documenter").BlockContent} BlockContent */
/** @typedef {import("@fluid-tools/api-markdown-documenter").DocumentationNode} DocumentationNode */
/** @typedef {import("@fluid-tools/api-markdown-documenter").Section} Section */
/** @typedef {import("mdast").BlockContent} BlockContent */
/** @typedef {import("mdast").Paragraph} Paragraph */

import {
ApiItemKind,
ApiItemUtilities,
CodeSpanNode,
HeadingNode,
LayoutUtilities,
LinkNode,
ParagraphNode,
PlainTextNode,
ReleaseTag,
SectionNode,
transformTsdoc,
} from "@fluid-tools/api-markdown-documenter";

import { AdmonitionNode } from "./admonition-node.mjs";
import { createAdmonition } from "./admonition.mjs";

const customExamplesSectionTitle = "Usage";
const customThrowsSectionTitle = "Error Handling";

const supportDocsLinkParagraph = new ParagraphNode([
new PlainTextNode("For more information about our API support guarantees, see "),
new LinkNode(
"here",
// Is there a URL that would be relative to the current site? (For development use)
"https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels",
),
new PlainTextNode("."),
]);
/**
* A paragraph containing a link to the Fluid Framework API support documentation.
* @type Paragraph
*/
const supportDocsLinkParagraph = {
type: "paragraph",
children: [
{ type: "text", value: "For more information about our API support guarantees, see " },
{
type: "link",
children: [{ type: "text", value: "here" }],
// Is there a URL that would be relative to the current site? (For development use)
url: "https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels",
},
{ type: "text", value: "." },
],
};

/**
* A special use notice for the "@system" tag.
*/
const systemNotice = new AdmonitionNode(
const systemNotice = createAdmonition(
[supportDocsLinkParagraph],
/* admonitionKind: */ "warning",
"This API is reserved for internal system use and should not be imported directly. It may change at any time without notice.",
/* title: */ "This API is reserved for internal system use and should not be imported directly. It may change at any time without notice.",
);

/**
* A special use notice for the "@sealed" tag.
*/
const sealedNotice = new AdmonitionNode(
const sealedNotice = createAdmonition(
[
new ParagraphNode([
new PlainTextNode(
'This type is "sealed," meaning that code outside of the library defining it should not implement or extend it. Future versions of this type may add members or make typing of readonly members more specific.',
),
]),
{
type: "paragraph",
children: [
{
type: "text",
value: 'This type is "sealed," meaning that code outside of the library defining it should not implement or extend it. Future versions of this type may add members or make typing of readonly members more specific.',
},
],
},
],
/* admonitionKind: */ "info",
"Sealed",
/* title: */ "Sealed",
);

/**
* A special use notice for the "@input" tag.
*/
const inputNotice = new AdmonitionNode(
const inputNotice = createAdmonition(
[
new ParagraphNode([
new PlainTextNode(
'This type is "input," meaning that code outside of the library defining it should not read from it. Future versions of this type may add optional members or make typing of members more general.',
),
]),
{
type: "paragraph",
children: [
{
type: "text",
value: 'This type is "input," meaning that code outside of the library defining it should not read from it. Future versions of this type may add optional members or make typing of members more general.',
},
],
},
],
/* admonitionKind: */ "info",
"Input",
/* title: */ "Input",
);

/**
Expand Down Expand Up @@ -104,28 +115,29 @@ function createSupportNotice(apiItem, isImportable) {
* @param {string} importSubpath - Subpath beneath the item's package through which the item can be imported.
* @param {string} admonitionTitle - Title to display for the admonition.
*/
function createAdmonition(importSubpath, admonitionTitle) {
function createImportAdmonition(importSubpath, admonitionTitle) {
/** @type {BlockContent[]} */
const admonitionChildren = [];
if (isImportable) {
admonitionChildren.push(
new ParagraphNode([
new PlainTextNode("To use, import via "),
CodeSpanNode.createFromPlainText(`${packageName}/${importSubpath}`),
new PlainTextNode("."),
]),
);
admonitionChildren.push({
type: "paragraph",
children: [
{ type: "text", value: "To use, import via " },
{ type: "inlineCode", value: `${packageName}/${importSubpath}` },
{ type: "text", value: "." },
],
});
}
admonitionChildren.push(supportDocsLinkParagraph);
return new AdmonitionNode(
return createAdmonition(
admonitionChildren,
/* admonitionKind: */ "warning",
admonitionTitle,
);
}

if (ApiItemUtilities.ancestryHasModifierTag(apiItem, "@legacy")) {
return createAdmonition(
return createImportAdmonition(
"legacy",
"This API is provided for existing users, but is not recommended for new users.",
);
Expand All @@ -134,14 +146,14 @@ function createSupportNotice(apiItem, isImportable) {
const releaseLevel = ApiItemUtilities.getEffectiveReleaseLevel(apiItem);

if (releaseLevel === ReleaseTag.Alpha) {
return createAdmonition(
return createImportAdmonition(
"alpha",
"This API is provided as an alpha preview and may change without notice.",
);
}

if (releaseLevel === ReleaseTag.Beta) {
return createAdmonition(
return createImportAdmonition(
"beta",
"This API is provided as a beta preview and may change without notice.",
);
Expand All @@ -159,7 +171,7 @@ function createSupportNotice(apiItem, isImportable) {
* @param {`@${string}`} tag - The tag to check for.
* @param {boolean} includeContainingAncestry - Whether or not to include the `apiItem`'s containing ancestry when checking for the tag.
* E.g. whether or not a class member should inherit the tag from its containing class. Or a class inherit from its containing package/namespace.
* @param {AdmonitionNode} notice - The notice to display if the tag is present.
* @param {BlockContent} notice - The notice to display if the tag is present.
*/
function createTagNotice(apiItem, tag, includeContainingAncestry, notice) {
if (includeContainingAncestry && ApiItemUtilities.ancestryHasModifierTag(apiItem, tag)) {
Expand Down Expand Up @@ -199,7 +211,7 @@ function createTagNotice(apiItem, tag, includeContainingAncestry, notice) {
* 1. See (if any)
*
* @param {ApiItem} apiItem - The API item being rendered.
* @param {SectionNode[] | undefined} itemSpecificContent - API item-specific details to be included in the default layout.
* @param {Section[] | undefined} itemSpecificContent - API item-specific details to be included in the default layout.
* @param {ApiItemTransformationConfiguration} config - Transformation configuration.
*
* @returns An array of sections describing the layout. See {@link @fluid-tools/api-markdown-documenter#ApiItemTransformationConfiguration.createDefaultLayout}.
Expand All @@ -224,12 +236,12 @@ export function layoutContent(apiItem, itemSpecificContent, config) {

/**
* Adds node (if not undefined) to `sections`, wrapping in a `SectionNode` if not already a `SectionNode`.
* @param {DocumentationNode | undefined} node - The node to add to `sections`.
* @param {Section | BlockContent | undefined} node - The node to add to `sections`.
* @returns true if the node was added, false otherwise.
*/
function addSection(node) {
if (node !== undefined) {
sections.push(node instanceof SectionNode ? new SectionNode([node]) : node);
sections.push(node.type === "section" ? node : { type: "section", children: [node] });
return true;
}
return false;
Expand Down Expand Up @@ -279,12 +291,11 @@ export function layoutContent(apiItem, itemSpecificContent, config) {
return isDocumentItem
? sections
: [
new SectionNode(
sections,
HeadingNode.createFromPlainTextHeading(
ApiItemUtilities.getHeadingForApiItem(apiItem, config),
),
),
{
type: "section",
children: sections,
heading: ApiItemUtilities.getHeadingForApiItem(apiItem, config),
},
];
}

Expand All @@ -310,7 +321,7 @@ function createDeprecationNoticeSection(apiItem, config) {
throw new Error("Failed to transform deprecated block.");
}

return new AdmonitionNode(
return createAdmonition(
transformedDeprecatedBlockContents,
"warning",
"This API is deprecated and will be removed in a future release.",
Expand Down
Loading