diff --git a/.changeset/modern-snakes-taste.md b/.changeset/modern-snakes-taste.md
new file mode 100644
index 0000000000..a70972e7cc
--- /dev/null
+++ b/.changeset/modern-snakes-taste.md
@@ -0,0 +1,8 @@
+---
+'nextra': minor
+'nextra-theme-docs': minor
+---
+
+- show headings for partial md/mdx in toc
+
+- hide headings in toc when parent `` or ``
diff --git a/.gitignore b/.gitignore
index fcff5f2efb..3ecefe5ea1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,5 @@ packages/nextra-theme-*/style.css
.idea/
.eslintcache
.env
+
+tsup.config.bundled*
diff --git a/examples/blog/package.json b/examples/blog/package.json
index 24c1be9779..de19547d12 100644
--- a/examples/blog/package.json
+++ b/examples/blog/package.json
@@ -10,7 +10,7 @@
"start": "next start"
},
"dependencies": {
- "next": "^13.4.8",
+ "next": "^13.4.19",
"nextra": "workspace:*",
"nextra-theme-blog": "workspace:*",
"react": "^18.2.0",
diff --git a/examples/docs/package.json b/examples/docs/package.json
index 388e942ea1..ceff9efbd2 100644
--- a/examples/docs/package.json
+++ b/examples/docs/package.json
@@ -9,7 +9,7 @@
"start": "next start"
},
"dependencies": {
- "next": "^13.4.8",
+ "next": "^13.4.19",
"nextra": "workspace:*",
"nextra-theme-docs": "workspace:*",
"react": "*",
diff --git a/examples/swr-site/package.json b/examples/swr-site/package.json
index e8cb05d5d8..de0ab55b32 100644
--- a/examples/swr-site/package.json
+++ b/examples/swr-site/package.json
@@ -16,7 +16,7 @@
"intersection-observer": "^0.10.0",
"isomorphic-git": "1.21.0",
"markdown-to-jsx": "^6.11.4",
- "next": "^13.4.8",
+ "next": "^13.4.19",
"nextra": "workspace:*",
"nextra-theme-docs": "workspace:*",
"react": "^18.2.0",
diff --git a/examples/swr-site/pages/foo.en-US.md b/examples/swr-site/pages/foo.en-US.md
index 62a1852d0e..d992d448c3 100644
--- a/examples/swr-site/pages/foo.en-US.md
+++ b/examples/swr-site/pages/foo.en-US.md
@@ -7,18 +7,6 @@
## after
-
-
-
```sh npm2yarn
npm i @graphql-eslint/eslint-plugin
```
diff --git a/package.json b/package.json
index aab62f1efb..48970a231b 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
},
"pnpm": {
"overrides": {
- "vitest": "^0.27.1",
+ "vitest": "^0.29.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@mdx-js/react": "^2.3.0",
diff --git a/packages/nextra-theme-blog/package.json b/packages/nextra-theme-blog/package.json
index 6608f55dc5..88e151cd31 100644
--- a/packages/nextra-theme-blog/package.json
+++ b/packages/nextra-theme-blog/package.json
@@ -69,7 +69,7 @@
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"concurrently": "^8.0.0",
- "next": "^13.4.8",
+ "next": "^13.4.19",
"nextra": "workspace:*",
"postcss": "^8.4.28",
"postcss-cli": "^10.1.0",
diff --git a/packages/nextra-theme-docs/package.json b/packages/nextra-theme-docs/package.json
index 9a9c1a9fec..4e0f0574d3 100644
--- a/packages/nextra-theme-docs/package.json
+++ b/packages/nextra-theme-docs/package.json
@@ -61,7 +61,7 @@
"@vitejs/plugin-react": "^3.0.1",
"concurrently": "^8.0.0",
"jsdom": "^22.0.0",
- "next": "^13.4.8",
+ "next": "^13.4.19",
"nextra": "workspace:*",
"postcss": "^8.4.28",
"postcss-cli": "^10.1.0",
diff --git a/packages/nextra/__test__/__snapshots__/compile.test.ts.snap b/packages/nextra/__test__/__snapshots__/compile.test.ts.snap
index 0b5e66eb03..95bfa491cd 100644
--- a/packages/nextra/__test__/__snapshots__/compile.test.ts.snap
+++ b/packages/nextra/__test__/__snapshots__/compile.test.ts.snap
@@ -1,17 +1,15 @@
-// Vitest Snapshot v1
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Process heading > code-h1 1`] = `
{
"frontMatter": {},
- "headings": [
- {
- "depth": 1,
- "id": "codegenyml",
- "value": "codegen.yml",
- },
- ],
"result": "/*@jsxRuntime automatic @jsxImportSource react*/
import {useMDXComponents as _provideComponents} from \\"nextra/mdx\\";
+export const __headings = [{
+ depth: 1,
+ value: \\"codegen.yml\\",
+ id: \\"codegenyml\\"
+}];
function _createMdxContent(props) {
const _components = Object.assign({
h1: \\"h1\\",
@@ -25,7 +23,6 @@ function MDXContent(props = {}) {
}
export default MDXContent;
",
- "searchIndexKey": null,
"title": "codegen.yml",
}
`;
@@ -33,15 +30,13 @@ export default MDXContent;
exports[`Process heading > code-with-text-h1 1`] = `
{
"frontMatter": {},
- "headings": [
- {
- "depth": 1,
- "id": "codegenyml-file",
- "value": "codegen.yml file",
- },
- ],
"result": "/*@jsxRuntime automatic @jsxImportSource react*/
import {useMDXComponents as _provideComponents} from \\"nextra/mdx\\";
+export const __headings = [{
+ depth: 1,
+ value: \\"codegen.yml file\\",
+ id: \\"codegenyml-file\\"
+}];
function _createMdxContent(props) {
const _components = Object.assign({
h1: \\"h1\\",
@@ -55,7 +50,6 @@ function MDXContent(props = {}) {
}
export default MDXContent;
",
- "searchIndexKey": null,
"title": "codegen.yml file",
}
`;
@@ -64,13 +58,6 @@ exports[`Process heading > dynamic-h1 1`] = `
{
"frontMatter": {},
"hasJsxInH1": true,
- "headings": [
- {
- "depth": 1,
- "id": "posts-tagged-with-",
- "value": "Posts Tagged with “”",
- },
- ],
"result": "/*@jsxRuntime automatic @jsxImportSource react*/
import {useMDXComponents as _provideComponents} from \\"nextra/mdx\\";
import {useRouter} from 'next/router';
@@ -78,6 +65,11 @@ export const TagName = () => {
const {tag} = useRouter().query;
return tag || null;
};
+export const __headings = [{
+ depth: 1,
+ value: \\"Posts Tagged with “”\\",
+ id: \\"posts-tagged-with-\\"
+}];
function _createMdxContent(props) {
const _components = Object.assign({
h1: \\"h1\\"
@@ -90,7 +82,6 @@ function MDXContent(props = {}) {
}
export default MDXContent;
",
- "searchIndexKey": null,
"title": "Posts Tagged with “”",
}
`;
@@ -98,15 +89,13 @@ export default MDXContent;
exports[`Process heading > no-h1 1`] = `
{
"frontMatter": {},
- "headings": [
- {
- "depth": 2,
- "id": "h2",
- "value": "H2",
- },
- ],
"result": "/*@jsxRuntime automatic @jsxImportSource react*/
import {useMDXComponents as _provideComponents} from \\"nextra/mdx\\";
+export const __headings = [{
+ depth: 2,
+ value: \\"H2\\",
+ id: \\"h2\\"
+}];
function _createMdxContent(props) {
const _components = Object.assign({
h2: \\"h2\\"
@@ -119,22 +108,19 @@ function MDXContent(props = {}) {
}
export default MDXContent;
",
- "searchIndexKey": null,
}
`;
exports[`Process heading > static-h1 1`] = `
{
"frontMatter": {},
- "headings": [
- {
- "depth": 1,
- "id": "hello-world",
- "value": "Hello World",
- },
- ],
"result": "/*@jsxRuntime automatic @jsxImportSource react*/
import {useMDXComponents as _provideComponents} from \\"nextra/mdx\\";
+export const __headings = [{
+ depth: 1,
+ value: \\"Hello World\\",
+ id: \\"hello-world\\"
+}];
function _createMdxContent(props) {
const _components = Object.assign({
h1: \\"h1\\"
@@ -147,7 +133,6 @@ function MDXContent(props = {}) {
}
export default MDXContent;
",
- "searchIndexKey": null,
"title": "Hello World",
}
`;
diff --git a/packages/nextra/__test__/__snapshots__/context.test.ts.snap b/packages/nextra/__test__/__snapshots__/context.test.ts.snap
index ac2c2132a6..729ddcf940 100644
--- a/packages/nextra/__test__/__snapshots__/context.test.ts.snap
+++ b/packages/nextra/__test__/__snapshots__/context.test.ts.snap
@@ -1,4 +1,4 @@
-// Vitest Snapshot v1
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`context > getAllPages() > should work 1`] = `
[
diff --git a/packages/nextra/__test__/__snapshots__/normalize-page.spec.ts.snap b/packages/nextra/__test__/__snapshots__/normalize-page.spec.ts.snap
index c6fca482dd..e334ee5683 100644
--- a/packages/nextra/__test__/__snapshots__/normalize-page.spec.ts.snap
+++ b/packages/nextra/__test__/__snapshots__/normalize-page.spec.ts.snap
@@ -1,4 +1,4 @@
-// Vitest Snapshot v1
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`normalize-page > /404 page 1`] = `
{
diff --git a/packages/nextra/__test__/__snapshots__/page-map.test.ts.snap b/packages/nextra/__test__/__snapshots__/page-map.test.ts.snap
index ce403a7ab6..03d4ed3437 100644
--- a/packages/nextra/__test__/__snapshots__/page-map.test.ts.snap
+++ b/packages/nextra/__test__/__snapshots__/page-map.test.ts.snap
@@ -1,4 +1,4 @@
-// Vitest Snapshot v1
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Page Process > pageMap en-US 1`] = `
[
diff --git a/packages/nextra/__test__/collect-catch-all.test.ts b/packages/nextra/__test__/collect-catch-all.test.ts
index 359f9ec81e..5dcab23468 100644
--- a/packages/nextra/__test__/collect-catch-all.test.ts
+++ b/packages/nextra/__test__/collect-catch-all.test.ts
@@ -1,4 +1,3 @@
-import { describe, expect, it } from 'vitest'
import { createCatchAllMeta } from '../src/catch-all'
import { collectCatchAllRoutes } from '../src/setup-page'
diff --git a/packages/nextra/__test__/compile.test.ts b/packages/nextra/__test__/compile.test.ts
index ef5cdd281f..ec3d480a2f 100644
--- a/packages/nextra/__test__/compile.test.ts
+++ b/packages/nextra/__test__/compile.test.ts
@@ -1,6 +1,5 @@
import fs from 'node:fs/promises'
import path from 'node:path'
-import { describe, expect, it } from 'vitest'
import { compileMdx } from '../src/compile'
import { CWD } from '../src/constants'
@@ -77,6 +76,80 @@ describe('Process heading', () => {
const { result } = await compileMdx(`### My Header`, { mdxOptions })
expect(result).toMatch(`<_components.h3 id="my-header">{"My Header"}`)
})
+
+ it('should merge headings from partial components', async () => {
+ const { result } = await compileMdx(
+ `
+import FromMdx from './one.mdx'
+import FromMarkdown from './two.md'
+import IgnoreMe from './foo'
+
+## ❤️
+
+
+
+## ✅
+
+
+
+import Last from './three.mdx'
+
+
+
+
+
+## 👋`,
+ { mdxOptions }
+ )
+ expect(result).toMatchInlineSnapshot(`
+ "/*@jsxRuntime automatic @jsxImportSource react*/
+ import {useMDXComponents as _provideComponents} from \\"nextra/mdx\\";
+ import FromMdx, {__headings as __headings0} from './one.mdx';
+ import FromMarkdown, {__headings as __headings1} from './two.md';
+ import IgnoreMe from './foo';
+ import Last, {__headings as __headings2} from './three.mdx';
+ export const __headings = [{
+ depth: 2,
+ value: \\"❤️\\",
+ id: \\"️\\"
+ }, ...__headings0, {
+ depth: 2,
+ value: \\"✅\\",
+ id: \\"\\"
+ }, ...__headings1, ...__headings2, {
+ depth: 2,
+ value: \\"👋\\",
+ id: \\"-1\\"
+ }];
+ function _createMdxContent(props) {
+ const _components = Object.assign({
+ h2: \\"h2\\"
+ }, _provideComponents(), props.components);
+ return <><_components.h2 id=\\"️\\">{\\"❤️\\"}{\\"\\\\n\\"}{\\"\\\\n\\"}<_components.h2 id=\\"\\">{\\"✅\\"}{\\"\\\\n\\"}{\\"\\\\n\\"}{\\"\\\\n\\"}{\\"\\\\n\\"}{\\"\\\\n\\"}<_components.h2 id=\\"-1\\">{\\"👋\\"}>;
+ }
+ function MDXContent(props = {}) {
+ const {wrapper: MDXLayout} = Object.assign({}, _provideComponents(), props.components);
+ return MDXLayout ? <_createMdxContent {...props} /> : _createMdxContent(props);
+ }
+ export default MDXContent;
+ "
+ `)
+ })
+ it('should not attach headings with parent Tab or Tabs.Tab', async () => {
+ const { result } = await compileMdx(
+ `
+
+ ## hello
+
+
+
+ ## World
+
+`,
+ { mdxOptions }
+ )
+ expect(result).toMatch('export const __headings = [];')
+ })
})
describe('Link', () => {
diff --git a/packages/nextra/__test__/context.test.ts b/packages/nextra/__test__/context.test.ts
index 5d94a88f74..5560ad4590 100644
--- a/packages/nextra/__test__/context.test.ts
+++ b/packages/nextra/__test__/context.test.ts
@@ -1,5 +1,4 @@
import path from 'node:path'
-import { beforeAll, describe, expect, it } from 'vitest'
import { CWD, NEXTRA_INTERNAL } from '../src/constants'
import {
getAllPages,
diff --git a/packages/nextra/__test__/loader.test.ts b/packages/nextra/__test__/loader.test.ts
index 79fba46a22..e3823652eb 100644
--- a/packages/nextra/__test__/loader.test.ts
+++ b/packages/nextra/__test__/loader.test.ts
@@ -1,6 +1,5 @@
import fs from 'node:fs/promises'
import path from 'node:path'
-import { describe, expect, it } from 'vitest'
import { CWD } from '../src/constants'
describe('tree shaking', async () => {
diff --git a/packages/nextra/__test__/locale-with-base-path.test.ts b/packages/nextra/__test__/locale-with-base-path.test.ts
index abb8adec46..801895dfd5 100644
--- a/packages/nextra/__test__/locale-with-base-path.test.ts
+++ b/packages/nextra/__test__/locale-with-base-path.test.ts
@@ -5,7 +5,6 @@ process.env.__NEXT_ROUTER_BASEPATH = '/testBasePath'
import { NextRequest } from 'next/server'
import type NextServer from 'next/server'
-import { describe, expect, it, vi } from 'vitest'
import { locales as originalLocales } from '../src/locales'
vi.mock('next/server', async () => {
diff --git a/packages/nextra/__test__/locale.test.ts b/packages/nextra/__test__/locale.test.ts
index 392b3567ac..96032162de 100644
--- a/packages/nextra/__test__/locale.test.ts
+++ b/packages/nextra/__test__/locale.test.ts
@@ -1,6 +1,5 @@
import { NextRequest } from 'next/server'
import type NextServer from 'next/server'
-import { describe, expect, it, vi } from 'vitest'
import { locales as originalLocales } from '../src/locales'
vi.mock('next/server', async () => {
diff --git a/packages/nextra/__test__/normalize-page.spec.ts b/packages/nextra/__test__/normalize-page.spec.ts
index d01df12854..c91487a8b4 100644
--- a/packages/nextra/__test__/normalize-page.spec.ts
+++ b/packages/nextra/__test__/normalize-page.spec.ts
@@ -1,4 +1,3 @@
-import { describe, expect, it } from 'vitest'
import { normalizePages } from '../src/normalize-pages'
import { cnPageMap, usPageMap } from './fixture/page-maps/pageMap'
diff --git a/packages/nextra/__test__/page-map.test.ts b/packages/nextra/__test__/page-map.test.ts
index 849f63faa6..932658e098 100644
--- a/packages/nextra/__test__/page-map.test.ts
+++ b/packages/nextra/__test__/page-map.test.ts
@@ -1,5 +1,4 @@
import path from 'node:path'
-import { beforeAll, describe, expect, it } from 'vitest'
import { CWD } from '../src/constants'
import { getDynamicMeta, resolvePageMap } from '../src/page-map'
import { collectFiles } from '../src/plugin'
diff --git a/packages/nextra/__test__/sort-pages.test.ts b/packages/nextra/__test__/sort-pages.test.ts
index 19a9d4714c..63b18ceb29 100644
--- a/packages/nextra/__test__/sort-pages.test.ts
+++ b/packages/nextra/__test__/sort-pages.test.ts
@@ -1,4 +1,3 @@
-import { describe, expect, it } from 'vitest'
import { sortPages } from '../src/utils'
const kind = 'MdxPage'
diff --git a/packages/nextra/__test__/use-fs-route.spec.ts b/packages/nextra/__test__/use-fs-route.spec.ts
index b2623b890a..11112d6bd4 100644
--- a/packages/nextra/__test__/use-fs-route.spec.ts
+++ b/packages/nextra/__test__/use-fs-route.spec.ts
@@ -1,7 +1,6 @@
import { renderHook } from '@testing-library/react'
import { useRouter } from 'next/router'
import type { Mock } from 'vitest'
-import { describe, expect, it, vi } from 'vitest'
import { useFSRoute } from '../src/hooks'
vi.mock('next/router', () => ({
diff --git a/packages/nextra/__test__/utils.test.ts b/packages/nextra/__test__/utils.test.ts
index 954c2c5856..3ff0b091d2 100644
--- a/packages/nextra/__test__/utils.test.ts
+++ b/packages/nextra/__test__/utils.test.ts
@@ -1,4 +1,3 @@
-import { describe, expect, it } from 'vitest'
import { parseFileName } from '../src/utils'
describe('Utils', () => {
diff --git a/packages/nextra/package.json b/packages/nextra/package.json
index 441e2e32f0..a6f5173e31 100644
--- a/packages/nextra/package.json
+++ b/packages/nextra/package.json
@@ -103,7 +103,6 @@
},
"files": [
"dist/*",
- "icons/*",
"loader.js",
"styles/*"
],
@@ -139,7 +138,6 @@
"rehype-katex": "^6.0.3",
"rehype-pretty-code": "0.9.11",
"rehype-raw": "^6.1.1",
- "rehype-sanitize": "^5.0.1",
"remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"remark-reading-time": "^2.0.1",
@@ -161,7 +159,7 @@
"@types/webpack-env": "^1.18.1",
"@vitejs/plugin-react": "^3.0.1",
"fast-glob": "^3.2.12",
- "next": "^13.4.8",
+ "next": "^13.4.19",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"unified": "^10.1.2",
diff --git a/packages/nextra/src/compile.ts b/packages/nextra/src/compile.ts
index 2585b85602..07d35d26bd 100644
--- a/packages/nextra/src/compile.ts
+++ b/packages/nextra/src/compile.ts
@@ -10,7 +10,6 @@ import rehypeKatex from 'rehype-katex'
import type { Options as RehypePrettyCodeOptions } from 'rehype-pretty-code'
import rehypePrettyCode from 'rehype-pretty-code'
import rehypeRaw from 'rehype-raw'
-import rehypeSanitize from 'rehype-sanitize'
import remarkGfm from 'remark-gfm'
import remarkMath from 'remark-math'
import remarkReadingTime from 'remark-reading-time'
@@ -187,17 +186,12 @@ export async function compileMdx(
].filter(truthy),
rehypePlugins: [
...(rehypePlugins || []),
- ...(format === 'md'
- ? [
- [
- // To render and correctly
- rehypeRaw,
- // fix Error: Cannot compile `mdxjsEsm` node for npm2yarn and mermaid
- { passThrough: ['mdxjsEsm', 'mdxJsxFlowElement'] }
- ],
- rehypeSanitize // To remove
- ]
- : []),
+ format === 'md' && [
+ // To render and correctly
+ rehypeRaw,
+ // fix Error: Cannot compile `mdxjsEsm` node for npm2yarn and mermaid
+ { passThrough: ['mdxjsEsm', 'mdxJsxFlowElement'] }
+ ],
[parseMeta, { defaultShowCopyCode }],
codeHighlight !== false &&
([
@@ -217,24 +211,20 @@ export async function compileMdx(
filePath ? { value: content, path: filePath } : content
)
- const { headings, hasJsxInH1, readingTime, structurizedData } =
- vFile.data as {
- readingTime?: ReadingTime
- structurizedData: StructurizedData
- } & Pick
-
- const title = headings.find(h => h.depth === 1)?.value
+ const { title, hasJsxInH1, readingTime, structurizedData } = vFile.data as {
+ readingTime?: ReadingTime
+ structurizedData: StructurizedData
+ title?: string
+ } & Pick
// https://github.com/shuding/nextra/issues/1032
const result = String(vFile).replaceAll('__esModule', '_\\_esModule')
return {
result,
- headings,
...(hasJsxInH1 && { hasJsxInH1 }),
...(title && { title }),
...(readingTime && { readingTime }),
- ...(searchIndexKey !== null && { structurizedData }),
- searchIndexKey,
+ ...(searchIndexKey !== null && { searchIndexKey, structurizedData }),
frontMatter
}
} catch (err) {
diff --git a/packages/nextra/src/loader.ts b/packages/nextra/src/loader.ts
index 61b36f801f..dec9e5bb94 100644
--- a/packages/nextra/src/loader.ts
+++ b/packages/nextra/src/loader.ts
@@ -163,7 +163,6 @@ async function loader(
const {
result,
- headings,
title,
frontMatter,
structurizedData,
@@ -244,7 +243,6 @@ async function loader(
filePath: slash(path.relative(CWD, mdxPath)),
route,
...(Object.keys(frontMatter).length > 0 && { frontMatter }),
- headings,
hasJsxInH1,
timestamp,
pageMap,
@@ -293,7 +291,8 @@ ${
delete pageOpts.pageMap
}
- const stringifiedPageOpts = JSON.stringify(pageOpts)
+ const stringifiedPageOpts =
+ JSON.stringify(pageOpts).slice(0, -1) + `,headings:__headings}`
const stringifiedChecksum = IS_PRODUCTION
? "''"
: JSON.stringify(hashFnv32a(stringifiedPageOpts))
@@ -307,9 +306,12 @@ ${
)
.join(',')
- return `import { setupNextraPage } from 'nextra/setup-page'
+ const res = `import { setupNextraPage } from 'nextra/setup-page'
${HAS_UNDERSCORE_APP_MDX_FILE ? '' : pageImports}
-
+${
+ // Remove the last match of `export default MDXContent` because it can be existed in the raw MDX file
+ finalResult.slice(0, finalResult.lastIndexOf('export default MDXContent;'))
+}
const __nextraPageOptions = {
MDXContent,
pageOpts: ${stringifiedPageOpts},
@@ -321,10 +323,6 @@ const __nextraPageOptions = {
(themeConfigImport && 'themeConfig: __nextra_themeConfig')
}
}
-${
- // Remove the last match of `export default MDXContent` because it can be existed in the raw MDX file
- finalResult.slice(0, finalResult.lastIndexOf('export default MDXContent;'))
-}
if (process.env.NODE_ENV !== 'production') {
__nextraPageOptions.hot = module.hot
__nextraPageOptions.pageOptsChecksum = ${stringifiedChecksum}
@@ -332,6 +330,7 @@ if (process.env.NODE_ENV !== 'production') {
if (typeof window === 'undefined') __nextraPageOptions.dynamicMetaModules = [${dynamicMetaModules}]
export default setupNextraPage(__nextraPageOptions)`
+ return res
}
export default function syncLoader(
diff --git a/packages/nextra/src/mdx-plugins/remark-headings.ts b/packages/nextra/src/mdx-plugins/remark-headings.ts
index d198cfe532..8cd957dd13 100644
--- a/packages/nextra/src/mdx-plugins/remark-headings.ts
+++ b/packages/nextra/src/mdx-plugins/remark-headings.ts
@@ -1,9 +1,9 @@
-import type { Processor } from '@mdx-js/mdx/lib/core'
import Slugger from 'github-slugger'
import type { Parent, Root } from 'mdast'
import type { Plugin } from 'unified'
import { visit } from 'unist-util-visit'
-import type { PageOpts } from '../types'
+import { MARKDOWN_EXTENSION_REGEX } from '../constants'
+import type { Heading, PageOpts } from '../types'
import type { HProperties } from './remark-custom-heading-id'
const getFlattenedValue = (node: Parent): string =>
@@ -17,52 +17,145 @@ const getFlattenedValue = (node: Parent): string =>
)
.join('')
-export const remarkHeadings: Plugin<[], Root> = function (this: Processor) {
- const headingMeta: Pick = {
+const DISABLE_EXPLICIT_JSX = new Set(['summary', 'details'])
+const SKIP_FOR_PARENT_NAMES = new Set(['Tab', 'Tabs.Tab'])
+
+export const remarkHeadings: Plugin<[exportName?: string], Root> = (
+ exportName = '__headings'
+) => {
+ const headingMeta: Pick & {
+ headings: (Heading | string)[]
+ } = {
headings: []
}
const slugger = new Slugger()
return (tree, file, done) => {
+ const PartialComponentToHeadingsName: Record =
+ Object.create(null)
+
visit(
tree,
[
- // Match headings and
- { type: 'heading' },
- { name: 'summary' },
- { name: 'details' }
+ 'heading',
+ // allow override details/summary + push partial component's __headings export name to headings list
+ 'mdxJsxFlowElement',
+ // verify .md/.mdx exports and attach named __headings export
+ 'mdxjsEsm'
],
- node => {
- if (node.type !== 'heading') {
- // Replace the and with customized components
- if (node.data) {
- delete node.data._mdxExplicitJsx
+ (node, _index, parent) => {
+ if (node.type === 'heading') {
+ const hasJsxInH1 =
+ node.depth === 1 &&
+ node.children.some(
+ (child: { type: string }) => child.type === 'mdxJsxTextElement'
+ )
+ if (hasJsxInH1) {
+ headingMeta.hasJsxInH1 = true
+ }
+ const value = getFlattenedValue(node)
+
+ node.data ||= {}
+ const headingProps = (node.data.hProperties ||= {}) as HProperties
+ const id = slugger.slug(headingProps.id || value)
+ // Attach flattened/custom #id to heading node
+ headingProps.id = id
+ if (!SKIP_FOR_PARENT_NAMES.has((parent as any).name)) {
+ headingMeta.headings.push({
+ depth: node.depth,
+ value,
+ id
+ })
}
return
}
- const hasJsxInH1 =
- node.depth === 1 &&
- node.children.some(
- (child: { type: string }) => child.type === 'mdxJsxTextElement'
- )
- if (hasJsxInH1) {
- headingMeta.hasJsxInH1 = true
+ if ((node as any).type === 'mdxjsEsm') {
+ for (const child of (node as any).data.estree.body) {
+ if (child.type !== 'ImportDeclaration') continue
+ const importPath = child.source.value
+ const isMdxImport = MARKDOWN_EXTENSION_REGEX.test(importPath)
+ if (!isMdxImport) continue
+
+ const componentName = child.specifiers.find(
+ (o: any) => o.type === 'ImportDefaultSpecifier'
+ )?.local.name
+
+ if (!componentName) continue
+ const { length } = Object.keys(PartialComponentToHeadingsName)
+ const exportAsName = `${exportName}${length}`
+ PartialComponentToHeadingsName[componentName] = exportAsName
+
+ child.specifiers.push({
+ type: 'ImportSpecifier',
+ imported: { type: 'Identifier', name: exportName },
+ local: { type: 'Identifier', name: exportAsName }
+ })
+ }
+ return
}
- const value = getFlattenedValue(node)
- node.data ||= {}
- const headingProps = (node.data.hProperties ||= {}) as HProperties
- const id = slugger.slug(headingProps.id || value)
- // Attach flattened/custom #id to heading node
- headingProps.id = id
- headingMeta.headings.push({
- depth: node.depth,
- value,
- id
- })
+ const nodeName = (node as any).name
+ if (DISABLE_EXPLICIT_JSX.has(nodeName)) {
+ // Replace the and with customized components
+ if (node.data) {
+ delete node.data._mdxExplicitJsx
+ }
+ } else {
+ // If component name equals default export name from .md/.mdx import
+ const headingsName = PartialComponentToHeadingsName[nodeName]
+ if (headingsName) {
+ headingMeta.headings.push(headingsName)
+ }
+ }
}
)
- Object.assign(file.data, headingMeta)
+
+ const headingElements = headingMeta.headings.map(heading =>
+ typeof heading === 'string'
+ ? {
+ type: 'SpreadElement',
+ argument: { type: 'Identifier', name: heading }
+ }
+ : {
+ type: 'ObjectExpression',
+ properties: Object.entries(heading).map(([key, value]) => ({
+ type: 'Property',
+ kind: 'init',
+ key: { type: 'Identifier', name: key },
+ value: { type: 'Literal', value }
+ }))
+ }
+ )
+
+ tree.children.push({
+ type: 'mdxjsEsm',
+ data: {
+ estree: {
+ body: [
+ {
+ type: 'ExportNamedDeclaration',
+ specifiers: [],
+ declaration: {
+ type: 'VariableDeclaration',
+ kind: 'const',
+ declarations: [
+ {
+ type: 'VariableDeclarator',
+ id: { type: 'Identifier', name: exportName },
+ init: { type: 'ArrayExpression', elements: headingElements }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ } as any)
+
+ file.data.hasJsxInH1 = headingMeta.hasJsxInH1
+ file.data.title = headingMeta.headings.find(
+ (h): h is Heading => typeof h !== 'string' && h.depth === 1
+ )?.value
done()
}
}
diff --git a/packages/nextra/src/remote.ts b/packages/nextra/src/remote.ts
index a6ba06abc1..37d76d9b8f 100644
--- a/packages/nextra/src/remote.ts
+++ b/packages/nextra/src/remote.ts
@@ -24,7 +24,7 @@ const result = await buildDynamicMDX(rawMdx, {
`)
}
- const { result, headings, frontMatter, title } = await compileMdx(
+ const { result, frontMatter, title } = await compileMdx(
content,
loaderOptions
)
@@ -32,7 +32,6 @@ const result = await buildDynamicMDX(rawMdx, {
return {
__nextra_dynamic_mdx: result,
__nextra_dynamic_opts: JSON.stringify({
- headings,
frontMatter,
title: frontMatter.title || title
})
diff --git a/packages/nextra/src/search/plugin.ts b/packages/nextra/src/search/plugin.ts
index 1fa774379f..c0ad4a49fe 100644
--- a/packages/nextra/src/search/plugin.ts
+++ b/packages/nextra/src/search/plugin.ts
@@ -25,7 +25,7 @@ export class NextraSearchPlugin {
// Nextra
let entryModule =
compilation.moduleGraph.getResolvedModule(entryDependency)
- if (!entryModule?.buildInfo?.nextraSearch) {
+ if (entryModule && !entryModule.buildInfo?.nextraSearch) {
for (const dependency of entryModule.dependencies) {
const mod =
compilation.moduleGraph.getResolvedModule(dependency)
diff --git a/packages/nextra/src/types.ts b/packages/nextra/src/types.ts
index 6eb2328323..674c559ff6 100644
--- a/packages/nextra/src/types.ts
+++ b/packages/nextra/src/types.ts
@@ -82,7 +82,8 @@ export type Page = (MdxFile | Folder) & {
meta?: Exclude
}
-export type Heading = Omit & {
+export type Heading = {
+ depth: MDASTHeading['depth']
value: string
id: string
}
diff --git a/packages/nextra/vite.config.ts b/packages/nextra/vite.config.ts
index c2e7b68f2e..171ffe94ed 100644
--- a/packages/nextra/vite.config.ts
+++ b/packages/nextra/vite.config.ts
@@ -4,6 +4,7 @@ import { defineConfig } from 'vitest/config'
export default defineConfig({
plugins: [react()],
test: {
+ globals: true,
environment: 'jsdom'
}
})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 316fb79e3a..35616fed7d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5,7 +5,7 @@ settings:
excludeLinksFromLockfile: false
overrides:
- vitest: ^0.27.1
+ vitest: ^0.29.8
react: ^18.2.0
react-dom: ^18.2.0
'@mdx-js/react': ^2.3.0
@@ -286,9 +286,6 @@ importers:
rehype-raw:
specifier: ^6.1.1
version: 6.1.1
- rehype-sanitize:
- specifier: ^5.0.1
- version: 5.0.1
remark-gfm:
specifier: ^3.0.1
version: 3.0.1
@@ -360,8 +357,8 @@ importers:
specifier: ^10.1.2
version: 10.1.2
vitest:
- specifier: ^0.27.1
- version: 0.27.1(@edge-runtime/vm@3.1.0)(jsdom@22.0.0)
+ specifier: ^0.29.8
+ version: 0.29.8(@edge-runtime/vm@3.1.0)(jsdom@22.0.0)
packages/nextra-theme-blog:
dependencies:
@@ -415,8 +412,8 @@ importers:
specifier: ^3.3.3
version: 3.3.3
vitest:
- specifier: ^0.27.1
- version: 0.27.1(@edge-runtime/vm@3.1.0)(jsdom@22.0.0)
+ specifier: ^0.29.8
+ version: 0.29.8(@edge-runtime/vm@3.1.0)(jsdom@22.0.0)
packages/nextra-theme-docs:
dependencies:
@@ -515,8 +512,8 @@ importers:
specifier: ^3.3.3
version: 3.3.3
vitest:
- specifier: ^0.27.1
- version: 0.27.1(@edge-runtime/vm@3.1.0)(jsdom@22.0.0)
+ specifier: ^0.29.8
+ version: 0.29.8(@edge-runtime/vm@3.1.0)(jsdom@22.0.0)
packages:
@@ -3733,6 +3730,37 @@ packages:
- supports-color
dev: true
+ /@vitest/expect@0.29.8:
+ resolution: {integrity: sha512-xlcVXn5I5oTq6NiZSY3ykyWixBxr5mG8HYtjvpgg6KaqHm0mvhX18xuwl5YGxIRNt/A5jidd7CWcNHrSvgaQqQ==}
+ dependencies:
+ '@vitest/spy': 0.29.8
+ '@vitest/utils': 0.29.8
+ chai: 4.3.7
+ dev: true
+
+ /@vitest/runner@0.29.8:
+ resolution: {integrity: sha512-FzdhnRDwEr/A3Oo1jtIk/B952BBvP32n1ObMEb23oEJNO+qO5cBet6M2XWIDQmA7BDKGKvmhUf2naXyp/2JEwQ==}
+ dependencies:
+ '@vitest/utils': 0.29.8
+ p-limit: 4.0.0
+ pathe: 1.1.1
+ dev: true
+
+ /@vitest/spy@0.29.8:
+ resolution: {integrity: sha512-VdjBe9w34vOMl5I5mYEzNX8inTxrZ+tYUVk9jxaZJmHFwmDFC/GV3KBFTA/JKswr3XHvZL+FE/yq5EVhb6pSAw==}
+ dependencies:
+ tinyspy: 1.0.2
+ dev: true
+
+ /@vitest/utils@0.29.8:
+ resolution: {integrity: sha512-qGzuf3vrTbnoY+RjjVVIBYfuWMjn3UMUqyQtdGNZ6ZIIyte7B37exj6LaVkrZiUTvzSadVvO/tJm8AEgbGCBPg==}
+ dependencies:
+ cli-truncate: 3.1.0
+ diff: 5.1.0
+ loupe: 2.3.6
+ pretty-format: 27.5.1
+ dev: true
+
/@webassemblyjs/ast@1.11.1:
resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==}
dependencies:
@@ -3871,12 +3899,6 @@ packages:
engines: {node: '>=0.4.0'}
dev: true
- /acorn@8.8.1:
- resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==}
- engines: {node: '>=0.4.0'}
- hasBin: true
- dev: true
-
/acorn@8.9.0:
resolution: {integrity: sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==}
engines: {node: '>=0.4.0'}
@@ -4441,6 +4463,14 @@ packages:
escape-string-regexp: 1.0.5
dev: true
+ /cli-truncate@3.1.0:
+ resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dependencies:
+ slice-ansi: 5.0.0
+ string-width: 5.1.2
+ dev: true
+
/client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
@@ -5178,7 +5208,6 @@ packages:
/diff@5.1.0:
resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==}
engines: {node: '>=0.3.1'}
- dev: false
/dir-glob@3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
@@ -6835,6 +6864,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /is-fullwidth-code-point@4.0.0:
+ resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
+ engines: {node: '>=12'}
+ dev: true
+
/is-generator-function@1.0.10:
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
engines: {node: '>= 0.4'}
@@ -7422,6 +7456,12 @@ packages:
get-func-name: 2.0.0
dev: true
+ /loupe@2.3.6:
+ resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
+ dependencies:
+ get-func-name: 2.0.0
+ dev: true
+
/lower-case@2.0.2:
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
dependencies:
@@ -8168,7 +8208,7 @@ packages:
resolution: {integrity: sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==}
dependencies:
acorn: 8.9.0
- pathe: 1.0.0
+ pathe: 1.1.1
pkg-types: 1.0.1
ufo: 1.0.1
dev: true
@@ -8533,6 +8573,13 @@ packages:
dependencies:
yocto-queue: 0.1.0
+ /p-limit@4.0.0:
+ resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dependencies:
+ yocto-queue: 1.0.0
+ dev: true
+
/p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
@@ -8657,12 +8704,8 @@ packages:
engines: {node: '>=8'}
dev: true
- /pathe@0.2.0:
- resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==}
- dev: true
-
- /pathe@1.0.0:
- resolution: {integrity: sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==}
+ /pathe@1.1.1:
+ resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
dev: true
/pathval@1.1.1:
@@ -8710,7 +8753,7 @@ packages:
dependencies:
jsonc-parser: 3.2.0
mlly: 1.1.0
- pathe: 1.0.0
+ pathe: 1.1.1
dev: true
/pluralize@8.0.0:
@@ -9658,6 +9701,14 @@ packages:
engines: {node: '>=14.16'}
dev: true
+ /slice-ansi@5.0.0:
+ resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
+ engines: {node: '>=12'}
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 4.0.0
+ dev: true
+
/smartwrap@2.0.2:
resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==}
engines: {node: '>=6'}
@@ -9757,6 +9808,10 @@ packages:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
dev: true
+ /std-env@3.4.3:
+ resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==}
+ dev: true
+
/stop-iteration-iterator@1.0.0:
resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
engines: {node: '>= 0.4'}
@@ -10147,8 +10202,8 @@ packages:
resolution: {integrity: sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==}
dev: true
- /tinypool@0.3.0:
- resolution: {integrity: sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==}
+ /tinypool@0.4.0:
+ resolution: {integrity: sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==}
engines: {node: '>=14.0.0'}
dev: true
@@ -10748,18 +10803,16 @@ packages:
unist-util-stringify-position: 3.0.2
vfile-message: 3.1.2
- /vite-node@0.27.1(@types/node@18.11.18):
- resolution: {integrity: sha512-d6+ue/3NzsfndWaPbYh/bFkHbmAWfDXI4B874zRx+WREnG6CUHUbBC8lKaRYZjeR6gCPN5m1aVNNRXBYICA9XA==}
+ /vite-node@0.29.8(@types/node@18.11.18):
+ resolution: {integrity: sha512-b6OtCXfk65L6SElVM20q5G546yu10/kNrhg08afEoWlFRJXFq9/6glsvSVY+aI6YeC1tu2TtAqI2jHEQmOmsFw==}
engines: {node: '>=v14.16.0'}
hasBin: true
dependencies:
cac: 6.7.14
debug: 4.3.4
mlly: 1.1.0
- pathe: 0.2.0
+ pathe: 1.1.1
picocolors: 1.0.0
- source-map: 0.6.1
- source-map-support: 0.5.21
vite: 4.0.4(@types/node@18.11.18)
transitivePeerDependencies:
- '@types/node'
@@ -10805,8 +10858,8 @@ packages:
fsevents: 2.3.2
dev: true
- /vitest@0.27.1(@edge-runtime/vm@3.1.0)(jsdom@22.0.0):
- resolution: {integrity: sha512-1sIpQ1DVFTEn7c1ici1XHcVfdU4nKiBmPtPAtGKJJJLuJjojTv/OHGgcf69P57alM4ty8V4NMv+7Yoi5Cxqx9g==}
+ /vitest@0.29.8(@edge-runtime/vm@3.1.0)(jsdom@22.0.0):
+ resolution: {integrity: sha512-JIAVi2GK5cvA6awGpH0HvH/gEG9PZ0a/WoxdiV3PmqK+3CjQMf8c+J/Vhv4mdZ2nRyXFw66sAg6qz7VNkaHfDQ==}
engines: {node: '>=v14.16.0'}
hasBin: true
peerDependencies:
@@ -10815,6 +10868,9 @@ packages:
'@vitest/ui': '*'
happy-dom: '*'
jsdom: '*'
+ playwright: '*'
+ safaridriver: '*'
+ webdriverio: '*'
peerDependenciesMeta:
'@edge-runtime/vm':
optional: true
@@ -10826,26 +10882,38 @@ packages:
optional: true
jsdom:
optional: true
+ playwright:
+ optional: true
+ safaridriver:
+ optional: true
+ webdriverio:
+ optional: true
dependencies:
'@edge-runtime/vm': 3.1.0
'@types/chai': 4.3.4
'@types/chai-subset': 1.3.3
'@types/node': 18.11.18
- acorn: 8.8.1
+ '@vitest/expect': 0.29.8
+ '@vitest/runner': 0.29.8
+ '@vitest/spy': 0.29.8
+ '@vitest/utils': 0.29.8
+ acorn: 8.9.0
acorn-walk: 8.2.0
cac: 6.7.14
chai: 4.3.7
debug: 4.3.4
jsdom: 22.0.0
local-pkg: 0.4.2
+ pathe: 1.1.1
picocolors: 1.0.0
source-map: 0.6.1
+ std-env: 3.4.3
strip-literal: 1.0.0
tinybench: 2.3.1
- tinypool: 0.3.0
+ tinypool: 0.4.0
tinyspy: 1.0.2
vite: 4.0.4(@types/node@18.11.18)
- vite-node: 0.27.1(@types/node@18.11.18)
+ vite-node: 0.29.8(@types/node@18.11.18)
why-is-node-running: 2.2.2
transitivePeerDependencies:
- less
@@ -11202,6 +11270,11 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
+ /yocto-queue@1.0.0:
+ resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
+ engines: {node: '>=12.20'}
+ dev: true
+
/yoga-wasm-web@0.3.3:
resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==}
dev: false