mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
MDX: Support remark-directive for Include API
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-mdx': patch
|
||||
---
|
||||
|
||||
Support `remark-directive` for Include API
|
||||
@@ -84,7 +84,7 @@ export default function CustomSearchDialog(props: SharedProps) {
|
||||
client,
|
||||
tag,
|
||||
});
|
||||
const { root } = useTreeContext();
|
||||
const { full } = useTreeContext();
|
||||
const router = useRouter();
|
||||
const pageTreeActions = useMemo(() => {
|
||||
const actions: SearchItemType[] = [];
|
||||
@@ -95,7 +95,7 @@ export default function CustomSearchDialog(props: SharedProps) {
|
||||
(item) =>
|
||||
typeof item.name === 'string' &&
|
||||
item.name.toLowerCase().startsWith(normalized),
|
||||
root.children,
|
||||
full.children,
|
||||
);
|
||||
|
||||
if (result) {
|
||||
@@ -118,7 +118,7 @@ export default function CustomSearchDialog(props: SharedProps) {
|
||||
}
|
||||
|
||||
return actions;
|
||||
}, [root.children, router, search]);
|
||||
}, [full.children, router, search]);
|
||||
|
||||
return (
|
||||
<SearchDialog
|
||||
|
||||
@@ -5,24 +5,43 @@ description: Reuse content from other files.
|
||||
|
||||
## Usage
|
||||
|
||||
### Markdown
|
||||
### Content
|
||||
|
||||
To display content from another Markdown/MDX file, specify its path relative to the file itself in the `<include>` tag.
|
||||
|
||||
```mdx title="page.mdx"
|
||||
```mdx tab="MDX"
|
||||
<include>./another.mdx</include>
|
||||
```
|
||||
|
||||
<Callout>
|
||||
For Markdown files, you don't need to escape for MDX syntax but note that
|
||||
you'll need `rehypeRaw` for HTML comments & content.
|
||||
```md tab="Markdown"
|
||||
::include[./another.mdx]
|
||||
```
|
||||
|
||||
<Callout title='For Markdown'>
|
||||
|
||||
Markdown (`.md`) files do not support JSX syntax. To use `<include />`, you need to configure `remark-directive`.
|
||||
|
||||
```ts title="source.config.ts"
|
||||
import { defineConfig } from 'fumadocs-mdx/config';
|
||||
import remarkDirective from 'remark-directive';
|
||||
|
||||
export default defineConfig({
|
||||
mdxOptions: {
|
||||
// [!code ++]
|
||||
remarkPlugins: [remarkDirective],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You may also need `rehype-raw` for HTML comments & content.
|
||||
|
||||
</Callout>
|
||||
|
||||
### CodeBlock
|
||||
|
||||
For other types of files, it will become a codeblock:
|
||||
|
||||
```mdx title="page.mdx"
|
||||
```mdx tab="MDX"
|
||||
<include>./script.ts</include>
|
||||
|
||||
<include lang="md" meta='title="lib.md"'>
|
||||
@@ -30,19 +49,33 @@ For other types of files, it will become a codeblock:
|
||||
</include>
|
||||
```
|
||||
|
||||
```md tab="Markdown"
|
||||
::include[./script.ts]
|
||||
|
||||
::include[page.md]{lang=md meta='title="lib.md"'}
|
||||
```
|
||||
|
||||
### `cwd`
|
||||
|
||||
Resolve relative paths from cwd instead of the Markdown file:
|
||||
Resolve relative paths from cwd instead of the current file:
|
||||
|
||||
```mdx
|
||||
```mdx tab="MDX"
|
||||
<include cwd lang="tsx" meta='title="lib.ts"'>
|
||||
./script.ts
|
||||
</include>
|
||||
```
|
||||
|
||||
```md tab="Markdown"
|
||||
::include[./script.ts]{cwd lang=tsx meta='title="lib.ts"'}
|
||||
```
|
||||
|
||||
## Extraction
|
||||
|
||||
When referencing content files, you can only include a certain part of the document.
|
||||
|
||||
### Section
|
||||
|
||||
For Markdown files, you can include a section of it:
|
||||
Encapsulate by a `<section />` tag:
|
||||
|
||||
```mdx tab="a.mdx"
|
||||
## Hello World
|
||||
@@ -58,7 +91,27 @@ Include the content from `a.mdx`:
|
||||
<include>a.mdx#test</include>
|
||||
```
|
||||
|
||||
Or with heading id:
|
||||
In Markdown:
|
||||
|
||||
```md tab="a.md"
|
||||
## Hello World
|
||||
|
||||
:::section{#test}
|
||||
This is included
|
||||
:::
|
||||
|
||||
This is not included.
|
||||
```
|
||||
|
||||
```md tab="b.md"
|
||||
Include the content from `a.mdx`:
|
||||
|
||||
::include[a.md#test]
|
||||
```
|
||||
|
||||
### Heading
|
||||
|
||||
Include contents under a certain heading
|
||||
|
||||
```mdx tab="a.mdx"
|
||||
## Included Section
|
||||
@@ -75,3 +128,21 @@ Content under the heading:
|
||||
|
||||
<include>a.mdx#included-section</include>
|
||||
```
|
||||
|
||||
In Markdown:
|
||||
|
||||
```md tab="a.md"
|
||||
## Included Section
|
||||
|
||||
I'm here!
|
||||
|
||||
## Not Included
|
||||
|
||||
Some random text.
|
||||
```
|
||||
|
||||
```md tab="b.md"
|
||||
Content under the heading:
|
||||
|
||||
::include[a.mdx#included-section]
|
||||
```
|
||||
|
||||
@@ -92,9 +92,12 @@
|
||||
"@types/react": "^19.1.13",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"remark-directive": "^4.0.0",
|
||||
"mdast-util-directive": "^3.1.0",
|
||||
"mdast-util-mdx-jsx": "^3.2.0",
|
||||
"next": "^15.5.3",
|
||||
"react": "^19.1.1",
|
||||
"remark": "^15.0.1",
|
||||
"rollup": "^4.50.1",
|
||||
"tsconfig": "workspace:*",
|
||||
"vfile": "^6.0.3",
|
||||
|
||||
@@ -129,7 +129,7 @@ export async function buildMDX(
|
||||
}
|
||||
|
||||
return getProcessor(
|
||||
(options.format ?? filePath.endsWith('.mdx')) ? 'mdx' : 'md',
|
||||
options.format ?? (filePath.endsWith('.mdx') ? 'mdx' : 'md'),
|
||||
).process({
|
||||
value: source,
|
||||
path: filePath,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type Processor, type Transformer, unified } from 'unified';
|
||||
import { visit } from 'unist-util-visit';
|
||||
import type { Code, Root, RootContent } from 'mdast';
|
||||
import type { Code, Node, Root, RootContent } from 'mdast';
|
||||
import * as path from 'node:path';
|
||||
import * as fs from 'node:fs/promises';
|
||||
import { fumaMatter } from '@/utils/fuma-matter';
|
||||
@@ -9,13 +9,46 @@ import remarkParse from 'remark-parse';
|
||||
import remarkMdx from 'remark-mdx';
|
||||
import { remarkHeading } from 'fumadocs-core/mdx-plugins';
|
||||
import type { DataMap } from 'vfile';
|
||||
import type { Directives } from 'mdast-util-directive';
|
||||
|
||||
export interface Params {
|
||||
lang?: string;
|
||||
meta?: string;
|
||||
}
|
||||
|
||||
const baseProcessor = unified().use(remarkHeading);
|
||||
const ElementLikeTypes: ElementLikeContent['type'][] = [
|
||||
'mdxJsxFlowElement',
|
||||
'mdxJsxTextElement',
|
||||
'containerDirective',
|
||||
'textDirective',
|
||||
'leafDirective',
|
||||
];
|
||||
type ElementLikeContent = MdxJsxFlowElement | MdxJsxTextElement | Directives;
|
||||
|
||||
function isElementLike(node: Node): node is ElementLikeContent {
|
||||
return ElementLikeTypes.includes(node.type as ElementLikeContent['type']);
|
||||
}
|
||||
|
||||
function parseElementAttributes(
|
||||
element: ElementLikeContent,
|
||||
): Record<string, string | null | undefined> {
|
||||
if (Array.isArray(element.attributes)) {
|
||||
const attributes: Record<string, string | null> = {};
|
||||
|
||||
for (const attr of element.attributes) {
|
||||
if (
|
||||
attr.type === 'mdxJsxAttribute' &&
|
||||
(typeof attr.value === 'string' || attr.value === null)
|
||||
) {
|
||||
attributes[attr.name] = attr.value;
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
return element.attributes ?? {};
|
||||
}
|
||||
|
||||
function flattenNode(node: RootContent): string {
|
||||
if ('children' in node)
|
||||
@@ -39,34 +72,39 @@ function parseSpecifier(specifier: string): {
|
||||
};
|
||||
}
|
||||
|
||||
// do a swallow extract
|
||||
function extractSection(root: Root, section: string): Root | undefined {
|
||||
let nodes: RootContent[] | undefined;
|
||||
let capturingHeadingContent = false;
|
||||
|
||||
for (const node of root.children) {
|
||||
if (
|
||||
node.type === 'mdxJsxFlowElement' &&
|
||||
node.name === 'section' &&
|
||||
node.attributes.some(
|
||||
(attr) =>
|
||||
attr.type === 'mdxJsxAttribute' &&
|
||||
attr.name === 'id' &&
|
||||
attr.value === section,
|
||||
)
|
||||
) {
|
||||
nodes = node.children;
|
||||
break;
|
||||
visit(root, (node) => {
|
||||
if (node.type === 'heading') {
|
||||
if (capturingHeadingContent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node.data?.hProperties?.id === section) {
|
||||
capturingHeadingContent = true;
|
||||
nodes = [node];
|
||||
return 'skip';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.type === 'heading' && node.data?.hProperties?.id === section) {
|
||||
nodes = [node];
|
||||
continue;
|
||||
if (capturingHeadingContent) {
|
||||
nodes?.push(node as RootContent);
|
||||
return 'skip';
|
||||
}
|
||||
|
||||
if (!nodes) continue;
|
||||
if (node.type === 'heading') break;
|
||||
nodes.push(node);
|
||||
}
|
||||
if (isElementLike(node) && node.name === 'section') {
|
||||
const attributes = parseElementAttributes(node);
|
||||
|
||||
if (attributes.id === section) {
|
||||
nodes = node.children;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (nodes)
|
||||
return {
|
||||
@@ -109,70 +147,62 @@ export function remarkInclude(this: Processor): Transformer<Root, Root> {
|
||||
} satisfies Code;
|
||||
}
|
||||
|
||||
const processor = (data._getProcessor ?? getDefaultProcessor)(
|
||||
const parser = (data._getProcessor ?? getDefaultProcessor)(
|
||||
ext === '.mdx' ? 'mdx' : 'md',
|
||||
);
|
||||
let parsed = await baseProcessor.run(
|
||||
processor.parse(fumaMatter(content).content),
|
||||
);
|
||||
const parsed = fumaMatter(content);
|
||||
let mdast = parser.parse({
|
||||
path: file,
|
||||
value: parsed.content,
|
||||
data: { frontmatter: parsed.data as Record<string, unknown> },
|
||||
});
|
||||
|
||||
if (heading) {
|
||||
const extracted = extractSection(parsed, heading);
|
||||
// parse headings before extraction
|
||||
const extracted = extractSection(
|
||||
await unified().use(remarkHeading).run(mdast),
|
||||
heading,
|
||||
);
|
||||
if (!extracted)
|
||||
throw new Error(
|
||||
`Cannot find section ${heading} in ${file}, make sure you have encapsulated the section in a <section id="${heading}"> tag.`,
|
||||
`Cannot find section ${heading} in ${file}, make sure you have encapsulated the section in a <section id="${heading}"> tag, or a :::section directive with remark-directive configured.`,
|
||||
);
|
||||
|
||||
parsed = extracted;
|
||||
mdast = extracted;
|
||||
}
|
||||
|
||||
await update(parsed, path.dirname(file), data);
|
||||
|
||||
return parsed;
|
||||
await update(mdast, path.dirname(file), data);
|
||||
return mdast;
|
||||
}
|
||||
|
||||
async function update(tree: Root, directory: string, data: Partial<DataMap>) {
|
||||
const queue: Promise<void>[] = [];
|
||||
|
||||
visit(
|
||||
tree,
|
||||
['mdxJsxFlowElement', 'mdxJsxTextElement'],
|
||||
(_node, _, parent) => {
|
||||
const node = _node as MdxJsxFlowElement | MdxJsxTextElement;
|
||||
if (node.name !== TagName) return;
|
||||
visit(tree, ElementLikeTypes, (_node, _, parent) => {
|
||||
const node = _node as ElementLikeContent;
|
||||
if (node.name !== TagName) return;
|
||||
|
||||
const params: Record<string, string | null> = {};
|
||||
const specifier = flattenNode(node);
|
||||
if (specifier.length === 0) return 'skip';
|
||||
const specifier = flattenNode(node);
|
||||
if (specifier.length === 0) return 'skip';
|
||||
|
||||
for (const attr of node.attributes) {
|
||||
if (
|
||||
attr.type === 'mdxJsxAttribute' &&
|
||||
(typeof attr.value === 'string' || attr.value === null)
|
||||
) {
|
||||
params[attr.name] = attr.value;
|
||||
}
|
||||
}
|
||||
const attributes = parseElementAttributes(node);
|
||||
const { file: relativePath, section } = parseSpecifier(specifier);
|
||||
const file = path.resolve(
|
||||
'cwd' in attributes ? process.cwd() : directory,
|
||||
relativePath,
|
||||
);
|
||||
|
||||
const { file: relativePath, section } = parseSpecifier(specifier);
|
||||
queue.push(
|
||||
embedContent(file, section, attributes, data).then((replace) => {
|
||||
Object.assign(
|
||||
parent && parent.type === 'paragraph' ? parent : node,
|
||||
replace,
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
const file = path.resolve(
|
||||
'cwd' in params ? process.cwd() : directory,
|
||||
relativePath,
|
||||
);
|
||||
|
||||
queue.push(
|
||||
embedContent(file, section, params, data).then((replace) => {
|
||||
Object.assign(
|
||||
parent && parent.type === 'paragraph' ? parent : node,
|
||||
replace,
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
return 'skip';
|
||||
},
|
||||
);
|
||||
return 'skip';
|
||||
});
|
||||
|
||||
await Promise.all(queue);
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ import { _runtimeAsync, buildConfig } from "fumadocs-mdx/runtime/async"
|
||||
const _sourceConfig = buildConfig(_source)
|
||||
import { _runtime } from "fumadocs-mdx"
|
||||
import * as _source from "./config"
|
||||
export const docs = _runtimeAsync.doc<typeof _source.docs>([{"info":{"path":"index.mdx","fullPath":"$cwd/packages/mdx/test/fixtures/index.mdx"},"data":{},"content":{"body":"# Hello World\n","matter":""}}, {"info":{"path":"folder/test.mdx","fullPath":"$cwd/packages/mdx/test/fixtures/folder/test.mdx"},"data":{},"content":{"body":"","matter":""}}], "docs", _sourceConfig)
|
||||
export const docs = _runtimeAsync.doc<typeof _source.docs>([{"info":{"path":"index.mdx","fullPath":"$cwd/packages/mdx/test/fixtures/generate-index/index.mdx"},"data":{},"content":{"body":"# Hello World\n","matter":""}}, {"info":{"path":"folder/test.mdx","fullPath":"$cwd/packages/mdx/test/fixtures/generate-index/folder/test.mdx"},"data":{},"content":{"body":"","matter":""}}], "docs", _sourceConfig)
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
// @ts-nocheck -- skip type checking
|
||||
import * as docs_1 from "./folder/test.mdx?collection=docs&hash=hash"
|
||||
import * as docs_0 from "./index.mdx?collection=docs&hash=hash"
|
||||
import * as docs_1 from "./generate-index/folder/test.mdx?collection=docs&hash=hash"
|
||||
import * as docs_0 from "./generate-index/index.mdx?collection=docs&hash=hash"
|
||||
import { _runtime } from "fumadocs-mdx"
|
||||
import * as _source from "./config"
|
||||
export const docs = _runtime.doc<typeof _source.docs>([{ info: {"path":"index.mdx","fullPath":"$cwd/packages/mdx/test/fixtures/index.mdx"}, data: docs_0 }, { info: {"path":"folder/test.mdx","fullPath":"$cwd/packages/mdx/test/fixtures/folder/test.mdx"}, data: docs_1 }]);
|
||||
export const docs = _runtime.doc<typeof _source.docs>([{ info: {"path":"index.mdx","fullPath":"$cwd/packages/mdx/test/fixtures/generate-index/index.mdx"}, data: docs_0 }, { info: {"path":"folder/test.mdx","fullPath":"$cwd/packages/mdx/test/fixtures/generate-index/folder/test.mdx"}, data: docs_1 }]);
|
||||
@@ -0,0 +1,29 @@
|
||||
## Using JSX
|
||||
|
||||
Full:
|
||||
|
||||
<include>./test.mdx</include>
|
||||
|
||||
First Heading:
|
||||
|
||||
<include>./test.mdx#heading</include>
|
||||
|
||||
In JSX:
|
||||
|
||||
<include>./test.mdx#section-in-jsx</include>
|
||||
|
||||
In Directive:
|
||||
|
||||
<include>./test.mdx#section-in-directive</include>
|
||||
|
||||
## Using Directives
|
||||
|
||||
In Directive:
|
||||
|
||||
:::include
|
||||
./test.mdx#section-in-directive
|
||||
:::
|
||||
|
||||
Inline Directive:
|
||||
|
||||
::include[./test.mdx#section-in-directive]
|
||||
@@ -0,0 +1,75 @@
|
||||
## Using JSX
|
||||
|
||||
Full:
|
||||
|
||||
# Hello World \[#heading]
|
||||
|
||||
Hey there!
|
||||
|
||||
<section id="section-in-jsx">
|
||||
This is My Test.
|
||||
|
||||
### Nested Heading
|
||||
|
||||
```ts
|
||||
console.log('Hello World');
|
||||
```
|
||||
</section>
|
||||
|
||||
:::section{#section-in-directive}
|
||||
### Heading in Directive
|
||||
|
||||
some content inside.
|
||||
:::
|
||||
|
||||
First Heading:
|
||||
|
||||
# Hello World
|
||||
|
||||
Hey there!
|
||||
|
||||
<section id="section-in-jsx">
|
||||
This is My Test.
|
||||
|
||||
### Nested Heading
|
||||
|
||||
```ts
|
||||
console.log('Hello World');
|
||||
```
|
||||
</section>
|
||||
|
||||
:::section{#section-in-directive}
|
||||
### Heading in Directive
|
||||
|
||||
some content inside.
|
||||
:::
|
||||
|
||||
In JSX:
|
||||
|
||||
This is My Test.
|
||||
|
||||
### Nested Heading
|
||||
|
||||
```ts
|
||||
console.log('Hello World');
|
||||
```
|
||||
|
||||
In Directive:
|
||||
|
||||
### Heading in Directive
|
||||
|
||||
some content inside.
|
||||
|
||||
## Using Directives
|
||||
|
||||
In Directive:
|
||||
|
||||
### Heading in Directive
|
||||
|
||||
some content inside.
|
||||
|
||||
Inline Directive:
|
||||
|
||||
### Heading in Directive
|
||||
|
||||
some content inside.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Hello World [#heading]
|
||||
|
||||
Hey there!
|
||||
|
||||
<section id="section-in-jsx">
|
||||
|
||||
This is My Test.
|
||||
|
||||
### Nested Heading
|
||||
|
||||
```ts
|
||||
console.log('Hello World');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
:::section{#section-in-directive}
|
||||
|
||||
### Heading in Directive
|
||||
|
||||
some content inside.
|
||||
|
||||
:::
|
||||
@@ -38,21 +38,20 @@ test('format errors', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
const file = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const dir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const cases = [
|
||||
{
|
||||
name: 'sync',
|
||||
collection: defineCollections({
|
||||
type: 'doc',
|
||||
dir: path.join(file, './fixtures'),
|
||||
dir: path.join(dir, './fixtures/generate-index'),
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'async',
|
||||
collection: defineCollections({
|
||||
type: 'doc',
|
||||
dir: path.join(file, './fixtures'),
|
||||
dir: path.join(dir, './fixtures/generate-index'),
|
||||
async: true,
|
||||
}),
|
||||
},
|
||||
@@ -61,7 +60,7 @@ const cases = [
|
||||
for (const { name, collection } of cases) {
|
||||
test(`generate JS index file: ${name}`, async () => {
|
||||
const out = await generateJS(
|
||||
path.join(file, './fixtures/config.ts'),
|
||||
path.join(dir, './fixtures/config.ts'),
|
||||
{
|
||||
// @ts-expect-error -- test file
|
||||
_runtime: {
|
||||
@@ -70,7 +69,7 @@ for (const { name, collection } of cases) {
|
||||
collections: new Map([['docs', collection]]),
|
||||
},
|
||||
{
|
||||
relativeTo: path.join(file, './fixtures'),
|
||||
relativeTo: path.join(dir, './fixtures'),
|
||||
},
|
||||
'hash',
|
||||
);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { expect, test } from 'vitest';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import remarkMdx from 'remark-mdx';
|
||||
import { remarkInclude } from '@/mdx/remark-include';
|
||||
import remarkDirective from 'remark-directive';
|
||||
import fs from 'node:fs/promises';
|
||||
import { remark } from 'remark';
|
||||
|
||||
const dir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const processor = remark()
|
||||
.use(remarkMdx)
|
||||
.use(remarkInclude)
|
||||
.use(remarkDirective);
|
||||
test('remark include', async () => {
|
||||
const file = path.join(dir, 'fixtures/remark-include/index.mdx');
|
||||
const out = await processor.process({
|
||||
path: file,
|
||||
value: await fs.readFile(file),
|
||||
data: {
|
||||
_getProcessor() {
|
||||
return processor as any;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await expect(String(out.value)).toMatchFileSnapshot(
|
||||
'fixtures/remark-include/index.out.mdx',
|
||||
);
|
||||
});
|
||||
Generated
+51
@@ -1604,6 +1604,9 @@ importers:
|
||||
fumadocs-core:
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
mdast-util-directive:
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0
|
||||
mdast-util-mdx-jsx:
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0
|
||||
@@ -1613,6 +1616,12 @@ importers:
|
||||
react:
|
||||
specifier: ^19.1.1
|
||||
version: 19.1.1
|
||||
remark:
|
||||
specifier: ^15.0.1
|
||||
version: 15.0.1
|
||||
remark-directive:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
rollup:
|
||||
specifier: ^4.50.1
|
||||
version: 4.50.1
|
||||
@@ -8047,6 +8056,9 @@ packages:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
|
||||
|
||||
@@ -8145,6 +8157,9 @@ packages:
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==}
|
||||
|
||||
@@ -9230,6 +9245,9 @@ packages:
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==}
|
||||
|
||||
[email protected]:
|
||||
resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==}
|
||||
|
||||
@@ -17806,6 +17824,20 @@ snapshots:
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
'@types/unist': 3.0.3
|
||||
ccount: 2.0.1
|
||||
devlop: 1.1.0
|
||||
mdast-util-from-markdown: 2.0.2
|
||||
mdast-util-to-markdown: 2.1.2
|
||||
parse-entities: 4.0.2
|
||||
stringify-entities: 4.0.4
|
||||
unist-util-visit-parents: 6.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
@@ -18069,6 +18101,16 @@ snapshots:
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
devlop: 1.1.0
|
||||
micromark-factory-space: 2.0.1
|
||||
micromark-factory-whitespace: 2.0.1
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
parse-entities: 4.0.2
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
fault: 2.0.1
|
||||
@@ -19492,6 +19534,15 @@ snapshots:
|
||||
hast-util-to-html: 9.0.5
|
||||
unified: 11.0.5
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
mdast-util-directive: 3.1.0
|
||||
micromark-extension-directive: 4.0.0
|
||||
unified: 11.0.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
|
||||
Reference in New Issue
Block a user