Skip to content

Commit bdf55ed

Browse files
authored
refactor(mdx-loader): streamline typescript usage for remark plugin types (#10651)
1 parent e32aa60 commit bdf55ed

File tree

12 files changed

+92
-92
lines changed

12 files changed

+92
-92
lines changed

packages/docusaurus-mdx-loader/src/remark/admonitions/index.ts

+13-20
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,11 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
8-
import type {Transformer, Processor} from 'unified';
8+
import type {Transformer, Plugin} from 'unified';
99

1010
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
1111
import type {ContainerDirective} from 'mdast-util-directive';
12-
import type {Parent} from 'mdast';
13-
14-
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
15-
// This might change soon, likely after TS 5.2
16-
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
17-
// import type {Plugin} from 'unified';
18-
type Plugin = any; // TODO fix this asap
12+
import type {Parent, Root} from 'mdast';
1913

2014
export type AdmonitionOptions = {
2115
keywords: string[];
@@ -85,42 +79,41 @@ function getTextOnlyTitle(directiveLabel: DirectiveLabel): string | undefined {
8579
: undefined;
8680
}
8781

88-
const plugin: Plugin = function plugin(
89-
this: Processor,
90-
optionsInput: Partial<AdmonitionOptions> = {},
91-
): Transformer {
82+
const plugin: Plugin<Partial<AdmonitionOptions>[], Root> = function plugin(
83+
this,
84+
optionsInput = {},
85+
): Transformer<Root> {
9286
const {keywords} = normalizeAdmonitionOptions(optionsInput);
9387

9488
return async (root) => {
9589
const {visit} = await import('unist-util-visit');
9690

9791
visit(root, (node) => {
9892
if (node.type === 'containerDirective') {
99-
const directive = node as ContainerDirective;
100-
const isAdmonition = keywords.includes(directive.name);
93+
const isAdmonition = keywords.includes(node.name);
10194

10295
if (!isAdmonition) {
10396
return;
10497
}
10598

106-
const {directiveLabel, contentNodes} = parseDirective(directive);
99+
const {directiveLabel, contentNodes} = parseDirective(node);
107100

108101
const textOnlyTitle =
109-
directive.attributes?.title ??
102+
node.attributes?.title ??
110103
(directiveLabel ? getTextOnlyTitle(directiveLabel) : undefined);
111104

112105
// Transform the mdast directive node to a hast admonition node
113106
// See https://github.com/syntax-tree/mdast-util-to-hast#fields-on-nodes
114107
// TODO in MDX v2 we should transform the whole directive to
115108
// mdxJsxFlowElement instead of using hast
116-
directive.data = {
109+
node.data = {
117110
hName: 'admonition',
118111
hProperties: {
119112
...(textOnlyTitle && {title: textOnlyTitle}),
120-
type: directive.name,
113+
type: node.name,
121114
},
122115
};
123-
directive.children = contentNodes;
116+
node.children = contentNodes;
124117

125118
// TODO legacy MDX v1 <mdxAdmonitionTitle> workaround
126119
// v1: not possible to inject complex JSX elements as props
@@ -135,7 +128,7 @@ const plugin: Plugin = function plugin(
135128
children: directiveLabel.children,
136129
};
137130
// @ts-expect-error: invented node type
138-
directive.children.unshift(complexTitleNode);
131+
node.children.unshift(complexTitleNode);
139132
}
140133
}
141134
});

packages/docusaurus-mdx-loader/src/remark/contentTitle/index.ts

+13-19
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,13 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*/
7-
87
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
9-
import type {Transformer} from 'unified';
10-
import type {Heading, Parent} from 'mdast';
8+
import type {Transformer, Plugin} from 'unified';
9+
import type {Heading, Parent, Root} from 'mdast';
1110

1211
// @ts-expect-error: ES support...
1312
import type {MdxJsxFlowElement} from 'mdast-util-mdx';
1413

15-
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
16-
// TODO upgrade to TS 5.3
17-
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
18-
// import type {Plugin} from 'unified';
19-
type Plugin = any; // TODO fix this asap
20-
2114
interface PluginOptions {
2215
removeContentTitle?: boolean;
2316
}
@@ -41,35 +34,36 @@ function wrapHeadingInJsxHeader(
4134
* This is exposed as "data.contentTitle" to the processed vfile
4235
* Also gives the ability to strip that content title (used for the blog plugin)
4336
*/
44-
const plugin: Plugin = function plugin(
45-
options: PluginOptions = {},
46-
): Transformer {
37+
const plugin: Plugin<PluginOptions[], Root> = function plugin(
38+
options = {},
39+
): Transformer<Root> {
4740
// content title is
4841
const removeContentTitle = options.removeContentTitle ?? false;
4942

5043
return async (root, vfile) => {
5144
const {toString} = await import('mdast-util-to-string');
5245
const {visit, EXIT} = await import('unist-util-visit');
5346
visit(root, ['heading', 'thematicBreak'], (node, index, parent) => {
47+
if (!parent || index === undefined) {
48+
return undefined;
49+
}
5450
if (node.type === 'heading') {
55-
const headingNode = node as Heading;
5651
// console.log('headingNode:', headingNode);
5752

58-
if (headingNode.depth === 1) {
59-
vfile.data.contentTitle = toString(headingNode);
53+
if (node.depth === 1) {
54+
vfile.data.contentTitle = toString(node);
6055
if (removeContentTitle) {
61-
// @ts-expect-error: TODO how to fix?
62-
parent!.children.splice(index, 1);
56+
parent.children.splice(index, 1);
6357
} else {
6458
// TODO in the future it might be better to export contentTitle as
6559
// as JSX node to keep this logic a theme concern?
6660
// See https://github.com/facebook/docusaurus/pull/10335#issuecomment-2250187371
67-
wrapHeadingInJsxHeader(headingNode, parent, index!);
61+
wrapHeadingInJsxHeader(node, parent, index);
6862
}
6963
return EXIT; // We only handle the very first heading
7064
}
7165
// We only handle contentTitle if it's the very first heading found
72-
if (headingNode.depth >= 1) {
66+
if (node.depth >= 1) {
7367
return EXIT;
7468
}
7569
}

packages/docusaurus-mdx-loader/src/remark/details/index.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
99
import type {Transformer} from 'unified';
1010

11-
// @ts-expect-error: ES support...
12-
import type {MdxJsxFlowElement} from 'mdast-util-mdx';
11+
import type {Root} from 'mdast';
1312

1413
// Transform <details> to <Details>
1514
// MDX 2 doesn't allow to substitute html elements with the provider anymore
16-
export default function plugin(): Transformer {
15+
export default function plugin(): Transformer<Root> {
1716
return async (root) => {
1817
const {visit} = await import('unist-util-visit');
19-
visit(root, 'mdxJsxFlowElement', (node: MdxJsxFlowElement) => {
18+
visit(root, 'mdxJsxFlowElement', (node) => {
2019
if (node.name === 'details') {
2120
node.name = 'Details';
2221
}

packages/docusaurus-mdx-loader/src/remark/head/index.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
99
import type {Transformer} from 'unified';
1010

11-
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
12-
import type {MdxJsxFlowElement} from 'mdast-util-mdx';
11+
import type {Root} from 'mdast';
1312

1413
// Transform <head> to <Head>
1514
// MDX 2 doesn't allow to substitute html elements with the provider anymore
16-
export default function plugin(): Transformer {
15+
export default function plugin(): Transformer<Root> {
1716
return async (root) => {
1817
const {visit} = await import('unist-util-visit');
19-
visit(root, 'mdxJsxFlowElement', (node: MdxJsxFlowElement) => {
18+
visit(root, 'mdxJsxFlowElement', (node) => {
2019
if (node.name === 'head') {
2120
node.name = 'Head';
2221
}

packages/docusaurus-mdx-loader/src/remark/headings/index.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@
99

1010
import {parseMarkdownHeadingId, createSlugger} from '@docusaurus/utils';
1111
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
12-
import type {Transformer} from 'unified';
13-
import type {Heading, Text} from 'mdast';
12+
import type {Plugin, Transformer} from 'unified';
13+
import type {Root, Text} from 'mdast';
1414

1515
export interface PluginOptions {
1616
anchorsMaintainCase: boolean;
1717
}
1818

19-
export default function plugin({
19+
const plugin: Plugin<PluginOptions[], Root> = function plugin({
2020
anchorsMaintainCase,
21-
}: PluginOptions): Transformer {
21+
}): Transformer<Root> {
2222
return async (root) => {
2323
const {toString} = await import('mdast-util-to-string');
2424
const {visit} = await import('unist-util-visit');
2525

2626
const slugs = createSlugger();
27-
visit(root, 'heading', (headingNode: Heading) => {
27+
visit(root, 'heading', (headingNode) => {
2828
const data = headingNode.data ?? (headingNode.data = {});
2929
const properties = (data.hProperties || (data.hProperties = {})) as {
3030
id: string;
@@ -77,4 +77,6 @@ export default function plugin({
7777
properties.id = id;
7878
});
7979
};
80-
}
80+
};
81+
82+
export default plugin;

packages/docusaurus-mdx-loader/src/remark/mdx1Compat/codeCompatPlugin.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
*/
77

88
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
9-
import type {Transformer, Processor} from 'unified';
10-
import type {Code} from 'mdast';
9+
import type {Transformer, Plugin} from 'unified';
10+
import type {Root} from 'mdast';
1111

1212
// Solution inspired by https://github.com/pomber/docusaurus-mdx-2/blob/main/packages/mdx-loader/src/remark/codeCompat/index.ts
1313
// TODO after MDX 2 we probably don't need this - remove soon?
@@ -16,11 +16,11 @@ import type {Code} from 'mdast';
1616

1717
// To make theme-classic/src/theme/MDXComponents/Pre work
1818
// we need to fill two properties that mdx v2 doesn't provide anymore
19-
export default function codeCompatPlugin(this: Processor): Transformer {
19+
const plugin: Plugin<unknown[], Root> = function plugin(): Transformer<Root> {
2020
return async (root) => {
2121
const {visit} = await import('unist-util-visit');
2222

23-
visit(root, 'code', (node: Code) => {
23+
visit(root, 'code', (node) => {
2424
node.data = node.data || {};
2525

2626
node.data.hProperties = node.data.hProperties || {};
@@ -31,4 +31,6 @@ export default function codeCompatPlugin(this: Processor): Transformer {
3131
node.data.hProperties.live = node.meta?.split(' ').includes('live');
3232
});
3333
};
34-
}
34+
};
35+
36+
export default plugin;

packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ import {transformNode} from '../utils';
99

1010
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
1111
import type {Transformer} from 'unified';
12-
import type {Code} from 'mdast';
12+
import type {Root} from 'mdast';
1313

1414
// TODO: this plugin shouldn't be in the core MDX loader
1515
// After we allow plugins to provide Remark/Rehype plugins (see
1616
// https://github.com/facebook/docusaurus/issues/6370), this should be provided
1717
// by theme-mermaid itself
18-
export default function plugin(): Transformer {
18+
export default function plugin(): Transformer<Root> {
1919
return async (root) => {
2020
const {visit} = await import('unist-util-visit');
2121

22-
visit(root, 'code', (node: Code) => {
22+
visit(root, 'code', (node) => {
2323
if (node.lang === 'mermaid') {
2424
// TODO migrate to mdxJsxFlowElement? cf admonitions
2525
transformNode(node, {

packages/docusaurus-mdx-loader/src/remark/resolveMarkdownLinks/index.ts

+5-9
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import {
1212
} from '@docusaurus/utils';
1313

1414
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
15-
import type {Transformer} from 'unified';
16-
import type {Definition, Link} from 'mdast';
15+
import type {Plugin, Transformer} from 'unified';
16+
import type {Definition, Link, Root} from 'mdast';
1717

1818
type ResolveMarkdownLinkParams = {
1919
/**
@@ -35,12 +35,6 @@ export interface PluginOptions {
3535
resolveMarkdownLink: ResolveMarkdownLink;
3636
}
3737

38-
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
39-
// TODO upgrade to TS 5.3
40-
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
41-
// import type {Plugin} from 'unified';
42-
type Plugin = any; // TODO fix this asap
43-
4438
const HAS_MARKDOWN_EXTENSION = /\.mdx?$/i;
4539

4640
function parseMarkdownLinkURLPath(link: string): URLPath | null {
@@ -64,7 +58,9 @@ function parseMarkdownLinkURLPath(link: string): URLPath | null {
6458
* This is exposed as "data.contentTitle" to the processed vfile
6559
* Also gives the ability to strip that content title (used for the blog plugin)
6660
*/
67-
const plugin: Plugin = function plugin(options: PluginOptions): Transformer {
61+
const plugin: Plugin<PluginOptions[], Root> = function plugin(
62+
options,
63+
): Transformer<Root> {
6864
const {resolveMarkdownLink} = options;
6965
return async (root, file) => {
7066
const {visit} = await import('unist-util-visit');

packages/docusaurus-mdx-loader/src/remark/toc/index.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
} from './utils';
1616
import type {Heading, Root} from 'mdast';
1717
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
18-
import type {Transformer} from 'unified';
18+
import type {Plugin, Transformer} from 'unified';
1919
import type {
2020
MdxjsEsm,
2121
MdxJsxFlowElement,
@@ -155,7 +155,9 @@ async function collectTOCItems({
155155
}
156156
}
157157

158-
export default function plugin(options: PluginOptions = {}): Transformer<Root> {
158+
const plugin: Plugin<PluginOptions[], Root> = function plugin(
159+
options = {},
160+
): Transformer<Root> {
159161
const tocExportName = options.name || 'toc';
160162

161163
return async (root) => {
@@ -184,4 +186,6 @@ export default function plugin(options: PluginOptions = {}): Transformer<Root> {
184186
}),
185187
);
186188
};
187-
}
189+
};
190+
191+
export default plugin;

packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ import sizeOf from 'image-size';
2121
import logger from '@docusaurus/logger';
2222
import {assetRequireAttributeValue, transformNode} from '../utils';
2323
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
24-
import type {Transformer} from 'unified';
24+
import type {Plugin, Transformer} from 'unified';
2525
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
2626
import type {MdxJsxTextElement} from 'mdast-util-mdx';
27-
import type {Image} from 'mdast';
27+
import type {Image, Root} from 'mdast';
2828
import type {Parent} from 'unist';
2929

3030
type PluginOptions = {
@@ -186,7 +186,9 @@ async function processImageNode(target: Target, context: Context) {
186186
await toImageRequireNode(target, imagePath, context);
187187
}
188188

189-
export default function plugin(options: PluginOptions): Transformer {
189+
const plugin: Plugin<PluginOptions[], Root> = function plugin(
190+
options,
191+
): Transformer<Root> {
190192
return async (root, vfile) => {
191193
const {visit} = await import('unist-util-visit');
192194

@@ -201,9 +203,14 @@ export default function plugin(options: PluginOptions): Transformer {
201203
};
202204

203205
const promises: Promise<void>[] = [];
204-
visit(root, 'image', (node: Image, index, parent) => {
206+
visit(root, 'image', (node, index, parent) => {
207+
if (!parent || index === undefined) {
208+
return;
209+
}
205210
promises.push(processImageNode([node, index, parent!], context));
206211
});
207212
await Promise.all(promises);
208213
};
209-
}
214+
};
215+
216+
export default plugin;

0 commit comments

Comments
 (0)