mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 18:27:56 +02:00
refactor(mdx-loader): streamline typescript usage for remark plugin types (#10651)
This commit is contained in:
parent
e32aa605ca
commit
bdf55eda22
12 changed files with 92 additions and 92 deletions
|
@ -5,17 +5,11 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer, Processor} from 'unified';
|
||||
import type {Transformer, Plugin} from 'unified';
|
||||
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {ContainerDirective} from 'mdast-util-directive';
|
||||
import type {Parent} from 'mdast';
|
||||
|
||||
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
|
||||
// This might change soon, likely after TS 5.2
|
||||
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
|
||||
// import type {Plugin} from 'unified';
|
||||
type Plugin = any; // TODO fix this asap
|
||||
import type {Parent, Root} from 'mdast';
|
||||
|
||||
export type AdmonitionOptions = {
|
||||
keywords: string[];
|
||||
|
@ -85,10 +79,10 @@ function getTextOnlyTitle(directiveLabel: DirectiveLabel): string | undefined {
|
|||
: undefined;
|
||||
}
|
||||
|
||||
const plugin: Plugin = function plugin(
|
||||
this: Processor,
|
||||
optionsInput: Partial<AdmonitionOptions> = {},
|
||||
): Transformer {
|
||||
const plugin: Plugin<Partial<AdmonitionOptions>[], Root> = function plugin(
|
||||
this,
|
||||
optionsInput = {},
|
||||
): Transformer<Root> {
|
||||
const {keywords} = normalizeAdmonitionOptions(optionsInput);
|
||||
|
||||
return async (root) => {
|
||||
|
@ -96,31 +90,30 @@ const plugin: Plugin = function plugin(
|
|||
|
||||
visit(root, (node) => {
|
||||
if (node.type === 'containerDirective') {
|
||||
const directive = node as ContainerDirective;
|
||||
const isAdmonition = keywords.includes(directive.name);
|
||||
const isAdmonition = keywords.includes(node.name);
|
||||
|
||||
if (!isAdmonition) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {directiveLabel, contentNodes} = parseDirective(directive);
|
||||
const {directiveLabel, contentNodes} = parseDirective(node);
|
||||
|
||||
const textOnlyTitle =
|
||||
directive.attributes?.title ??
|
||||
node.attributes?.title ??
|
||||
(directiveLabel ? getTextOnlyTitle(directiveLabel) : undefined);
|
||||
|
||||
// Transform the mdast directive node to a hast admonition node
|
||||
// See https://github.com/syntax-tree/mdast-util-to-hast#fields-on-nodes
|
||||
// TODO in MDX v2 we should transform the whole directive to
|
||||
// mdxJsxFlowElement instead of using hast
|
||||
directive.data = {
|
||||
node.data = {
|
||||
hName: 'admonition',
|
||||
hProperties: {
|
||||
...(textOnlyTitle && {title: textOnlyTitle}),
|
||||
type: directive.name,
|
||||
type: node.name,
|
||||
},
|
||||
};
|
||||
directive.children = contentNodes;
|
||||
node.children = contentNodes;
|
||||
|
||||
// TODO legacy MDX v1 <mdxAdmonitionTitle> workaround
|
||||
// v1: not possible to inject complex JSX elements as props
|
||||
|
@ -135,7 +128,7 @@ const plugin: Plugin = function plugin(
|
|||
children: directiveLabel.children,
|
||||
};
|
||||
// @ts-expect-error: invented node type
|
||||
directive.children.unshift(complexTitleNode);
|
||||
node.children.unshift(complexTitleNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,20 +4,13 @@
|
|||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Heading, Parent} from 'mdast';
|
||||
import type {Transformer, Plugin} from 'unified';
|
||||
import type {Heading, Parent, Root} from 'mdast';
|
||||
|
||||
// @ts-expect-error: ES support...
|
||||
import type {MdxJsxFlowElement} from 'mdast-util-mdx';
|
||||
|
||||
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
|
||||
// TODO upgrade to TS 5.3
|
||||
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
|
||||
// import type {Plugin} from 'unified';
|
||||
type Plugin = any; // TODO fix this asap
|
||||
|
||||
interface PluginOptions {
|
||||
removeContentTitle?: boolean;
|
||||
}
|
||||
|
@ -41,9 +34,9 @@ function wrapHeadingInJsxHeader(
|
|||
* This is exposed as "data.contentTitle" to the processed vfile
|
||||
* Also gives the ability to strip that content title (used for the blog plugin)
|
||||
*/
|
||||
const plugin: Plugin = function plugin(
|
||||
options: PluginOptions = {},
|
||||
): Transformer {
|
||||
const plugin: Plugin<PluginOptions[], Root> = function plugin(
|
||||
options = {},
|
||||
): Transformer<Root> {
|
||||
// content title is
|
||||
const removeContentTitle = options.removeContentTitle ?? false;
|
||||
|
||||
|
@ -51,25 +44,26 @@ const plugin: Plugin = function plugin(
|
|||
const {toString} = await import('mdast-util-to-string');
|
||||
const {visit, EXIT} = await import('unist-util-visit');
|
||||
visit(root, ['heading', 'thematicBreak'], (node, index, parent) => {
|
||||
if (!parent || index === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (node.type === 'heading') {
|
||||
const headingNode = node as Heading;
|
||||
// console.log('headingNode:', headingNode);
|
||||
|
||||
if (headingNode.depth === 1) {
|
||||
vfile.data.contentTitle = toString(headingNode);
|
||||
if (node.depth === 1) {
|
||||
vfile.data.contentTitle = toString(node);
|
||||
if (removeContentTitle) {
|
||||
// @ts-expect-error: TODO how to fix?
|
||||
parent!.children.splice(index, 1);
|
||||
parent.children.splice(index, 1);
|
||||
} else {
|
||||
// TODO in the future it might be better to export contentTitle as
|
||||
// as JSX node to keep this logic a theme concern?
|
||||
// See https://github.com/facebook/docusaurus/pull/10335#issuecomment-2250187371
|
||||
wrapHeadingInJsxHeader(headingNode, parent, index!);
|
||||
wrapHeadingInJsxHeader(node, parent, index);
|
||||
}
|
||||
return EXIT; // We only handle the very first heading
|
||||
}
|
||||
// We only handle contentTitle if it's the very first heading found
|
||||
if (headingNode.depth >= 1) {
|
||||
if (node.depth >= 1) {
|
||||
return EXIT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,14 @@
|
|||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
|
||||
// @ts-expect-error: ES support...
|
||||
import type {MdxJsxFlowElement} from 'mdast-util-mdx';
|
||||
import type {Root} from 'mdast';
|
||||
|
||||
// Transform <details> to <Details>
|
||||
// MDX 2 doesn't allow to substitute html elements with the provider anymore
|
||||
export default function plugin(): Transformer {
|
||||
export default function plugin(): Transformer<Root> {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
visit(root, 'mdxJsxFlowElement', (node: MdxJsxFlowElement) => {
|
||||
visit(root, 'mdxJsxFlowElement', (node) => {
|
||||
if (node.name === 'details') {
|
||||
node.name = 'Details';
|
||||
}
|
||||
|
|
|
@ -8,15 +8,14 @@
|
|||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {MdxJsxFlowElement} from 'mdast-util-mdx';
|
||||
import type {Root} from 'mdast';
|
||||
|
||||
// Transform <head> to <Head>
|
||||
// MDX 2 doesn't allow to substitute html elements with the provider anymore
|
||||
export default function plugin(): Transformer {
|
||||
export default function plugin(): Transformer<Root> {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
visit(root, 'mdxJsxFlowElement', (node: MdxJsxFlowElement) => {
|
||||
visit(root, 'mdxJsxFlowElement', (node) => {
|
||||
if (node.name === 'head') {
|
||||
node.name = 'Head';
|
||||
}
|
||||
|
|
|
@ -9,22 +9,22 @@
|
|||
|
||||
import {parseMarkdownHeadingId, createSlugger} from '@docusaurus/utils';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Heading, Text} from 'mdast';
|
||||
import type {Plugin, Transformer} from 'unified';
|
||||
import type {Root, Text} from 'mdast';
|
||||
|
||||
export interface PluginOptions {
|
||||
anchorsMaintainCase: boolean;
|
||||
}
|
||||
|
||||
export default function plugin({
|
||||
const plugin: Plugin<PluginOptions[], Root> = function plugin({
|
||||
anchorsMaintainCase,
|
||||
}: PluginOptions): Transformer {
|
||||
}): Transformer<Root> {
|
||||
return async (root) => {
|
||||
const {toString} = await import('mdast-util-to-string');
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
const slugs = createSlugger();
|
||||
visit(root, 'heading', (headingNode: Heading) => {
|
||||
visit(root, 'heading', (headingNode) => {
|
||||
const data = headingNode.data ?? (headingNode.data = {});
|
||||
const properties = (data.hProperties || (data.hProperties = {})) as {
|
||||
id: string;
|
||||
|
@ -77,4 +77,6 @@ export default function plugin({
|
|||
properties.id = id;
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer, Processor} from 'unified';
|
||||
import type {Code} from 'mdast';
|
||||
import type {Transformer, Plugin} from 'unified';
|
||||
import type {Root} from 'mdast';
|
||||
|
||||
// Solution inspired by https://github.com/pomber/docusaurus-mdx-2/blob/main/packages/mdx-loader/src/remark/codeCompat/index.ts
|
||||
// TODO after MDX 2 we probably don't need this - remove soon?
|
||||
|
@ -16,11 +16,11 @@ import type {Code} from 'mdast';
|
|||
|
||||
// To make theme-classic/src/theme/MDXComponents/Pre work
|
||||
// we need to fill two properties that mdx v2 doesn't provide anymore
|
||||
export default function codeCompatPlugin(this: Processor): Transformer {
|
||||
const plugin: Plugin<unknown[], Root> = function plugin(): Transformer<Root> {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
visit(root, 'code', (node: Code) => {
|
||||
visit(root, 'code', (node) => {
|
||||
node.data = node.data || {};
|
||||
|
||||
node.data.hProperties = node.data.hProperties || {};
|
||||
|
@ -31,4 +31,6 @@ export default function codeCompatPlugin(this: Processor): Transformer {
|
|||
node.data.hProperties.live = node.meta?.split(' ').includes('live');
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
@ -9,17 +9,17 @@ import {transformNode} from '../utils';
|
|||
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Code} from 'mdast';
|
||||
import type {Root} from 'mdast';
|
||||
|
||||
// TODO: this plugin shouldn't be in the core MDX loader
|
||||
// After we allow plugins to provide Remark/Rehype plugins (see
|
||||
// https://github.com/facebook/docusaurus/issues/6370), this should be provided
|
||||
// by theme-mermaid itself
|
||||
export default function plugin(): Transformer {
|
||||
export default function plugin(): Transformer<Root> {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
visit(root, 'code', (node: Code) => {
|
||||
visit(root, 'code', (node) => {
|
||||
if (node.lang === 'mermaid') {
|
||||
// TODO migrate to mdxJsxFlowElement? cf admonitions
|
||||
transformNode(node, {
|
||||
|
|
|
@ -12,8 +12,8 @@ import {
|
|||
} from '@docusaurus/utils';
|
||||
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Definition, Link} from 'mdast';
|
||||
import type {Plugin, Transformer} from 'unified';
|
||||
import type {Definition, Link, Root} from 'mdast';
|
||||
|
||||
type ResolveMarkdownLinkParams = {
|
||||
/**
|
||||
|
@ -35,12 +35,6 @@ export interface PluginOptions {
|
|||
resolveMarkdownLink: ResolveMarkdownLink;
|
||||
}
|
||||
|
||||
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
|
||||
// TODO upgrade to TS 5.3
|
||||
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
|
||||
// import type {Plugin} from 'unified';
|
||||
type Plugin = any; // TODO fix this asap
|
||||
|
||||
const HAS_MARKDOWN_EXTENSION = /\.mdx?$/i;
|
||||
|
||||
function parseMarkdownLinkURLPath(link: string): URLPath | null {
|
||||
|
@ -64,7 +58,9 @@ function parseMarkdownLinkURLPath(link: string): URLPath | null {
|
|||
* This is exposed as "data.contentTitle" to the processed vfile
|
||||
* Also gives the ability to strip that content title (used for the blog plugin)
|
||||
*/
|
||||
const plugin: Plugin = function plugin(options: PluginOptions): Transformer {
|
||||
const plugin: Plugin<PluginOptions[], Root> = function plugin(
|
||||
options,
|
||||
): Transformer<Root> {
|
||||
const {resolveMarkdownLink} = options;
|
||||
return async (root, file) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
} from './utils';
|
||||
import type {Heading, Root} from 'mdast';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Plugin, Transformer} from 'unified';
|
||||
import type {
|
||||
MdxjsEsm,
|
||||
MdxJsxFlowElement,
|
||||
|
@ -155,7 +155,9 @@ async function collectTOCItems({
|
|||
}
|
||||
}
|
||||
|
||||
export default function plugin(options: PluginOptions = {}): Transformer<Root> {
|
||||
const plugin: Plugin<PluginOptions[], Root> = function plugin(
|
||||
options = {},
|
||||
): Transformer<Root> {
|
||||
const tocExportName = options.name || 'toc';
|
||||
|
||||
return async (root) => {
|
||||
|
@ -184,4 +186,6 @@ export default function plugin(options: PluginOptions = {}): Transformer<Root> {
|
|||
}),
|
||||
);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
@ -21,10 +21,10 @@ import sizeOf from 'image-size';
|
|||
import logger from '@docusaurus/logger';
|
||||
import {assetRequireAttributeValue, transformNode} from '../utils';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Plugin, Transformer} from 'unified';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {MdxJsxTextElement} from 'mdast-util-mdx';
|
||||
import type {Image} from 'mdast';
|
||||
import type {Image, Root} from 'mdast';
|
||||
import type {Parent} from 'unist';
|
||||
|
||||
type PluginOptions = {
|
||||
|
@ -186,7 +186,9 @@ async function processImageNode(target: Target, context: Context) {
|
|||
await toImageRequireNode(target, imagePath, context);
|
||||
}
|
||||
|
||||
export default function plugin(options: PluginOptions): Transformer {
|
||||
const plugin: Plugin<PluginOptions[], Root> = function plugin(
|
||||
options,
|
||||
): Transformer<Root> {
|
||||
return async (root, vfile) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
|
@ -201,9 +203,14 @@ export default function plugin(options: PluginOptions): Transformer {
|
|||
};
|
||||
|
||||
const promises: Promise<void>[] = [];
|
||||
visit(root, 'image', (node: Image, index, parent) => {
|
||||
visit(root, 'image', (node, index, parent) => {
|
||||
if (!parent || index === undefined) {
|
||||
return;
|
||||
}
|
||||
promises.push(processImageNode([node, index, parent!], context));
|
||||
});
|
||||
await Promise.all(promises);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
@ -18,11 +18,11 @@ import {
|
|||
import escapeHtml from 'escape-html';
|
||||
import {assetRequireAttributeValue, transformNode} from '../utils';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Plugin, Transformer} from 'unified';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {MdxJsxTextElement} from 'mdast-util-mdx';
|
||||
import type {Parent} from 'unist';
|
||||
import type {Link, Literal} from 'mdast';
|
||||
import type {Link, Literal, Root} from 'mdast';
|
||||
|
||||
type PluginOptions = {
|
||||
staticDirs: string[];
|
||||
|
@ -199,7 +199,9 @@ async function processLinkNode(target: Target, context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
export default function plugin(options: PluginOptions): Transformer {
|
||||
const plugin: Plugin<PluginOptions[], Root> = function plugin(
|
||||
options,
|
||||
): Transformer<Root> {
|
||||
return async (root, vfile) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
|
@ -214,9 +216,14 @@ export default function plugin(options: PluginOptions): Transformer {
|
|||
};
|
||||
|
||||
const promises: Promise<void>[] = [];
|
||||
visit(root, 'link', (node: Link, index, parent) => {
|
||||
promises.push(processLinkNode([node, index, parent!], context));
|
||||
visit(root, 'link', (node, index, parent) => {
|
||||
if (!parent || index === undefined) {
|
||||
return;
|
||||
}
|
||||
promises.push(processLinkNode([node, index, parent], context));
|
||||
});
|
||||
await Promise.all(promises);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
|
|
|
@ -9,21 +9,16 @@ import process from 'process';
|
|||
import logger from '@docusaurus/logger';
|
||||
import {posixPath} from '@docusaurus/utils';
|
||||
import {transformNode} from '../utils';
|
||||
import type {Root} from 'mdast';
|
||||
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer, Processor, Parent} from 'unified';
|
||||
import type {Transformer, Processor, Parent, Plugin} from 'unified';
|
||||
import type {
|
||||
Directives,
|
||||
TextDirective,
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
} from 'mdast-util-directive';
|
||||
|
||||
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
|
||||
// This might change soon, likely after TS 5.2
|
||||
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
|
||||
// import type {Plugin} from 'unified';
|
||||
type Plugin = any; // TODO fix this asap
|
||||
|
||||
type DirectiveType = Directives['type'];
|
||||
|
||||
const directiveTypes: DirectiveType[] = [
|
||||
|
@ -130,7 +125,9 @@ function isUnusedDirective(directive: Directives) {
|
|||
return !directive.data;
|
||||
}
|
||||
|
||||
const plugin: Plugin = function plugin(this: Processor): Transformer {
|
||||
const plugin: Plugin<unknown[], Root> = function plugin(
|
||||
this: Processor,
|
||||
): Transformer<Root> {
|
||||
return async (tree, file) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue