diff --git a/CHANGELOG.md b/CHANGELOG.md
index 99edf822..7d630958 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+## [2.0.0-alpha.2](https://github.com/vuejs/vitepress/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2025-01-23)
+
+### Bug Fixes
+
+- fix docsearch navigation and rendering ([e035027](https://github.com/vuejs/vitepress/commit/e0350275b39258a61ee867840ce1c6f5b2cecf2a))
+- **types:** support preload built-in shiki languages as string ([#4513](https://github.com/vuejs/vitepress/issues/4513)) ([4f77b4f](https://github.com/vuejs/vitepress/commit/4f77b4fdfdbe945e482348a57731bff5fb4672fc))
+
+### Features
+
+- allow `markdown.config` and `markdown.preConfig` to accept async function ([#4512](https://github.com/vuejs/vitepress/issues/4512)) ([b88ae8d](https://github.com/vuejs/vitepress/commit/b88ae8d4a11a20104b2007c2631eb7aeb123d965))
+- support same page navigation in `router.go` and expose decoded hash and query from the `route` object ([#4511](https://github.com/vuejs/vitepress/issues/4511)) ([23d3281](https://github.com/vuejs/vitepress/commit/23d3281ed6f1111ab15708ca1fd86202674f8ef7))
+
## [2.0.0-alpha.1](https://github.com/vuejs/vitepress/compare/v1.6.2...v2.0.0-alpha.1) (2025-01-22)
### Features
diff --git a/__tests__/e2e/.vitepress/config.ts b/__tests__/e2e/.vitepress/config.ts
index 65f845ab..43dbfa84 100644
--- a/__tests__/e2e/.vitepress/config.ts
+++ b/__tests__/e2e/.vitepress/config.ts
@@ -165,8 +165,8 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('local-search/excluded')) return ''
return html
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
index 7208825e..0e7ba37f 100644
--- a/docs/.vitepress/theme/index.ts
+++ b/docs/.vitepress/theme/index.ts
@@ -1,4 +1,5 @@
import Theme from 'vitepress/theme'
import 'virtual:group-icons.css'
+import './styles.css'
export default Theme
diff --git a/docs/.vitepress/theme/styles.css b/docs/.vitepress/theme/styles.css
new file mode 100644
index 00000000..1c4b3af5
--- /dev/null
+++ b/docs/.vitepress/theme/styles.css
@@ -0,0 +1,40 @@
+@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap');
+
+:root:where(:lang(fa)) {
+ --vp-font-family-base: 'Vazirmatn', 'Inter', ui-sans-serif, system-ui,
+ sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
+ 'Noto Color Emoji';
+}
+
+:root {
+ --vp-home-hero-name-color: transparent;
+ --vp-home-hero-name-background: -webkit-linear-gradient(
+ 120deg,
+ #bd34fe 30%,
+ #41d1ff
+ );
+ --vp-home-hero-image-background-image: linear-gradient(
+ -45deg,
+ #bd34fe 50%,
+ #47caff 50%
+ );
+ --vp-home-hero-image-filter: blur(44px);
+}
+
+@media (min-width: 640px) {
+ :root {
+ --vp-home-hero-image-filter: blur(56px);
+ }
+}
+
+@media (min-width: 960px) {
+ :root {
+ --vp-home-hero-image-filter: blur(68px);
+ }
+}
+
+/* used in reference/default-theme-search */
+img[src='/search.png'] {
+ width: 100%;
+ aspect-ratio: 1 / 1;
+}
diff --git a/docs/en/index.md b/docs/en/index.md
index 9be32c3e..d65ee07b 100644
--- a/docs/en/index.md
+++ b/docs/en/index.md
@@ -36,25 +36,3 @@ features:
title: Ship Fast Sites
details: Fast initial load with static HTML, fast post-load navigation with client-side routing.
---
-
-
diff --git a/docs/en/reference/default-theme-search.md b/docs/en/reference/default-theme-search.md
index 16bb9289..d647e32e 100644
--- a/docs/en/reference/default-theme-search.md
+++ b/docs/en/reference/default-theme-search.md
@@ -124,9 +124,9 @@ export default defineConfig({
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
- * @param {import('markdown-it')} md
+ * @param {import('markdown-it-async')} md
*/
- _render(src, env, md) {
+ async _render(src, env, md) {
// return html string
}
}
@@ -149,8 +149,8 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('some/path')) return ''
return html
@@ -162,7 +162,7 @@ export default defineConfig({
```
::: warning Note
-In case a custom `_render` function is provided, you need to handle the `search: false` frontmatter yourself. Also, the `env` object won't be completely populated before `md.render` is called, so any checks on optional `env` properties like `frontmatter` should be done after that.
+In case a custom `_render` function is provided, you need to handle the `search: false` frontmatter yourself. Also, the `env` object won't be completely populated before `md.renderAsync` is called, so any checks on optional `env` properties like `frontmatter` should be done after that.
:::
#### Example: Transforming content - adding anchors
@@ -175,10 +175,10 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.title)
- return md.render(`# ${env.frontmatter.title}`) + html
+ return await md.renderAsync(`# ${env.frontmatter.title}`) + html
return html
}
}
@@ -381,10 +381,3 @@ new Crawler({
}
})
```
-
-
diff --git a/docs/es/index.md b/docs/es/index.md
index bf9701e5..6ced6057 100644
--- a/docs/es/index.md
+++ b/docs/es/index.md
@@ -36,25 +36,3 @@ features:
title: Entrega rápida de sitios
details: Carga inicial rápida con HTML estático, navegación rápida con enrutamiento del lado del cliente.
---
-
-
diff --git a/docs/es/reference/default-theme-search.md b/docs/es/reference/default-theme-search.md
index 5a654705..3059b0ba 100644
--- a/docs/es/reference/default-theme-search.md
+++ b/docs/es/reference/default-theme-search.md
@@ -113,9 +113,9 @@ export default defineConfig({
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
- * @param {import('markdown-it')} md
+ * @param {import('markdown-it-async')} md
*/
- _render(src, env, md) {
+ async _render(src, env, md) {
// retorne un string HTML
}
}
@@ -138,8 +138,8 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('algum/caminho')) return ''
return html
@@ -151,7 +151,7 @@ export default defineConfig({
```
::: warning Nota
-En este caso, una función `_render` se proporciona, es necesario manipular el `search: false` desde el frente por su cuenta. Además, el objeto `env` no estará completamente poblado antes que `md.render` se llama, luego verifica las propiedades opcionales `env`, como `frontmatter`, debe hacerse después de eso.
+En este caso, una función `_render` se proporciona, es necesario manipular el `search: false` desde el frente por su cuenta. Además, el objeto `env` no estará completamente poblado antes que `md.renderAsync` se llama, luego verifica las propiedades opcionales `env`, como `frontmatter`, debe hacerse después de eso.
:::
#### Ejemplo: Transformar contenido - agregar anclajes {#example-transforming-content-adding-anchors}
@@ -164,10 +164,10 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.title)
- return md.render(`# ${env.frontmatter.title}`) + html
+ return await md.renderAsync(`# ${env.frontmatter.title}`) + html
return html
}
}
@@ -370,10 +370,3 @@ new Crawler({
}
})
```
-
-
diff --git a/docs/fa/index.md b/docs/fa/index.md
index 3b0fabd7..1637397f 100644
--- a/docs/fa/index.md
+++ b/docs/fa/index.md
@@ -36,30 +36,3 @@ features:
title: ارسال سایت های سریع
details: بارگذاری اولیه سریع با HTML ایستا، ناوبری سریع پس از بارگیری با مسیریابی سمت کلاینت
---
-
-
diff --git a/docs/fa/reference/default-theme-search.md b/docs/fa/reference/default-theme-search.md
index dd325c9f..2694a291 100644
--- a/docs/fa/reference/default-theme-search.md
+++ b/docs/fa/reference/default-theme-search.md
@@ -120,9 +120,9 @@ export default defineConfig({
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
- * @param {import('markdown-it')} md
+ * @param {import('markdown-it-async')} md
*/
- _render(src, env, md) {
+ async _render(src, env, md) {
// بازگشت رشته HTML
}
}
@@ -145,8 +145,8 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('some/path')) return ''
return html
@@ -158,7 +158,7 @@ export default defineConfig({
```
::: warning توجه
-در صورت ارائه تابع `_render` سفارشی، باید خودتان بررسی کنید که آیا frontmatter `search: false` را مدیریت میکند یا خیر. همچنین، شی env قبل از فراخوانی `md.render` کاملاً پر نمیشود، بنابراین هر بررسیای روی ویژگیهای اختیاری env مانند `frontmatter` باید بعد از آن انجام شود.
+در صورت ارائه تابع `_render` سفارشی، باید خودتان بررسی کنید که آیا frontmatter `search: false` را مدیریت میکند یا خیر. همچنین، شی env قبل از فراخوانی `md.renderAsync` کاملاً پر نمیشود، بنابراین هر بررسیای روی ویژگیهای اختیاری env مانند `frontmatter` باید بعد از آن انجام شود.
:::
#### مثال: تبدیل محتوا - افزودن لینکهای صفحه {#example-transforming-content-adding-anchors}
@@ -171,10 +171,10 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.title)
- return md.render(`# ${env.frontmatter.title}`) + html
+ return await md.renderAsync(`# ${env.frontmatter.title}`) + html
return html
}
}
@@ -377,10 +377,3 @@ new Crawler({
}
})
```
-
-
\ No newline at end of file
diff --git a/docs/ko/index.md b/docs/ko/index.md
index 50e56e4c..6a16ff49 100644
--- a/docs/ko/index.md
+++ b/docs/ko/index.md
@@ -36,25 +36,3 @@ features:
title: 웹사이트를 빠르게 제공
details: 정적 HTML로 빠른 초기 로딩, 클라이언트 측 라우팅을 통한 빠른 탐색.
---
-
-
diff --git a/docs/ko/reference/default-theme-search.md b/docs/ko/reference/default-theme-search.md
index da1feb42..69b633aa 100644
--- a/docs/ko/reference/default-theme-search.md
+++ b/docs/ko/reference/default-theme-search.md
@@ -120,9 +120,9 @@ export default defineConfig({
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
- * @param {import('markdown-it')} md
+ * @param {import('markdown-it-async')} md
*/
- _render(src, env, md) {
+ async _render(src, env, md) {
// return html string
}
}
@@ -145,8 +145,8 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('some/path')) return ''
return html
@@ -158,7 +158,7 @@ export default defineConfig({
```
::: warning 참고
-커스텀 `_render` 함수가 제공된 경우, `search: false` 전문을 직접 처리해야 합니다. 또한, `md.render`가 호출되기 전에 `env` 객체가 완전히 채워지지 않으므로, `frontmatter`와 같은 선택적 `env` 프로퍼티에 대한 검사는 그 이후에 수행해야 합니다.
+커스텀 `_render` 함수가 제공된 경우, `search: false` 전문을 직접 처리해야 합니다. 또한, `md.renderAsync`가 호출되기 전에 `env` 객체가 완전히 채워지지 않으므로, `frontmatter`와 같은 선택적 `env` 프로퍼티에 대한 검사는 그 이후에 수행해야 합니다.
:::
#### 예제: 콘텐츠 변환 - 앵커 추가 {#example-transforming-content-adding-anchors}
@@ -171,10 +171,10 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.title)
- return md.render(`# ${env.frontmatter.title}`) + html
+ return await md.renderAsync(`# ${env.frontmatter.title}`) + html
return html
}
}
@@ -377,10 +377,3 @@ new Crawler({
}
})
```
-
-
diff --git a/docs/pt/index.md b/docs/pt/index.md
index 3f979dca..fccf03a0 100644
--- a/docs/pt/index.md
+++ b/docs/pt/index.md
@@ -36,25 +36,3 @@ features:
title: Entregue Sites Rápidos
details: Carregamento inicial rápido com HTML estático, navegação rápida com roteamento no lado do cliente.
---
-
-
diff --git a/docs/pt/reference/default-theme-search.md b/docs/pt/reference/default-theme-search.md
index e7347afa..c16406cb 100644
--- a/docs/pt/reference/default-theme-search.md
+++ b/docs/pt/reference/default-theme-search.md
@@ -113,9 +113,9 @@ export default defineConfig({
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
- * @param {import('markdown-it')} md
+ * @param {import('markdown-it-async')} md
*/
- _render(src, env, md) {
+ async _render(src, env, md) {
// retorne a string HTML
}
}
@@ -138,8 +138,8 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('algum/caminho')) return ''
return html
@@ -151,7 +151,7 @@ export default defineConfig({
```
::: warning Nota
-No caso uma função `_render` personalizada ser fornecida, você precisa manipular o `search: false` do frontmatter por conta própria. Além disso, o objeto `env` não estará completamente populado antes que `md.render` seja chamado, então verificações em propriedades opcionais `env`, como `frontmatter`, devem ser feitas após isso.
+No caso uma função `_render` personalizada ser fornecida, você precisa manipular o `search: false` do frontmatter por conta própria. Além disso, o objeto `env` não estará completamente populado antes que `md.renderAsync` seja chamado, então verificações em propriedades opcionais `env`, como `frontmatter`, devem ser feitas após isso.
:::
#### Exemplo: Transformando conteúdo - adicionando âncoras {#example-transforming-content-adding-anchors}
@@ -164,10 +164,10 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.title)
- return md.render(`# ${env.frontmatter.title}`) + html
+ return await md.renderAsync(`# ${env.frontmatter.title}`) + html
return html
}
}
@@ -370,10 +370,3 @@ new Crawler({
}
})
```
-
-
diff --git a/docs/ru/index.md b/docs/ru/index.md
index 5d2e52e5..ecddc946 100644
--- a/docs/ru/index.md
+++ b/docs/ru/index.md
@@ -36,25 +36,3 @@ features:
title: Быстрый запуск веб-сайтов
details: Быстрая начальная загрузка с помощью статического HTML, быстрая навигация после загрузки с помощью маршрутизации на стороне клиента.
---
-
-
diff --git a/docs/ru/reference/default-theme-search.md b/docs/ru/reference/default-theme-search.md
index c91e4be4..bab3fa9e 100644
--- a/docs/ru/reference/default-theme-search.md
+++ b/docs/ru/reference/default-theme-search.md
@@ -124,9 +124,9 @@ export default defineConfig({
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
- * @param {import('markdown-it')} md
+ * @param {import('markdown-it-async')} md
*/
- _render(src, env, md) {
+ async _render(src, env, md) {
// возвращаем html
}
}
@@ -149,8 +149,8 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('some/path')) return ''
return html
@@ -162,7 +162,7 @@ export default defineConfig({
```
::: warning ПРИМЕЧАНИЕ
-В случае, если предоставляется пользовательская функция `_render`, вам нужно самостоятельно обработать заголовок `search: false`. Кроме того, объект `env` не будет полностью заполнен до вызова `md.render`, поэтому любые проверки необязательных свойств `env`, таких как `frontmatter`, должны быть выполнены после этого.
+В случае, если предоставляется пользовательская функция `_render`, вам нужно самостоятельно обработать заголовок `search: false`. Кроме того, объект `env` не будет полностью заполнен до вызова `md.renderAsync`, поэтому любые проверки необязательных свойств `env`, таких как `frontmatter`, должны быть выполнены после этого.
:::
#### Пример: Преобразование содержимого - добавление якорей {#example-transforming-content-adding-anchors}
@@ -175,10 +175,10 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.title)
- return md.render(`# ${env.frontmatter.title}`) + html
+ return await md.renderAsync(`# ${env.frontmatter.title}`) + html
return html
}
}
@@ -384,10 +384,3 @@ new Crawler({
}
})
```
-
-
diff --git a/docs/zh/index.md b/docs/zh/index.md
index 23299c1f..81f71c16 100644
--- a/docs/zh/index.md
+++ b/docs/zh/index.md
@@ -36,24 +36,3 @@ features:
title: 速度真的很快!
details: 采用静态 HTML 实现快速的页面初次加载,使用客户端路由实现快速的页面切换导航。
---
-
diff --git a/docs/zh/reference/default-theme-search.md b/docs/zh/reference/default-theme-search.md
index e19f052a..31af2c9d 100644
--- a/docs/zh/reference/default-theme-search.md
+++ b/docs/zh/reference/default-theme-search.md
@@ -113,9 +113,9 @@ export default defineConfig({
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
- * @param {import('markdown-it')} md
+ * @param {import('markdown-it-async')} md
*/
- _render(src, env, md) {
+ async _render(src, env, md) {
// 返回 html 字符串
}
}
@@ -138,8 +138,8 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('some/path')) return ''
return html
@@ -151,7 +151,7 @@ export default defineConfig({
```
::: warning 注意
-如果提供了自定义的 `_render` 函数,你需要自己处理 `search: false` 的 frontmatter。此外,在调用 `md.render` 之前,`env` 对象不会完全填充,因此对可选 `env` 属性 (如 `frontmatter`) 的任何检查都应该在此之后完成。
+如果提供了自定义的 `_render` 函数,你需要自己处理 `search: false` 的 frontmatter。此外,在调用 `md.renderAsync` 之前,`env` 对象不会完全填充,因此对可选 `env` 属性 (如 `frontmatter`) 的任何检查都应该在此之后完成。
:::
#### 示例:转换内容——添加锚点 {#example-transforming-content-adding-anchors}
@@ -164,10 +164,10 @@ export default defineConfig({
search: {
provider: 'local',
options: {
- _render(src, env, md) {
- const html = md.render(src, env)
+ async _render(src, env, md) {
+ const html = await md.renderAsync(src, env)
if (env.frontmatter?.title)
- return md.render(`# ${env.frontmatter.title}`) + html
+ return await md.renderAsync(`# ${env.frontmatter.title}`) + html
return html
}
}
@@ -370,10 +370,3 @@ new Crawler({
}
})
```
-
-
diff --git a/package.json b/package.json
index 167ffb98..d43c1684 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "vitepress",
- "version": "2.0.0-alpha.1",
+ "version": "2.0.0-alpha.2",
"description": "Vite & Vue powered static site generator",
"keywords": [
"vite",
@@ -101,12 +101,11 @@
"@shikijs/core": "^2.1.0",
"@shikijs/transformers": "^2.1.0",
"@shikijs/types": "^2.1.0",
- "@types/markdown-it": "^14.1.2",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/devtools-api": "^7.7.0",
"@vue/shared": "^3.5.13",
- "@vueuse/core": "^12.4.0",
- "@vueuse/integrations": "^12.4.0",
+ "@vueuse/core": "^12.5.0",
+ "@vueuse/integrations": "^12.5.0",
"focus-trap": "^7.6.4",
"mark.js": "8.11.1",
"minisearch": "^7.1.1",
@@ -135,11 +134,12 @@
"@types/fs-extra": "^11.0.4",
"@types/lodash.template": "^4.5.3",
"@types/mark.js": "^8.11.12",
+ "@types/markdown-it": "^14.1.2",
"@types/markdown-it-attrs": "^4.1.3",
"@types/markdown-it-container": "^2.0.10",
"@types/markdown-it-emoji": "^3.0.1",
"@types/minimist": "^1.2.5",
- "@types/node": "^22.10.7",
+ "@types/node": "^22.10.9",
"@types/picomatch": "^3.0.2",
"@types/postcss-prefix-selector": "^1.16.3",
"@types/prompts": "^2.4.9",
@@ -152,11 +152,12 @@
"fs-extra": "^11.3.0",
"get-port": "^7.1.0",
"gray-matter": "^4.0.3",
- "lint-staged": "^15.4.1",
+ "lint-staged": "^15.4.2",
"lodash.template": "^4.5.0",
"lru-cache": "^11.0.2",
"markdown-it": "^14.1.0",
"markdown-it-anchor": "^9.2.0",
+ "markdown-it-async": "^2.0.0",
"markdown-it-attrs": "^4.3.1",
"markdown-it-container": "^4.0.0",
"markdown-it-emoji": "^3.0.0",
@@ -169,7 +170,7 @@
"picocolors": "^1.1.1",
"picomatch": "^4.0.2",
"pkg-dir": "^8.0.0",
- "playwright-chromium": "^1.49.1",
+ "playwright-chromium": "^1.50.0",
"polka": "^1.0.0-next.28",
"postcss-prefix-selector": "^2.1.0",
"prettier": "^3.4.2",
@@ -183,10 +184,9 @@
"simple-git-hooks": "^2.11.1",
"sirv": "^3.0.0",
"sitemap": "^8.0.0",
- "synckit": "^0.9.2",
"tinyglobby": "^0.2.10",
"typescript": "^5.7.3",
- "vitest": "^3.0.3",
+ "vitest": "^3.0.4",
"vue-tsc": "^2.2.0",
"wait-on": "^8.0.2"
},
@@ -215,7 +215,8 @@
"ora>string-width": "^5"
},
"patchedDependencies": {
- "@types/mdurl@2.0.0": "patches/@types__mdurl@2.0.0.patch"
+ "@types/mdurl@2.0.0": "patches/@types__mdurl@2.0.0.patch",
+ "markdown-it-anchor@9.2.0": "patches/markdown-it-anchor@9.2.0.patch"
}
}
}
diff --git a/patches/markdown-it-anchor@9.2.0.patch b/patches/markdown-it-anchor@9.2.0.patch
new file mode 100644
index 00000000..ac4498e4
--- /dev/null
+++ b/patches/markdown-it-anchor@9.2.0.patch
@@ -0,0 +1,17 @@
+diff --git a/types/index.d.ts b/types/index.d.ts
+index 40c25c0be1add8b0fc2c51489c25a423dbc49d2c..807bc1b0e434d660c6a298b1dee1c87935bfac86 100644
+--- a/types/index.d.ts
++++ b/types/index.d.ts
+@@ -1,10 +1,8 @@
+ import MarkdownIt from 'markdown-it';
+-import { default as MarkdownItToken } from 'markdown-it/lib/token.mjs';
+-import { default as MarkdownItState} from 'markdown-it/lib/rules_core/state_core.mjs';
++import { default as Token } from 'markdown-it/lib/token.mjs';
++import { default as State } from 'markdown-it/lib/rules_core/state_core.mjs';
+
+ declare namespace anchor {
+- export type Token = MarkdownItToken
+- export type State = MarkdownItState
+ export type RenderHref = (slug: string, state: State) => string;
+ export type RenderAttrs = (slug: string, state: State) => Record;
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 33fc3990..d4bdaf17 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ patchedDependencies:
'@types/mdurl@2.0.0':
hash: ztuyknm7z4pyl4jot5hljjv5bm
path: patches/@types__mdurl@2.0.0.patch
+ markdown-it-anchor@9.2.0:
+ hash: ivrlfano2jj27ilcyyknwlzzfu
+ path: patches/markdown-it-anchor@9.2.0.patch
importers:
@@ -21,7 +24,7 @@ importers:
version: 3.8.3
'@docsearch/js':
specifier: ^3.8.3
- version: 3.8.3(@algolia/client-search@5.19.0)
+ version: 3.8.3(@algolia/client-search@5.20.0)
'@iconify-json/simple-icons':
specifier: ^1.2.21
version: 1.2.21
@@ -34,12 +37,9 @@ importers:
'@shikijs/types':
specifier: ^2.1.0
version: 2.1.0
- '@types/markdown-it':
- specifier: ^14.1.2
- version: 14.1.2
'@vitejs/plugin-vue':
specifier: ^5.2.1
- version: 5.2.1(vite@6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
+ version: 5.2.1(vite@6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
'@vue/devtools-api':
specifier: ^7.7.0
version: 7.7.0
@@ -47,11 +47,11 @@ importers:
specifier: ^3.5.13
version: 3.5.13
'@vueuse/core':
- specifier: ^12.4.0
- version: 12.4.0(typescript@5.7.3)
+ specifier: ^12.5.0
+ version: 12.5.0(typescript@5.7.3)
'@vueuse/integrations':
- specifier: ^12.4.0
- version: 12.4.0(axios@1.7.9(debug@4.4.0))(focus-trap@7.6.4)(typescript@5.7.3)
+ specifier: ^12.5.0
+ version: 12.5.0(axios@1.7.9(debug@4.4.0))(focus-trap@7.6.4)(typescript@5.7.3)
focus-trap:
specifier: ^7.6.4
version: 7.6.4
@@ -66,7 +66,7 @@ importers:
version: 2.1.0
vite:
specifier: ^6.0.11
- version: 6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1)
+ version: 6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0)
vue:
specifier: ^3.5.13
version: 3.5.13(typescript@5.7.3)
@@ -131,6 +131,9 @@ importers:
'@types/mark.js':
specifier: ^8.11.12
version: 8.11.12
+ '@types/markdown-it':
+ specifier: ^14.1.2
+ version: 14.1.2
'@types/markdown-it-attrs':
specifier: ^4.1.3
version: 4.1.3
@@ -144,8 +147,8 @@ importers:
specifier: ^1.2.5
version: 1.2.5
'@types/node':
- specifier: ^22.10.7
- version: 22.10.7
+ specifier: ^22.10.9
+ version: 22.10.9
'@types/picomatch':
specifier: ^3.0.2
version: 3.0.2
@@ -183,8 +186,8 @@ importers:
specifier: ^4.0.3
version: 4.0.3
lint-staged:
- specifier: ^15.4.1
- version: 15.4.1
+ specifier: ^15.4.2
+ version: 15.4.2
lodash.template:
specifier: ^4.5.0
version: 4.5.0
@@ -196,7 +199,10 @@ importers:
version: 14.1.0
markdown-it-anchor:
specifier: ^9.2.0
- version: 9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.0)
+ version: 9.2.0(patch_hash=ivrlfano2jj27ilcyyknwlzzfu)(@types/markdown-it@14.1.2)(markdown-it@14.1.0)
+ markdown-it-async:
+ specifier: ^2.0.0
+ version: 2.0.0
markdown-it-attrs:
specifier: ^4.3.1
version: 4.3.1(markdown-it@14.1.0)
@@ -234,8 +240,8 @@ importers:
specifier: ^8.0.0
version: 8.0.0
playwright-chromium:
- specifier: ^1.49.1
- version: 1.49.1
+ specifier: ^1.50.0
+ version: 1.50.0
polka:
specifier: ^1.0.0-next.28
version: 1.0.0-next.28
@@ -275,9 +281,6 @@ importers:
sitemap:
specifier: ^8.0.0
version: 8.0.0
- synckit:
- specifier: ^0.9.2
- version: 0.9.2
tinyglobby:
specifier: ^0.2.10
version: 0.2.10
@@ -285,8 +288,8 @@ importers:
specifier: ^5.7.3
version: 5.7.3
vitest:
- specifier: ^3.0.3
- version: 3.0.3(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1)
+ specifier: ^3.0.4
+ version: 3.0.4(@types/debug@4.1.12)(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0)
vue-tsc:
specifier: ^2.2.0
version: 2.2.0(typescript@5.7.3)
@@ -349,56 +352,56 @@ packages:
'@algolia/client-search': '>= 4.9.1 < 6'
algoliasearch: '>= 4.9.1 < 6'
- '@algolia/client-abtesting@5.19.0':
- resolution: {integrity: sha512-dMHwy2+nBL0SnIsC1iHvkBao64h4z+roGelOz11cxrDBrAdASxLxmfVMop8gmodQ2yZSacX0Rzevtxa+9SqxCw==}
+ '@algolia/client-abtesting@5.20.0':
+ resolution: {integrity: sha512-YaEoNc1Xf2Yk6oCfXXkZ4+dIPLulCx8Ivqj0OsdkHWnsI3aOJChY5qsfyHhDBNSOhqn2ilgHWxSfyZrjxBcAww==}
engines: {node: '>= 14.0.0'}
- '@algolia/client-analytics@5.19.0':
- resolution: {integrity: sha512-CDW4RwnCHzU10upPJqS6N6YwDpDHno7w6/qXT9KPbPbt8szIIzCHrva4O9KIfx1OhdsHzfGSI5hMAiOOYl4DEQ==}
+ '@algolia/client-analytics@5.20.0':
+ resolution: {integrity: sha512-CIT9ni0+5sYwqehw+t5cesjho3ugKQjPVy/iPiJvtJX4g8Cdb6je6SPt2uX72cf2ISiXCAX9U3cY0nN0efnRDw==}
engines: {node: '>= 14.0.0'}
- '@algolia/client-common@5.19.0':
- resolution: {integrity: sha512-2ERRbICHXvtj5kfFpY5r8qu9pJII/NAHsdgUXnUitQFwPdPL7wXiupcvZJC7DSntOnE8AE0lM7oDsPhrJfj5nQ==}
+ '@algolia/client-common@5.20.0':
+ resolution: {integrity: sha512-iSTFT3IU8KNpbAHcBUJw2HUrPnMXeXLyGajmCL7gIzWOsYM4GabZDHXOFx93WGiXMti1dymz8k8R+bfHv1YZmA==}
engines: {node: '>= 14.0.0'}
- '@algolia/client-insights@5.19.0':
- resolution: {integrity: sha512-xPOiGjo6I9mfjdJO7Y+p035aWePcbsItizIp+qVyfkfZiGgD+TbNxM12g7QhFAHIkx/mlYaocxPY/TmwPzTe+A==}
+ '@algolia/client-insights@5.20.0':
+ resolution: {integrity: sha512-w9RIojD45z1csvW1vZmAko82fqE/Dm+Ovsy2ElTsjFDB0HMAiLh2FO86hMHbEXDPz6GhHKgGNmBRiRP8dDPgJg==}
engines: {node: '>= 14.0.0'}
- '@algolia/client-personalization@5.19.0':
- resolution: {integrity: sha512-B9eoce/fk8NLboGje+pMr72pw+PV7c5Z01On477heTZ7jkxoZ4X92dobeGuEQop61cJ93Gaevd1of4mBr4hu2A==}
+ '@algolia/client-personalization@5.20.0':
+ resolution: {integrity: sha512-p/hftHhrbiHaEcxubYOzqVV4gUqYWLpTwK+nl2xN3eTrSW9SNuFlAvUBFqPXSVBqc6J5XL9dNKn3y8OA1KElSQ==}
engines: {node: '>= 14.0.0'}
- '@algolia/client-query-suggestions@5.19.0':
- resolution: {integrity: sha512-6fcP8d4S8XRDtVogrDvmSM6g5g6DndLc0pEm1GCKe9/ZkAzCmM3ZmW1wFYYPxdjMeifWy1vVEDMJK7sbE4W7MA==}
+ '@algolia/client-query-suggestions@5.20.0':
+ resolution: {integrity: sha512-m4aAuis5vZi7P4gTfiEs6YPrk/9hNTESj3gEmGFgfJw3hO2ubdS4jSId1URd6dGdt0ax2QuapXufcrN58hPUcw==}
engines: {node: '>= 14.0.0'}
- '@algolia/client-search@5.19.0':
- resolution: {integrity: sha512-Ctg3xXD/1VtcwmkulR5+cKGOMj4r0wC49Y/KZdGQcqpydKn+e86F6l3tb3utLJQVq4lpEJud6kdRykFgcNsp8Q==}
+ '@algolia/client-search@5.20.0':
+ resolution: {integrity: sha512-KL1zWTzrlN4MSiaK1ea560iCA/UewMbS4ZsLQRPoDTWyrbDKVbztkPwwv764LAqgXk0fvkNZvJ3IelcK7DqhjQ==}
engines: {node: '>= 14.0.0'}
- '@algolia/ingestion@1.19.0':
- resolution: {integrity: sha512-LO7w1MDV+ZLESwfPmXkp+KLeYeFrYEgtbCZG6buWjddhYraPQ9MuQWLhLLiaMlKxZ/sZvFTcZYuyI6Jx4WBhcg==}
+ '@algolia/ingestion@1.20.0':
+ resolution: {integrity: sha512-shj2lTdzl9un4XJblrgqg54DoK6JeKFO8K8qInMu4XhE2JuB8De6PUuXAQwiRigZupbI0xq8aM0LKdc9+qiLQA==}
engines: {node: '>= 14.0.0'}
- '@algolia/monitoring@1.19.0':
- resolution: {integrity: sha512-Mg4uoS0aIKeTpu6iv6O0Hj81s8UHagi5TLm9k2mLIib4vmMtX7WgIAHAcFIaqIZp5D6s5EVy1BaDOoZ7buuJHA==}
+ '@algolia/monitoring@1.20.0':
+ resolution: {integrity: sha512-aF9blPwOhKtWvkjyyXh9P5peqmhCA1XxLBRgItT+K6pbT0q4hBDQrCid+pQZJYy4HFUKjB/NDDwyzFhj/rwKhw==}
engines: {node: '>= 14.0.0'}
- '@algolia/recommend@5.19.0':
- resolution: {integrity: sha512-PbgrMTbUPlmwfJsxjFhal4XqZO2kpBNRjemLVTkUiti4w/+kzcYO4Hg5zaBgVqPwvFDNQ8JS4SS3TBBem88u+g==}
+ '@algolia/recommend@5.20.0':
+ resolution: {integrity: sha512-T6B/WPdZR3b89/F9Vvk6QCbt/wrLAtrGoL8z4qPXDFApQ8MuTFWbleN/4rHn6APWO3ps+BUePIEbue2rY5MlRw==}
engines: {node: '>= 14.0.0'}
- '@algolia/requester-browser-xhr@5.19.0':
- resolution: {integrity: sha512-GfnhnQBT23mW/VMNs7m1qyEyZzhZz093aY2x8p0era96MMyNv8+FxGek5pjVX0b57tmSCZPf4EqNCpkGcGsmbw==}
+ '@algolia/requester-browser-xhr@5.20.0':
+ resolution: {integrity: sha512-t6//lXsq8E85JMenHrI6mhViipUT5riNhEfCcvtRsTV+KIBpC6Od18eK864dmBhoc5MubM0f+sGpKOqJIlBSCg==}
engines: {node: '>= 14.0.0'}
- '@algolia/requester-fetch@5.19.0':
- resolution: {integrity: sha512-oyTt8ZJ4T4fYvW5avAnuEc6Laedcme9fAFryMD9ndUTIUe/P0kn3BuGcCLFjN3FDmdrETHSFkgPPf1hGy3sLCw==}
+ '@algolia/requester-fetch@5.20.0':
+ resolution: {integrity: sha512-FHxYGqRY+6bgjKsK4aUsTAg6xMs2S21elPe4Y50GB0Y041ihvw41Vlwy2QS6K9ldoftX4JvXodbKTcmuQxywdQ==}
engines: {node: '>= 14.0.0'}
- '@algolia/requester-node-http@5.19.0':
- resolution: {integrity: sha512-p6t8ue0XZNjcRiqNkb5QAM0qQRAKsCiebZ6n9JjWA+p8fWf8BvnhO55y2fO28g3GW0Imj7PrAuyBuxq8aDVQwQ==}
+ '@algolia/requester-node-http@5.20.0':
+ resolution: {integrity: sha512-kmtQClq/w3vtPteDSPvaW9SPZL/xrIgMrxZyAgsFwrJk0vJxqyC5/hwHmrCraDnStnGSADnLpBf4SpZnwnkwWw==}
engines: {node: '>= 14.0.0'}
'@antfu/install-pkg@0.4.1':
@@ -701,10 +704,6 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
- '@pkgr/core@0.1.1':
- resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
- engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
-
'@polka/compression@1.0.0-next.28':
resolution: {integrity: sha512-aDmrBhgHJtxE+jy145WfhW9WmTAFmES/dNnn1LAs8UnnkFgBUj4T8I4ScQ9+rOkpDZStvnVP5iqhN3tvt7O1NA==}
engines: {node: '>=6'}
@@ -964,8 +963,8 @@ packages:
'@types/node@17.0.45':
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
- '@types/node@22.10.7':
- resolution: {integrity: sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==}
+ '@types/node@22.10.9':
+ resolution: {integrity: sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==}
'@types/normalize-package-data@2.4.4':
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
@@ -997,8 +996,8 @@ packages:
'@types/web-bluetooth@0.0.20':
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
- '@ungap/structured-clone@1.2.1':
- resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==}
+ '@ungap/structured-clone@1.3.0':
+ resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
'@vitejs/plugin-vue@5.2.1':
resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
@@ -1007,11 +1006,11 @@ packages:
vite: ^5.0.0 || ^6.0.0
vue: ^3.2.25
- '@vitest/expect@3.0.3':
- resolution: {integrity: sha512-SbRCHU4qr91xguu+dH3RUdI5dC86zm8aZWydbp961aIR7G8OYNN6ZiayFuf9WAngRbFOfdrLHCGgXTj3GtoMRQ==}
+ '@vitest/expect@3.0.4':
+ resolution: {integrity: sha512-Nm5kJmYw6P2BxhJPkO3eKKhGYKRsnqJqf+r0yOGRKpEP+bSCBDsjXgiu1/5QFrnPMEgzfC38ZEjvCFgaNBC0Eg==}
- '@vitest/mocker@3.0.3':
- resolution: {integrity: sha512-XT2XBc4AN9UdaxJAeIlcSZ0ILi/GzmG5G8XSly4gaiqIvPV3HMTSIDZWJVX6QRJ0PX1m+W8Cy0K9ByXNb/bPIA==}
+ '@vitest/mocker@3.0.4':
+ resolution: {integrity: sha512-gEef35vKafJlfQbnyOXZ0Gcr9IBUsMTyTLXsEQwuyYAerpHqvXhzdBnDFuHLpFqth3F7b6BaFr4qV/Cs1ULx5A==}
peerDependencies:
msw: ^2.4.9
vite: ^5.0.0 || ^6.0.0
@@ -1021,20 +1020,20 @@ packages:
vite:
optional: true
- '@vitest/pretty-format@3.0.3':
- resolution: {integrity: sha512-gCrM9F7STYdsDoNjGgYXKPq4SkSxwwIU5nkaQvdUxiQ0EcNlez+PdKOVIsUJvh9P9IeIFmjn4IIREWblOBpP2Q==}
+ '@vitest/pretty-format@3.0.4':
+ resolution: {integrity: sha512-ts0fba+dEhK2aC9PFuZ9LTpULHpY/nd6jhAQ5IMU7Gaj7crPCTdCFfgvXxruRBLFS+MLraicCuFXxISEq8C93g==}
- '@vitest/runner@3.0.3':
- resolution: {integrity: sha512-Rgi2kOAk5ZxWZlwPguRJFOBmWs6uvvyAAR9k3MvjRvYrG7xYvKChZcmnnpJCS98311CBDMqsW9MzzRFsj2gX3g==}
+ '@vitest/runner@3.0.4':
+ resolution: {integrity: sha512-dKHzTQ7n9sExAcWH/0sh1elVgwc7OJ2lMOBrAm73J7AH6Pf9T12Zh3lNE1TETZaqrWFXtLlx3NVrLRb5hCK+iw==}
- '@vitest/snapshot@3.0.3':
- resolution: {integrity: sha512-kNRcHlI4txBGztuJfPEJ68VezlPAXLRT1u5UCx219TU3kOG2DplNxhWLwDf2h6emwmTPogzLnGVwP6epDaJN6Q==}
+ '@vitest/snapshot@3.0.4':
+ resolution: {integrity: sha512-+p5knMLwIk7lTQkM3NonZ9zBewzVp9EVkVpvNta0/PlFWpiqLaRcF4+33L1it3uRUCh0BGLOaXPPGEjNKfWb4w==}
- '@vitest/spy@3.0.3':
- resolution: {integrity: sha512-7/dgux8ZBbF7lEIKNnEqQlyRaER9nkAL9eTmdKJkDO3hS8p59ATGwKOCUDHcBLKr7h/oi/6hP+7djQk8049T2A==}
+ '@vitest/spy@3.0.4':
+ resolution: {integrity: sha512-sXIMF0oauYyUy2hN49VFTYodzEAu744MmGcPR3ZBsPM20G+1/cSW/n1U+3Yu/zHxX2bIDe1oJASOkml+osTU6Q==}
- '@vitest/utils@3.0.3':
- resolution: {integrity: sha512-f+s8CvyzPtMFY1eZKkIHGhPsQgYo5qCm6O8KZoim9qm1/jT64qBgGpO5tHscNH6BzRHM+edLNOP+3vO8+8pE/A==}
+ '@vitest/utils@3.0.4':
+ resolution: {integrity: sha512-8BqC1ksYsHtbWH+DfpOAKrFw3jl3Uf9J7yeFh85Pz52IWuh1hBBtyfEbRNNZNjl8H8A5yMLH9/t+k7HIKzQcZQ==}
'@volar/language-core@2.4.11':
resolution: {integrity: sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==}
@@ -1094,11 +1093,11 @@ packages:
'@vue/shared@3.5.13':
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
- '@vueuse/core@12.4.0':
- resolution: {integrity: sha512-XnjQYcJwCsyXyIafyA6SvyN/OBtfPnjvJmbxNxQjCcyWD198urwm5TYvIUUyAxEAN0K7HJggOgT15cOlWFyLeA==}
+ '@vueuse/core@12.5.0':
+ resolution: {integrity: sha512-GVyH1iYqNANwcahAx8JBm6awaNgvR/SwZ1fjr10b8l1HIgDp82ngNbfzJUgOgWEoxjL+URAggnlilAEXwCOZtg==}
- '@vueuse/integrations@12.4.0':
- resolution: {integrity: sha512-EZm+TLoZMeEwDnccnEqB54CvvcVKbVnJubOF380HqdyZAxWfQ8egnFCESdlXWEIbxFgjfhcGfZUvQx5Nqw9Ofw==}
+ '@vueuse/integrations@12.5.0':
+ resolution: {integrity: sha512-HYLt8M6mjUfcoUOzyBcX2RjpfapIwHPBmQJtTmXOQW845Y/Osu9VuTJ5kPvnmWJ6IUa05WpblfOwZ+P0G4iZsQ==}
peerDependencies:
async-validator: ^4
axios: ^1
@@ -1138,11 +1137,11 @@ packages:
universal-cookie:
optional: true
- '@vueuse/metadata@12.4.0':
- resolution: {integrity: sha512-AhPuHs/qtYrKHUlEoNO6zCXufu8OgbR8S/n2oMw1OQuBQJ3+HOLQ+EpvXs+feOlZMa0p8QVvDWNlmcJJY8rW2g==}
+ '@vueuse/metadata@12.5.0':
+ resolution: {integrity: sha512-Ui7Lo2a7AxrMAXRF+fAp9QsXuwTeeZ8fIB9wsLHqzq9MQk+2gMYE2IGJW48VMJ8ecvCB3z3GsGLKLbSasQ5Qlg==}
- '@vueuse/shared@12.4.0':
- resolution: {integrity: sha512-9yLgbHVIF12OSCojnjTIoZL1+UA10+O4E1aD6Hpfo/DKVm5o3SZIwz6CupqGy3+IcKI8d6Jnl26EQj/YucnW0Q==}
+ '@vueuse/shared@12.5.0':
+ resolution: {integrity: sha512-vMpcL1lStUU6O+kdj6YdHDixh0odjPAUM15uJ9f7MY781jcYkIwFA4iv2EfoIPO6vBmvutI1HxxAwmf0cx5ISQ==}
acorn@8.14.0:
resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
@@ -1152,8 +1151,8 @@ packages:
add-stream@1.0.0:
resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==}
- algoliasearch@5.19.0:
- resolution: {integrity: sha512-zrLtGhC63z3sVLDDKGW+SlCRN9eJHFTgdEmoAOpsVh6wgGL1GgTTDou7tpCBjevzgIvi3AIyDAQO3Xjbg5eqZg==}
+ algoliasearch@5.20.0:
+ resolution: {integrity: sha512-groO71Fvi5SWpxjI9Ia+chy0QBwT61mg6yxJV27f5YFf+Mw+STT75K6SHySpP8Co5LsCrtsbCH5dJZSRtkSKaQ==}
engines: {node: '>= 14.0.0'}
alien-signals@0.4.14:
@@ -1290,8 +1289,8 @@ packages:
comma-separated-tokens@2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
- commander@12.1.0:
- resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
+ commander@13.1.0:
+ resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==}
engines: {node: '>=18'}
commander@6.2.1:
@@ -1840,8 +1839,8 @@ packages:
linkify-it@5.0.0:
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
- lint-staged@15.4.1:
- resolution: {integrity: sha512-P8yJuVRyLrm5KxCtFx+gjI5Bil+wO7wnTl7C3bXhvtTaAFGirzeB24++D0wGoUwxrUKecNiehemgCob9YL39NA==}
+ lint-staged@15.4.2:
+ resolution: {integrity: sha512-gCqzB/Li281uZJgReNci+oXXqUEdrFAQAzTE/LwoxxiEuP41vozNe4BATS+4ehdqkWn+Z6bGc3EDcBja3npBVw==}
engines: {node: '>=18.12.0'}
hasBin: true
@@ -1895,6 +1894,9 @@ packages:
'@types/markdown-it': '*'
markdown-it: '*'
+ markdown-it-async@2.0.0:
+ resolution: {integrity: sha512-jBthmQR5MwXR9Y8Y0teRoZAenaKQMdjuTfpbNARqMBSRPvyzyXCVduHZHakyyhL3ugIacCobXJrO07t277sIjw==}
+
markdown-it-attrs@4.3.1:
resolution: {integrity: sha512-/ko6cba+H6gdZ0DOw7BbNMZtfuJTRp9g/IrGIuz8lYc/EfnmWRpaR3CFPnNbVz0LDvF8Gf1hFGPqrQqq7De0rg==}
engines: {node: '>=6'}
@@ -2164,13 +2166,13 @@ packages:
pkg-types@1.3.1:
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
- playwright-chromium@1.49.1:
- resolution: {integrity: sha512-XAQDkZ1Eem1OONhfS8B2LM2mgHG/i5jIxooxjvqjbF/9GnLnRTJHdQamNjo1e4FZvt7J0BFD/15+qAcT0eKlfA==}
+ playwright-chromium@1.50.0:
+ resolution: {integrity: sha512-gyI1ATjSCn0kCHCV8lGS65h0tRSlJvdlwgvXwY5EyUHW+YLPnOtnMaCiNmHgrcVK8ofsXWq3alaUfnmirNzBlA==}
engines: {node: '>=18'}
hasBin: true
- playwright-core@1.49.1:
- resolution: {integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==}
+ playwright-core@1.50.0:
+ resolution: {integrity: sha512-CXkSSlr4JaZs2tZHI40DsZUN/NIwgaUPsyLuOAaIZp2CyF2sN5MM5NJsyB188lFSSozFxQ5fPT4qM+f0tH/6wQ==}
engines: {node: '>=18'}
hasBin: true
@@ -2482,10 +2484,6 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
- synckit@0.9.2:
- resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==}
- engines: {node: ^14.18.0 || >=16.0.0}
-
tabbable@6.2.0:
resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
@@ -2629,8 +2627,8 @@ packages:
vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
- vite-node@3.0.3:
- resolution: {integrity: sha512-0sQcwhwAEw/UJGojbhOrnq3HtiZ3tC7BzpAa0lx3QaTX0S3YX70iGcik25UBdB96pmdwjyY2uyKNYruxCDmiEg==}
+ vite-node@3.0.4:
+ resolution: {integrity: sha512-7JZKEzcYV2Nx3u6rlvN8qdo3QV7Fxyt6hx+CCKz9fbWxdX5IvUOmTWEAxMrWxaiSf7CKGLJQ5rFu8prb/jBjOA==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
@@ -2677,20 +2675,23 @@ packages:
vitepress-plugin-group-icons@1.3.5:
resolution: {integrity: sha512-1f1NP7osRYlNTR0yS5CAqcaasKHRSAzFKpeCUOfCPwYLAFxhCxsEbRtPBm0U1CfrDVa303MsjX18ngGpFGxIMA==}
- vitest@3.0.3:
- resolution: {integrity: sha512-dWdwTFUW9rcnL0LyF2F+IfvNQWB0w9DERySCk8VMG75F8k25C7LsZoh6XfCjPvcR8Nb+Lqi9JKr6vnzH7HSrpQ==}
+ vitest@3.0.4:
+ resolution: {integrity: sha512-6XG8oTKy2gnJIFTHP6LD7ExFeNLxiTkK3CfMvT7IfR8IN+BYICCf0lXUQmX7i7JoxUP8QmeP4mTnWXgflu4yjw==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
peerDependencies:
'@edge-runtime/vm': '*'
+ '@types/debug': ^4.1.12
'@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
- '@vitest/browser': 3.0.3
- '@vitest/ui': 3.0.3
+ '@vitest/browser': 3.0.4
+ '@vitest/ui': 3.0.4
happy-dom: '*'
jsdom: '*'
peerDependenciesMeta:
'@edge-runtime/vm':
optional: true
+ '@types/debug':
+ optional: true
'@types/node':
optional: true
'@vitest/browser':
@@ -2766,8 +2767,8 @@ packages:
resolution: {integrity: sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==}
engines: {node: '>=0.1'}
- yaml@2.6.1:
- resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==}
+ yaml@2.7.0:
+ resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==}
engines: {node: '>= 14'}
hasBin: true
@@ -2783,109 +2784,109 @@ packages:
snapshots:
- '@algolia/autocomplete-core@1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)':
+ '@algolia/autocomplete-core@1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)':
dependencies:
- '@algolia/autocomplete-plugin-algolia-insights': 1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)
- '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)
+ '@algolia/autocomplete-plugin-algolia-insights': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
transitivePeerDependencies:
- '@algolia/client-search'
- algoliasearch
- search-insights
- '@algolia/autocomplete-plugin-algolia-insights@1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)':
+ '@algolia/autocomplete-plugin-algolia-insights@1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)':
dependencies:
- '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)
+ '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
transitivePeerDependencies:
- '@algolia/client-search'
- algoliasearch
- '@algolia/autocomplete-preset-algolia@1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)':
+ '@algolia/autocomplete-preset-algolia@1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)':
dependencies:
- '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)
- '@algolia/client-search': 5.19.0
- algoliasearch: 5.19.0
+ '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ '@algolia/client-search': 5.20.0
+ algoliasearch: 5.20.0
- '@algolia/autocomplete-shared@1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)':
+ '@algolia/autocomplete-shared@1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)':
dependencies:
- '@algolia/client-search': 5.19.0
- algoliasearch: 5.19.0
+ '@algolia/client-search': 5.20.0
+ algoliasearch: 5.20.0
- '@algolia/client-abtesting@5.19.0':
+ '@algolia/client-abtesting@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/client-analytics@5.19.0':
+ '@algolia/client-analytics@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/client-common@5.19.0': {}
+ '@algolia/client-common@5.20.0': {}
- '@algolia/client-insights@5.19.0':
+ '@algolia/client-insights@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/client-personalization@5.19.0':
+ '@algolia/client-personalization@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/client-query-suggestions@5.19.0':
+ '@algolia/client-query-suggestions@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/client-search@5.19.0':
+ '@algolia/client-search@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/ingestion@1.19.0':
+ '@algolia/ingestion@1.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/monitoring@1.19.0':
+ '@algolia/monitoring@1.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/recommend@5.19.0':
+ '@algolia/recommend@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
- '@algolia/requester-browser-xhr@5.19.0':
+ '@algolia/requester-browser-xhr@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
+ '@algolia/client-common': 5.20.0
- '@algolia/requester-fetch@5.19.0':
+ '@algolia/requester-fetch@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
+ '@algolia/client-common': 5.20.0
- '@algolia/requester-node-http@5.19.0':
+ '@algolia/requester-node-http@5.20.0':
dependencies:
- '@algolia/client-common': 5.19.0
+ '@algolia/client-common': 5.20.0
'@antfu/install-pkg@0.4.1':
dependencies:
@@ -2939,9 +2940,9 @@ snapshots:
'@docsearch/css@3.8.3': {}
- '@docsearch/js@3.8.3(@algolia/client-search@5.19.0)':
+ '@docsearch/js@3.8.3(@algolia/client-search@5.20.0)':
dependencies:
- '@docsearch/react': 3.8.3(@algolia/client-search@5.19.0)
+ '@docsearch/react': 3.8.3(@algolia/client-search@5.20.0)
preact: 10.25.4
transitivePeerDependencies:
- '@algolia/client-search'
@@ -2950,12 +2951,12 @@ snapshots:
- react-dom
- search-insights
- '@docsearch/react@3.8.3(@algolia/client-search@5.19.0)':
+ '@docsearch/react@3.8.3(@algolia/client-search@5.20.0)':
dependencies:
- '@algolia/autocomplete-core': 1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)
- '@algolia/autocomplete-preset-algolia': 1.17.9(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)
+ '@algolia/autocomplete-core': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ '@algolia/autocomplete-preset-algolia': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
'@docsearch/css': 3.8.3
- algoliasearch: 5.19.0
+ algoliasearch: 5.20.0
transitivePeerDependencies:
- '@algolia/client-search'
@@ -3162,8 +3163,6 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.18.0
- '@pkgr/core@0.1.1': {}
-
'@polka/compression@1.0.0-next.28': {}
'@polka/url@1.0.0-next.28': {}
@@ -3328,7 +3327,7 @@ snapshots:
'@types/cross-spawn@6.0.6':
dependencies:
- '@types/node': 22.10.7
+ '@types/node': 22.10.9
'@types/debug@4.1.12':
dependencies:
@@ -3339,7 +3338,7 @@ snapshots:
'@types/fs-extra@11.0.4':
dependencies:
'@types/jsonfile': 6.1.4
- '@types/node': 22.10.7
+ '@types/node': 22.10.9
'@types/hast@3.0.4':
dependencies:
@@ -3351,7 +3350,7 @@ snapshots:
'@types/jsonfile@6.1.4':
dependencies:
- '@types/node': 22.10.7
+ '@types/node': 22.10.9
'@types/linkify-it@5.0.0': {}
@@ -3394,7 +3393,7 @@ snapshots:
'@types/node@17.0.45': {}
- '@types/node@22.10.7':
+ '@types/node@22.10.9':
dependencies:
undici-types: 6.20.0
@@ -3408,14 +3407,14 @@ snapshots:
'@types/prompts@2.4.9':
dependencies:
- '@types/node': 22.10.7
+ '@types/node': 22.10.9
kleur: 3.0.3
'@types/resolve@1.20.2': {}
'@types/sax@1.2.7':
dependencies:
- '@types/node': 22.10.7
+ '@types/node': 22.10.9
'@types/semver@7.5.8': {}
@@ -3425,50 +3424,50 @@ snapshots:
'@types/web-bluetooth@0.0.20': {}
- '@ungap/structured-clone@1.2.1': {}
+ '@ungap/structured-clone@1.3.0': {}
- '@vitejs/plugin-vue@5.2.1(vite@6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))':
+ '@vitejs/plugin-vue@5.2.1(vite@6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))':
dependencies:
- vite: 6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1)
+ vite: 6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0)
vue: 3.5.13(typescript@5.7.3)
- '@vitest/expect@3.0.3':
+ '@vitest/expect@3.0.4':
dependencies:
- '@vitest/spy': 3.0.3
- '@vitest/utils': 3.0.3
+ '@vitest/spy': 3.0.4
+ '@vitest/utils': 3.0.4
chai: 5.1.2
tinyrainbow: 2.0.0
- '@vitest/mocker@3.0.3(vite@6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1))':
+ '@vitest/mocker@3.0.4(vite@6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0))':
dependencies:
- '@vitest/spy': 3.0.3
+ '@vitest/spy': 3.0.4
estree-walker: 3.0.3
magic-string: 0.30.17
optionalDependencies:
- vite: 6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1)
+ vite: 6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0)
- '@vitest/pretty-format@3.0.3':
+ '@vitest/pretty-format@3.0.4':
dependencies:
tinyrainbow: 2.0.0
- '@vitest/runner@3.0.3':
+ '@vitest/runner@3.0.4':
dependencies:
- '@vitest/utils': 3.0.3
+ '@vitest/utils': 3.0.4
pathe: 2.0.2
- '@vitest/snapshot@3.0.3':
+ '@vitest/snapshot@3.0.4':
dependencies:
- '@vitest/pretty-format': 3.0.3
+ '@vitest/pretty-format': 3.0.4
magic-string: 0.30.17
pathe: 2.0.2
- '@vitest/spy@3.0.3':
+ '@vitest/spy@3.0.4':
dependencies:
tinyspy: 3.0.2
- '@vitest/utils@3.0.3':
+ '@vitest/utils@3.0.4':
dependencies:
- '@vitest/pretty-format': 3.0.3
+ '@vitest/pretty-format': 3.0.4
loupe: 3.1.2
tinyrainbow: 2.0.0
@@ -3574,19 +3573,19 @@ snapshots:
'@vue/shared@3.5.13': {}
- '@vueuse/core@12.4.0(typescript@5.7.3)':
+ '@vueuse/core@12.5.0(typescript@5.7.3)':
dependencies:
'@types/web-bluetooth': 0.0.20
- '@vueuse/metadata': 12.4.0
- '@vueuse/shared': 12.4.0(typescript@5.7.3)
+ '@vueuse/metadata': 12.5.0
+ '@vueuse/shared': 12.5.0(typescript@5.7.3)
vue: 3.5.13(typescript@5.7.3)
transitivePeerDependencies:
- typescript
- '@vueuse/integrations@12.4.0(axios@1.7.9(debug@4.4.0))(focus-trap@7.6.4)(typescript@5.7.3)':
+ '@vueuse/integrations@12.5.0(axios@1.7.9(debug@4.4.0))(focus-trap@7.6.4)(typescript@5.7.3)':
dependencies:
- '@vueuse/core': 12.4.0(typescript@5.7.3)
- '@vueuse/shared': 12.4.0(typescript@5.7.3)
+ '@vueuse/core': 12.5.0(typescript@5.7.3)
+ '@vueuse/shared': 12.5.0(typescript@5.7.3)
vue: 3.5.13(typescript@5.7.3)
optionalDependencies:
axios: 1.7.9(debug@4.4.0)
@@ -3594,9 +3593,9 @@ snapshots:
transitivePeerDependencies:
- typescript
- '@vueuse/metadata@12.4.0': {}
+ '@vueuse/metadata@12.5.0': {}
- '@vueuse/shared@12.4.0(typescript@5.7.3)':
+ '@vueuse/shared@12.5.0(typescript@5.7.3)':
dependencies:
vue: 3.5.13(typescript@5.7.3)
transitivePeerDependencies:
@@ -3606,21 +3605,21 @@ snapshots:
add-stream@1.0.0: {}
- algoliasearch@5.19.0:
- dependencies:
- '@algolia/client-abtesting': 5.19.0
- '@algolia/client-analytics': 5.19.0
- '@algolia/client-common': 5.19.0
- '@algolia/client-insights': 5.19.0
- '@algolia/client-personalization': 5.19.0
- '@algolia/client-query-suggestions': 5.19.0
- '@algolia/client-search': 5.19.0
- '@algolia/ingestion': 1.19.0
- '@algolia/monitoring': 1.19.0
- '@algolia/recommend': 5.19.0
- '@algolia/requester-browser-xhr': 5.19.0
- '@algolia/requester-fetch': 5.19.0
- '@algolia/requester-node-http': 5.19.0
+ algoliasearch@5.20.0:
+ dependencies:
+ '@algolia/client-abtesting': 5.20.0
+ '@algolia/client-analytics': 5.20.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/client-insights': 5.20.0
+ '@algolia/client-personalization': 5.20.0
+ '@algolia/client-query-suggestions': 5.20.0
+ '@algolia/client-search': 5.20.0
+ '@algolia/ingestion': 1.20.0
+ '@algolia/monitoring': 1.20.0
+ '@algolia/recommend': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
alien-signals@0.4.14: {}
@@ -3747,7 +3746,7 @@ snapshots:
comma-separated-tokens@2.0.3: {}
- commander@12.1.0: {}
+ commander@13.1.0: {}
commander@6.2.1: {}
@@ -4305,10 +4304,10 @@ snapshots:
dependencies:
uc.micro: 2.1.0
- lint-staged@15.4.1:
+ lint-staged@15.4.2:
dependencies:
chalk: 5.4.1
- commander: 12.1.0
+ commander: 13.1.0
debug: 4.4.0
execa: 8.0.1
lilconfig: 3.1.3
@@ -4316,7 +4315,7 @@ snapshots:
micromatch: 4.0.8
pidtree: 0.6.0
string-argv: 0.3.2
- yaml: 2.6.1
+ yaml: 2.7.0
transitivePeerDependencies:
- supports-color
@@ -4372,7 +4371,12 @@ snapshots:
mark.js@8.11.1: {}
- markdown-it-anchor@9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.0):
+ markdown-it-anchor@9.2.0(patch_hash=ivrlfano2jj27ilcyyknwlzzfu)(@types/markdown-it@14.1.2)(markdown-it@14.1.0):
+ dependencies:
+ '@types/markdown-it': 14.1.2
+ markdown-it: 14.1.0
+
+ markdown-it-async@2.0.0:
dependencies:
'@types/markdown-it': 14.1.2
markdown-it: 14.1.0
@@ -4412,7 +4416,7 @@ snapshots:
dependencies:
'@types/hast': 3.0.4
'@types/mdast': 4.0.4
- '@ungap/structured-clone': 1.2.1
+ '@ungap/structured-clone': 1.3.0
devlop: 1.1.0
micromark-util-sanitize-uri: 2.0.1
trim-lines: 3.0.1
@@ -4630,11 +4634,11 @@ snapshots:
mlly: 1.7.4
pathe: 2.0.2
- playwright-chromium@1.49.1:
+ playwright-chromium@1.50.0:
dependencies:
- playwright-core: 1.49.1
+ playwright-core: 1.50.0
- playwright-core@1.49.1: {}
+ playwright-core@1.50.0: {}
polka@1.0.0-next.28:
dependencies:
@@ -4962,11 +4966,6 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
- synckit@0.9.2:
- dependencies:
- '@pkgr/core': 0.1.1
- tslib: 2.8.1
-
tabbable@6.2.0: {}
temp-dir@3.0.0: {}
@@ -5089,13 +5088,13 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.2
- vite-node@3.0.3(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1):
+ vite-node@3.0.4(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0):
dependencies:
cac: 6.7.14
debug: 4.4.0
es-module-lexer: 1.6.0
pathe: 2.0.2
- vite: 6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1)
+ vite: 6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0)
transitivePeerDependencies:
- '@types/node'
- jiti
@@ -5110,16 +5109,16 @@ snapshots:
- tsx
- yaml
- vite@6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1):
+ vite@6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0):
dependencies:
esbuild: 0.24.2
postcss: 8.5.1
rollup: 4.31.0
optionalDependencies:
- '@types/node': 22.10.7
+ '@types/node': 22.10.9
fsevents: 2.3.3
jiti: 1.21.7
- yaml: 2.6.1
+ yaml: 2.7.0
vitepress-plugin-group-icons@1.3.5:
dependencies:
@@ -5129,15 +5128,15 @@ snapshots:
transitivePeerDependencies:
- supports-color
- vitest@3.0.3(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1):
+ vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0):
dependencies:
- '@vitest/expect': 3.0.3
- '@vitest/mocker': 3.0.3(vite@6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1))
- '@vitest/pretty-format': 3.0.3
- '@vitest/runner': 3.0.3
- '@vitest/snapshot': 3.0.3
- '@vitest/spy': 3.0.3
- '@vitest/utils': 3.0.3
+ '@vitest/expect': 3.0.4
+ '@vitest/mocker': 3.0.4(vite@6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0))
+ '@vitest/pretty-format': 3.0.4
+ '@vitest/runner': 3.0.4
+ '@vitest/snapshot': 3.0.4
+ '@vitest/spy': 3.0.4
+ '@vitest/utils': 3.0.4
chai: 5.1.2
debug: 4.4.0
expect-type: 1.1.0
@@ -5148,11 +5147,12 @@ snapshots:
tinyexec: 0.3.2
tinypool: 1.0.2
tinyrainbow: 2.0.0
- vite: 6.0.11(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1)
- vite-node: 3.0.3(@types/node@22.10.7)(jiti@1.21.7)(yaml@2.6.1)
+ vite: 6.0.11(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0)
+ vite-node: 3.0.4(@types/node@22.10.9)(jiti@1.21.7)(yaml@2.7.0)
why-is-node-running: 2.3.0
optionalDependencies:
- '@types/node': 22.10.7
+ '@types/debug': 4.1.12
+ '@types/node': 22.10.9
transitivePeerDependencies:
- jiti
- less
@@ -5246,7 +5246,7 @@ snapshots:
xmldom-sre@0.1.31: {}
- yaml@2.6.1: {}
+ yaml@2.7.0: {}
yoctocolors@2.1.1: {}
diff --git a/rollup.config.ts b/rollup.config.ts
index 8a996b01..6bf7ff1b 100644
--- a/rollup.config.ts
+++ b/rollup.config.ts
@@ -8,7 +8,6 @@ import { builtinModules, createRequire } from 'node:module'
import { type RollupOptions, defineConfig } from 'rollup'
import dts from 'rollup-plugin-dts'
import esbuild from 'rollup-plugin-esbuild'
-import { globSync } from 'tinyglobby'
const require = createRequire(import.meta.url)
const pkg = require('./package.json')
@@ -39,11 +38,7 @@ const plugins = [
]
const esmBuild: RollupOptions = {
- input: [
- 'src/node/index.ts',
- 'src/node/cli.ts',
- ...globSync('src/node/worker_*.ts')
- ],
+ input: ['src/node/index.ts', 'src/node/cli.ts'],
output: {
format: 'esm',
entryFileNames: `[name].js`,
diff --git a/src/client/app/index.ts b/src/client/app/index.ts
index 5acb3be5..1f1e8069 100644
--- a/src/client/app/index.ts
+++ b/src/client/app/index.ts
@@ -159,19 +159,14 @@ function newRouter(): Router {
if (inBrowser) {
createApp().then(({ app, router, data }) => {
// wait until page component is fetched before mounting
- router.go().then(() => {
+ router.go(location.href, { initialLoad: true }).then(() => {
// dynamically update head tags
useUpdateHead(router.route, data.site)
app.mount('#app')
// scroll to hash on new tab during dev
if (import.meta.env.DEV && location.hash) {
- const target = document.getElementById(
- decodeURIComponent(location.hash).slice(1)
- )
- if (target) {
- scrollTo(target, location.hash)
- }
+ scrollTo(location.hash)
}
})
})
diff --git a/src/client/app/router.ts b/src/client/app/router.ts
index 0cffc700..8b09339d 100644
--- a/src/client/app/router.ts
+++ b/src/client/app/router.ts
@@ -7,6 +7,8 @@ import { getScrollOffset, inBrowser, withBase } from './utils'
export interface Route {
path: string
+ hash: string
+ query: string
data: PageData
component: Component | null
}
@@ -19,7 +21,15 @@ export interface Router {
/**
* Navigate to a new URL.
*/
- go: (to?: string) => Promise
+ go: (
+ to: string,
+ options?: {
+ // @internal
+ initialLoad?: boolean
+ // Whether to smoothly scroll to the target position.
+ smoothScroll?: boolean
+ }
+ ) => Promise
/**
* Called before the route changes. Return `false` to cancel the navigation.
*/
@@ -37,10 +47,6 @@ export interface Router {
* Called after the route changes.
*/
onAfterRouteChange?: (to: string) => Awaitable
- /**
- * @deprecated use `onAfterRouteChange` instead
- */
- onAfterRouteChanged?: (to: string) => Awaitable
}
export const RouterSymbol: InjectionKey = Symbol()
@@ -51,6 +57,8 @@ const fakeHost = 'http://a.com'
const getDefaultRoute = (): Route => ({
path: '/',
+ hash: '',
+ query: '',
component: null,
data: notFoundPageData
})
@@ -68,39 +76,32 @@ export function createRouter(
const router: Router = {
route,
- go
- }
-
- async function go(href: string = inBrowser ? location.href : '/') {
- href = normalizeHref(href)
- if ((await router.onBeforeRouteChange?.(href)) === false) return
- if (inBrowser && href !== normalizeHref(location.href)) {
- // save scroll position before changing url
- history.replaceState({ scrollPosition: window.scrollY }, '')
- history.pushState({}, '', href)
+ async go(href, options) {
+ href = normalizeHref(href)
+ if ((await router.onBeforeRouteChange?.(href)) === false) return
+ if (!inBrowser || (await changeRoute(href, options))) await loadPage(href)
+ syncRouteQueryAndHash()
+ await router.onAfterRouteChange?.(href)
}
- await loadPage(href)
- await (router.onAfterRouteChange ?? router.onAfterRouteChanged)?.(href)
}
let latestPendingPath: string | null = null
async function loadPage(href: string, scrollPosition = 0, isRetry = false) {
if ((await router.onBeforePageLoad?.(href)) === false) return
+
const targetLoc = new URL(href, fakeHost)
const pendingPath = (latestPendingPath = targetLoc.pathname)
+
try {
let page = await loadPageModule(pendingPath)
- if (!page) {
- throw new Error(`Page not found: ${pendingPath}`)
- }
+ if (!page) throw new Error(`Page not found: ${pendingPath}`)
+
if (latestPendingPath === pendingPath) {
latestPendingPath = null
const { default: comp, __pageData } = page
- if (!comp) {
- throw new Error(`Invalid route component: ${comp}`)
- }
+ if (!comp) throw new Error(`Invalid route component: ${comp}`)
await router.onAfterPageLoad?.(href)
@@ -109,36 +110,25 @@ export function createRouter(
route.data = import.meta.env.PROD
? markRaw(__pageData)
: (readonly(__pageData) as PageData)
+ syncRouteQueryAndHash(targetLoc)
if (inBrowser) {
nextTick(() => {
let actualPathname =
siteDataRef.value.base +
__pageData.relativePath.replace(/(?:(^|\/)index)?\.md$/, '$1')
+
if (!siteDataRef.value.cleanUrls && !actualPathname.endsWith('/')) {
actualPathname += '.html'
}
+
if (actualPathname !== targetLoc.pathname) {
targetLoc.pathname = actualPathname
href = actualPathname + targetLoc.search + targetLoc.hash
history.replaceState({}, '', href)
}
- if (targetLoc.hash && !scrollPosition) {
- let target: HTMLElement | null = null
- try {
- target = document.getElementById(
- decodeURIComponent(targetLoc.hash).slice(1)
- )
- } catch (e) {
- console.warn(e)
- }
- if (target) {
- scrollTo(target, targetLoc.hash)
- return
- }
- }
- window.scrollTo(0, scrollPosition)
+ return scrollTo(targetLoc.hash, false, scrollPosition)
})
}
}
@@ -173,14 +163,22 @@ export function createRouter(
.replace(/^\//, '')
: '404.md'
route.data = { ...notFoundPageData, relativePath }
+ syncRouteQueryAndHash(targetLoc)
}
}
}
+ function syncRouteQueryAndHash(
+ loc: { search: string; hash: string } = inBrowser
+ ? location
+ : { search: '', hash: '' }
+ ) {
+ route.query = loc.search
+ route.hash = decodeURIComponent(loc.hash)
+ }
+
if (inBrowser) {
- if (history.state === null) {
- history.replaceState({}, '')
- }
+ if (history.state === null) history.replaceState({}, '')
window.addEventListener(
'click',
(e) => {
@@ -193,8 +191,9 @@ export function createRouter(
e.shiftKey ||
e.altKey ||
e.metaKey
- )
+ ) {
return
+ }
const link = e.target.closest('a')
if (
@@ -202,47 +201,24 @@ export function createRouter(
link.closest('.vp-raw') ||
link.hasAttribute('download') ||
link.hasAttribute('target')
- )
+ ) {
return
+ }
const linkHref =
link.getAttribute('href') ??
(link instanceof SVGAElement ? link.getAttribute('xlink:href') : null)
if (linkHref == null) return
- const { href, origin, pathname, hash, search } = new URL(
- linkHref,
- link.baseURI
- )
- const currentUrl = new URL(location.href) // copy to keep old data
+ const { href, origin, pathname } = new URL(linkHref, link.baseURI)
+ const currentLoc = new URL(location.href) // copy to keep old data
// only intercept inbound html links
- if (origin === currentUrl.origin && treatAsHtml(pathname)) {
+ if (origin === currentLoc.origin && treatAsHtml(pathname)) {
e.preventDefault()
- if (
- pathname === currentUrl.pathname &&
- search === currentUrl.search
- ) {
- // scroll between hash anchors in the same page
- // avoid duplicate history entries when the hash is same
- if (hash !== currentUrl.hash) {
- history.pushState({}, '', href)
- // still emit the event so we can listen to it in themes
- window.dispatchEvent(
- new HashChangeEvent('hashchange', {
- oldURL: currentUrl.href,
- newURL: href
- })
- )
- }
- if (hash) {
- // use smooth scroll when clicking on header anchor links
- scrollTo(link, hash, link.classList.contains('header-anchor'))
- } else {
- window.scrollTo(0, 0)
- }
- } else {
- go(href)
- }
+ router.go(href, {
+ // use smooth scroll when clicking on header anchor links
+ smoothScroll: link.classList.contains('header-anchor')
+ })
}
},
{ capture: true }
@@ -252,11 +228,13 @@ export function createRouter(
if (e.state === null) return
const href = normalizeHref(location.href)
await loadPage(href, (e.state && e.state.scrollPosition) || 0)
- await (router.onAfterRouteChange ?? router.onAfterRouteChanged)?.(href)
+ syncRouteQueryAndHash()
+ await router.onAfterRouteChange?.(href)
})
window.addEventListener('hashchange', (e) => {
e.preventDefault()
+ syncRouteQueryAndHash()
})
}
@@ -267,9 +245,7 @@ export function createRouter(
export function useRouter(): Router {
const router = inject(RouterSymbol)
- if (!router) {
- throw new Error('useRouter() is called without provider.')
- }
+ if (!router) throw new Error('useRouter() is called without provider.')
return router
}
@@ -277,13 +253,16 @@ export function useRoute(): Route {
return useRouter().route
}
-export function scrollTo(el: Element, hash: string, smooth = false) {
+export function scrollTo(hash: string, smooth = false, scrollPosition = 0) {
+ if (!hash || scrollPosition) {
+ window.scrollTo(0, scrollPosition)
+ return
+ }
+
let target: Element | null = null
try {
- target = el.classList.contains('header-anchor')
- ? el
- : document.getElementById(decodeURIComponent(hash).slice(1))
+ target = document.getElementById(decodeURIComponent(hash).slice(1))
} catch (e) {
console.warn(e)
}
@@ -293,17 +272,20 @@ export function scrollTo(el: Element, hash: string, smooth = false) {
window.getComputedStyle(target).paddingTop,
10
)
+
const targetTop =
window.scrollY +
target.getBoundingClientRect().top -
getScrollOffset() +
targetPadding
+
function scrollToTarget() {
// only smooth scroll if distance is smaller than screen height.
if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight)
window.scrollTo(0, targetTop)
else window.scrollTo({ left: 0, top: targetTop, behavior: 'smooth' })
}
+
requestAnimationFrame(scrollToTarget)
}
}
@@ -313,9 +295,7 @@ function handleHMR(route: Route): void {
if (import.meta.hot) {
// hot reload pageData
import.meta.hot.on('vitepress:pageData', (payload: PageDataPayload) => {
- if (shouldHotReload(payload)) {
- route.data = payload.pageData
- }
+ if (shouldHotReload(payload)) route.data = payload.pageData
})
}
}
@@ -332,9 +312,47 @@ function normalizeHref(href: string): string {
const url = new URL(href, fakeHost)
url.pathname = url.pathname.replace(/(^|\/)index(\.html)?$/, '$1')
// ensure correct deep link so page refresh lands on correct files.
- if (siteDataRef.value.cleanUrls)
+ if (siteDataRef.value.cleanUrls) {
url.pathname = url.pathname.replace(/\.html$/, '')
- else if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html'))
+ } else if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html')) {
url.pathname += '.html'
+ }
return url.pathname + url.search + url.hash
}
+
+async function changeRoute(
+ href: string,
+ { smoothScroll = false, initialLoad = false } = {}
+): Promise {
+ const loc = normalizeHref(location.href)
+ const { pathname, hash } = new URL(href, fakeHost)
+ const currentLoc = new URL(loc, fakeHost)
+
+ if (href === loc) {
+ if (!initialLoad) {
+ scrollTo(hash, smoothScroll)
+ return false
+ }
+ } else {
+ // save scroll position before changing URL
+ history.replaceState({ scrollPosition: window.scrollY }, '')
+ history.pushState({}, '', href)
+
+ if (pathname === currentLoc.pathname) {
+ // scroll between hash anchors on the same page, avoid duplicate entries
+ if (hash !== currentLoc.hash) {
+ window.dispatchEvent(
+ new HashChangeEvent('hashchange', {
+ oldURL: currentLoc.href,
+ newURL: href
+ })
+ )
+ scrollTo(hash, smoothScroll)
+ }
+
+ return false
+ }
+ }
+
+ return true
+}
diff --git a/src/node/build/bundle.ts b/src/node/build/bundle.ts
index e4d2556c..662e9593 100644
--- a/src/node/build/bundle.ts
+++ b/src/node/build/bundle.ts
@@ -88,13 +88,7 @@ export async function bundle(
ssr,
ssrEmitAssets: config.mpa,
// minify with esbuild in MPA mode (for CSS)
- minify: ssr
- ? config.mpa
- ? 'esbuild'
- : false
- : typeof options.minify === 'boolean'
- ? options.minify
- : !process.env.DEBUG,
+ minify: ssr ? !!config.mpa : (options.minify ?? !process.env.DEBUG),
outDir: ssr ? config.tempDir : config.outDir,
cssCodeSplit: false,
rollupOptions: {
diff --git a/src/node/cli.ts b/src/node/cli.ts
index 5e0be858..cf8ce305 100644
--- a/src/node/cli.ts
+++ b/src/node/cli.ts
@@ -12,6 +12,14 @@ if (process.env.DEBUG) {
const argv: any = minimist(process.argv.slice(2))
+Object.keys(argv).forEach((key) => {
+ if (argv[key] === 'true') {
+ argv[key] = true
+ } else if (argv[key] === 'false') {
+ argv[key] = false
+ }
+})
+
const logVersion = (logger: Logger) => {
logger.info(`\n ${c.green(`${c.bold('vitepress')} v${version}`)}\n`, {
clear: !logger.hasWarned
diff --git a/src/node/config.ts b/src/node/config.ts
index ffffa5ab..5f1698fe 100644
--- a/src/node/config.ts
+++ b/src/node/config.ts
@@ -10,14 +10,9 @@ import {
type ConfigEnv
} from 'vite'
import { DEFAULT_THEME_PATH } from './alias'
+import type { DefaultTheme } from './defaultTheme'
import { resolvePages } from './plugins/dynamicRoutesPlugin'
-import {
- APPEARANCE_KEY,
- slash,
- type DefaultTheme,
- type HeadConfig,
- type SiteData
-} from './shared'
+import { APPEARANCE_KEY, slash, type HeadConfig, type SiteData } from './shared'
import type { RawConfigExports, SiteConfig, UserConfig } from './siteConfig'
export { resolvePages } from './plugins/dynamicRoutesPlugin'
diff --git a/src/node/contentLoader.ts b/src/node/contentLoader.ts
index e3bee2e8..cbd12e1c 100644
--- a/src/node/contentLoader.ts
+++ b/src/node/contentLoader.ts
@@ -144,9 +144,9 @@ export function createContentLoader(
normalizePath(path.relative(config.srcDir, file))
.replace(/(^|\/)index\.md$/, '$1')
.replace(/\.md$/, config.cleanUrls ? '' : '.html')
- const html = render ? md.render(src) : undefined
+ const html = render ? await md.renderAsync(src) : undefined
const renderedExcerpt = renderExcerpt
- ? excerpt && md.render(excerpt)
+ ? excerpt && (await md.renderAsync(excerpt))
: undefined
const data: ContentData = {
src: includeSrc ? src : undefined,
diff --git a/src/node/defaultTheme.ts b/src/node/defaultTheme.ts
new file mode 100644
index 00000000..7b50e1b6
--- /dev/null
+++ b/src/node/defaultTheme.ts
@@ -0,0 +1,47 @@
+// this file contains node-only types of default theme
+// (functions starting with _ are node-only)
+// in most of the cases these will leak to client too
+// but these can import types from dev deps
+
+import type { MarkdownItAsync } from 'markdown-it-async'
+import type { DefaultTheme } from '../../types/default-theme'
+import type { PageSplitSection } from '../../types/local-search'
+import type { Awaitable, MarkdownEnv } from './shared'
+
+declare module '../../types/default-theme.js' {
+ namespace DefaultTheme {
+ interface LocalSearchOptions {
+ /**
+ * Allows transformation of content before indexing (node only)
+ * Return empty string to skip indexing
+ */
+ _render?: (
+ src: string,
+ env: MarkdownEnv,
+ md: MarkdownItAsync
+ ) => Awaitable
+ }
+
+ interface MiniSearchOptions {
+ /**
+ * Overrides the default regex based page splitter.
+ * Supports async generator, making it possible to run in true parallel
+ * (when used along with `node:child_process` or `worker_threads`)
+ * ---
+ * This should be especially useful for scalability reasons.
+ * ---
+ * @param {string} path - absolute path to the markdown source file
+ * @param {string} html - document page rendered as html
+ */
+ _splitIntoSections?: (
+ path: string,
+ html: string
+ ) =>
+ | AsyncGenerator
+ | Generator
+ | Awaitable
+ }
+ }
+}
+
+export type { DefaultTheme }
diff --git a/src/node/index.ts b/src/node/index.ts
index 90c0956a..63ee79f8 100644
--- a/src/node/index.ts
+++ b/src/node/index.ts
@@ -8,11 +8,7 @@ export { defineLoader, type LoaderModule } from './plugins/staticDataPlugin'
export * from './postcss/isolateStyles'
export * from './serve/serve'
export * from './server'
+export type { DefaultTheme } from './defaultTheme'
// shared types
-export type {
- DefaultTheme,
- HeadConfig,
- Header,
- SiteData
-} from '../../types/shared'
+export type { HeadConfig, Header, SiteData } from '../../types/shared'
diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts
index c7b74d9e..a39832a4 100644
--- a/src/node/markdown/markdown.ts
+++ b/src/node/markdown/markdown.ts
@@ -20,7 +20,7 @@ import type {
ThemeRegistrationAny
} from '@shikijs/types'
import type { Options } from 'markdown-it'
-import MarkdownIt from 'markdown-it'
+import { MarkdownItAsync } from 'markdown-it-async'
import anchorPlugin from 'markdown-it-anchor'
import attrsPlugin from 'markdown-it-attrs'
import { full as emojiPlugin } from 'markdown-it-emoji'
@@ -53,11 +53,11 @@ export interface MarkdownOptions extends Options {
/**
* Setup markdown-it instance before applying plugins
*/
- preConfig?: (md: MarkdownIt) => Awaited
+ preConfig?: (md: MarkdownItAsync) => Awaited
/**
* Setup markdown-it instance
*/
- config?: (md: MarkdownIt) => Awaited
+ config?: (md: MarkdownItAsync) => Awaited
/**
* Disable cache (experimental)
*/
@@ -190,7 +190,7 @@ export interface MarkdownOptions extends Options {
gfmAlerts?: boolean
}
-export type MarkdownRenderer = MarkdownIt
+export type MarkdownRenderer = MarkdownItAsync
let md: MarkdownRenderer | undefined
let _disposeHighlighter: (() => void) | undefined
@@ -223,7 +223,7 @@ export async function createMarkdownRenderer(
_disposeHighlighter = dispose
- md = MarkdownIt({ html: true, linkify: true, highlight, ...options })
+ md = new MarkdownItAsync({ html: true, linkify: true, highlight, ...options })
md.linkify.set({ fuzzyLink: false })
md.use(restoreEntities)
diff --git a/src/node/markdown/plugins/highlight.ts b/src/node/markdown/plugins/highlight.ts
index fb276055..f0a0170e 100644
--- a/src/node/markdown/plugins/highlight.ts
+++ b/src/node/markdown/plugins/highlight.ts
@@ -7,20 +7,12 @@ import {
type TransformerCompactLineOption
} from '@shikijs/transformers'
import { customAlphabet } from 'nanoid'
-import { createRequire } from 'node:module'
-import c from 'picocolors'
import type { LanguageRegistration, ShikiTransformer } from 'shiki'
import { createHighlighter, isSpecialLang } from 'shiki'
-import { createSyncFn } from 'synckit'
import type { Logger } from 'vite'
-import type { ShikiResolveLang } from 'worker_shikiResolveLang'
import type { MarkdownOptions, ThemeOptions } from '../markdown'
+import c from 'picocolors'
-const require = createRequire(import.meta.url)
-
-const resolveLangSync = createSyncFn(
- require.resolve('vitepress/dist/node/worker_shikiResolveLang.js')
-)
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10)
/**
@@ -59,7 +51,9 @@ export async function highlight(
theme: ThemeOptions,
options: MarkdownOptions,
logger: Pick = console
-): Promise<[(str: string, lang: string, attrs: string) => string, () => void]> {
+): Promise<
+ [(str: string, lang: string, attrs: string) => Promise, () => void]
+> {
const {
defaultHighlightLang: defaultLang = 'txt',
codeTransformers: userTransformers = []
@@ -77,25 +71,14 @@ export async function highlight(
langAlias: options.languageAlias
})
- function loadLanguage(name: string | LanguageRegistration) {
+ async function loadLanguage(name: string | LanguageRegistration) {
const lang = typeof name === 'string' ? name : name.name
if (
!isSpecialLang(lang) &&
!highlighter.getLoadedLanguages().includes(lang)
) {
- const resolvedLang = resolveLangSync(lang)
- if (resolvedLang.length) highlighter.loadLanguageSync(resolvedLang)
- else return false
+ await highlighter.loadLanguage(lang as any)
}
- return true
- }
-
- // patch for twoslash - https://github.com/vuejs/vitepress/issues/4334
- const internal = highlighter.getInternalContext()
- const getLanguage = internal.getLanguage
- internal.getLanguage = (name) => {
- loadLanguage(name)
- return getLanguage.call(internal, name)
}
await options?.shikiSetup?.(highlighter)
@@ -136,7 +119,7 @@ export async function highlight(
const mustacheRE = /\{\{.*?\}\}/g
return [
- (str: string, lang: string, attrs: string) => {
+ async (str: string, lang: string, attrs: string) => {
const vPre = vueRE.test(lang) ? '' : 'v-pre'
lang =
lang
@@ -145,7 +128,9 @@ export async function highlight(
.replace(vueRE, '')
.toLowerCase() || defaultLang
- if (!loadLanguage(lang)) {
+ try {
+ await loadLanguage(lang)
+ } catch {
logger.warn(
c.yellow(
`\nThe language '${lang}' is not loaded, falling back to '${defaultLang}' for syntax highlighting.`
diff --git a/src/node/markdownToVue.ts b/src/node/markdownToVue.ts
index 98f236c7..a4f8a20d 100644
--- a/src/node/markdownToVue.ts
+++ b/src/node/markdownToVue.ts
@@ -119,7 +119,7 @@ export async function createMarkdownToVueRenderFn(
realPath: fileOrig,
localeIndex
}
- const html = md.render(src, env)
+ const html = await md.renderAsync(src, env)
const {
frontmatter = {},
headers = [],
diff --git a/src/node/plugin.ts b/src/node/plugin.ts
index 563bbdf3..078fd2a6 100644
--- a/src/node/plugin.ts
+++ b/src/node/plugin.ts
@@ -75,7 +75,6 @@ export async function createVitePressPlugin(
site,
vue: userVuePluginOptions,
vite: userViteConfig,
- pages,
lastUpdated,
cleanUrls
} = siteConfig
@@ -131,7 +130,7 @@ export async function createVitePressPlugin(
markdownToVue = await createMarkdownToVueRenderFn(
srcDir,
markdown,
- pages,
+ siteConfig.pages,
config.command === 'build',
config.base,
lastUpdated,
diff --git a/src/node/plugins/localSearchPlugin.ts b/src/node/plugins/localSearchPlugin.ts
index d3b37b42..bffe74e8 100644
--- a/src/node/plugins/localSearchPlugin.ts
+++ b/src/node/plugins/localSearchPlugin.ts
@@ -5,13 +5,9 @@ import path from 'node:path'
import pMap from 'p-map'
import type { Plugin, ViteDevServer } from 'vite'
import type { SiteConfig } from '../config'
+import type { DefaultTheme } from '../defaultTheme'
import { createMarkdownRenderer } from '../markdown/markdown'
-import {
- getLocaleForPath,
- slash,
- type DefaultTheme,
- type MarkdownEnv
-} from '../shared'
+import { getLocaleForPath, slash, type MarkdownEnv } from '../shared'
import { processIncludes } from '../utils/processIncludes'
const debug = _debug('vitepress:local-search')
@@ -61,9 +57,10 @@ export async function localSearchPlugin(
const env: MarkdownEnv = { path: file, relativePath, cleanUrls }
const md_raw = await fs.promises.readFile(file, 'utf-8')
const md_src = processIncludes(srcDir, md_raw, file, [])
- if (options._render) return await options._render(md_src, env, md)
- else {
- const html = md.render(md_src, env)
+ if (options._render) {
+ return await options._render(md_src, env, md)
+ } else {
+ const html = await md.renderAsync(md_src, env)
return env.frontmatter?.search === false ? '' : html
}
}
diff --git a/src/node/worker_shikiResolveLang.ts b/src/node/worker_shikiResolveLang.ts
deleted file mode 100644
index 644caf9e..00000000
--- a/src/node/worker_shikiResolveLang.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import {
- bundledLanguages,
- type DynamicImportLanguageRegistration,
- type LanguageRegistration
-} from 'shiki'
-import { runAsWorker } from 'synckit'
-
-async function resolveLang(lang: string) {
- return (
- (
- bundledLanguages as Record<
- string,
- DynamicImportLanguageRegistration | undefined
- >
- )
- [lang]?.()
- .then((m) => m.default) || ([] as LanguageRegistration[])
- )
-}
-
-runAsWorker(resolveLang)
-
-export type ShikiResolveLang = typeof resolveLang
diff --git a/types/default-theme.d.ts b/types/default-theme.d.ts
index 10681a84..5a669c49 100644
--- a/types/default-theme.d.ts
+++ b/types/default-theme.d.ts
@@ -1,12 +1,8 @@
-import type MarkdownIt from 'markdown-it'
-import type { Options as MiniSearchOptions } from 'minisearch'
+import type { Options as _MiniSearchOptions } from 'minisearch'
import type { ComputedRef, Ref, ShallowRef } from 'vue'
import type { DocSearchProps } from './docsearch.js'
-import type {
- LocalSearchTranslations,
- PageSplitSection
-} from './local-search.js'
-import type { Awaitable, MarkdownEnv, PageData } from './shared.js'
+import type { LocalSearchTranslations } from './local-search.js'
+import type { PageData } from './shared.js'
export namespace DefaultTheme {
export interface Config {
@@ -413,46 +409,21 @@ export namespace DefaultTheme {
translations?: LocalSearchTranslations
locales?: Record>>
- miniSearch?: {
- /**
- * @see https://lucaong.github.io/minisearch/types/MiniSearch.Options.html
- */
- options?: Pick<
- MiniSearchOptions,
- 'extractField' | 'tokenize' | 'processTerm'
- >
- /**
- * @see https://lucaong.github.io/minisearch/types/MiniSearch.SearchOptions.html
- */
- searchOptions?: MiniSearchOptions['searchOptions']
-
- /**
- * Overrides the default regex based page splitter.
- * Supports async generator, making it possible to run in true parallel
- * (when used along with `node:child_process` or `worker_threads`)
- * ---
- * This should be especially useful for scalability reasons.
- * ---
- * @param {string} path - absolute path to the markdown source file
- * @param {string} html - document page rendered as html
- */
- _splitIntoSections?: (
- path: string,
- html: string
- ) =>
- | AsyncGenerator
- | Generator
- | Awaitable
- }
- /**
- * Allows transformation of content before indexing (node only)
- * Return empty string to skip indexing
- */
- _render?: (
- src: string,
- env: MarkdownEnv,
- md: MarkdownIt
- ) => Awaitable
+ miniSearch?: MiniSearchOptions
+ }
+
+ interface MiniSearchOptions {
+ /**
+ * @see https://lucaong.github.io/minisearch/types/MiniSearch.Options.html
+ */
+ options?: Pick<
+ _MiniSearchOptions,
+ 'extractField' | 'tokenize' | 'processTerm'
+ >
+ /**
+ * @see https://lucaong.github.io/minisearch/types/MiniSearch.SearchOptions.html
+ */
+ searchOptions?: _MiniSearchOptions['searchOptions']
}
// algolia -------------------------------------------------------------------