Skip to content

Commit

Permalink
Docgen: Support TS2JS remark plugin [experimental]
Browse files Browse the repository at this point in the history
  • Loading branch information
fuma-nama committed Dec 18, 2024
1 parent 0f54234 commit 4ab0de6
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-trees-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'fumadocs-docgen': patch
---

Support TS2JS remark plugin [experimental]
1 change: 1 addition & 0 deletions packages/doc-gen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"types:check": "tsc --noEmit"
},
"dependencies": {
"@swc/wasm-typescript": "^1.10.1",
"estree-util-value-to-estree": "^3.2.1",
"fumadocs-typescript": "workspace:^",
"hast-util-to-estree": "^3.1.0",
Expand Down
1 change: 1 addition & 0 deletions packages/doc-gen/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './utils';
export * from './file-generator';
export * from './typescript-generator';
export * from './remark-install';
export * from './remark-ts2js';
120 changes: 120 additions & 0 deletions packages/doc-gen/src/remark-ts2js.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { Transformer } from 'unified';
import { type Code, Root } from 'mdast';
import { visit } from 'unist-util-visit';
import { transform, Options as SWCOptions } from '@swc/wasm-typescript';
import { createElement, expressionToAttribute } from '@/utils';

export interface TypeScriptToJavaScriptOptions {
swc?: SWCOptions;
/**
* Persist Tab value (Fumadocs UI only)
*
* @defaultValue false
*/
persist?:
| {
id: string;
}
| false;
}

export function remarkTs2js({
swc = {},
persist = false,
}: TypeScriptToJavaScriptOptions = {}): Transformer<Root> {
return async (tree, file) => {
const queue: Promise<void>[] = [];

visit(tree, 'code', (node) => {
if (node.lang !== 'ts' && node.lang !== 'tsx') return;

const task = transform(node.value, {
filename: `${file.path}.${node.lang}`,
transform: {
importExportAssignConfig: 'Preserve',
verbatimModuleSyntax: true,
},
sourceMap: false,
...swc,
})
.then((output) => {
const insert = createElement(
'Tabs',
[
...(typeof persist === 'object'
? [
{
type: 'mdxJsxAttribute',
name: 'groupId',
value: persist.id,
},
{
type: 'mdxJsxAttribute',
name: 'persist',
value: null,
},
]
: []),
expressionToAttribute('items', {
type: 'ArrayExpression',
elements: ['TypeScript', 'JavaScript'].map((name) => ({
type: 'Literal',
value: name,
})),
}),
],
[
{
type: 'mdxJsxFlowElement',
name: 'Tab',
attributes: [
{
type: 'mdxJsxAttribute',
name: 'value',
value: 'TypeScript',
},
],
children: [
{
type: 'code',
lang: node.lang,
meta: node.meta,
value: node.value,
} satisfies Code,
],
},
{
type: 'mdxJsxFlowElement',
name: 'Tab',
attributes: [
{
type: 'mdxJsxAttribute',
name: 'value',
value: 'JavaScript',
},
],
children: [
{
type: 'code',
lang: 'jsx',
meta: node.meta,
value: output.code,
} satisfies Code,
],
},
],
);

Object.assign(node, insert);
})
.catch((e) => {
// ignore node
console.error(e);
});

queue.push(task);
});

await Promise.all(queue);
};
}
Loading

0 comments on commit 4ab0de6

Please sign in to comment.