Merge branch 'main' into feat/translate-docs-japanese

pull/4527/head
kamome_runs 8 months ago committed by GitHub
commit d9c699e043
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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

@ -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

@ -1,4 +1,5 @@
import Theme from 'vitepress/theme'
import 'virtual:group-icons.css'
import './styles.css'
export default Theme

@ -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;
}

@ -36,25 +36,3 @@ features:
title: Ship Fast Sites
details: Fast initial load with static HTML, fast post-load navigation with client-side routing.
---
<style>
: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);
}
}
</style>

@ -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({
}
})
```
<style>
img[src="/search.png"] {
width: 100%;
aspect-ratio: 1 / 1;
}
</style>

@ -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.
---
<style>
: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);
}
}
</style>

@ -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({
}
})
```
<style>
img[src="/search.png"] {
width: 100%;
aspect-ratio: 1 / 1;
}
</style>

@ -36,30 +36,3 @@ features:
title: ارسال سایت های سریع
details: بارگذاری اولیه سریع با HTML ایستا، ناوبری سریع پس از بارگیری با مسیریابی سمت کلاینت
---
<style>
@import url("https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap");
:root {
--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';
--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);
}
}
</style>

@ -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({
}
})
```
<style>
img[src="/search.png"] {
width: 100%;
aspect-ratio: 1 / 1;
}
</style>

@ -36,25 +36,3 @@ features:
title: 웹사이트를 빠르게 제공
details: 정적 HTML로 빠른 초기 로딩, 클라이언트 측 라우팅을 통한 빠른 탐색.
---
<style>
: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);
}
}
</style>

@ -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({
}
})
```
<style>
img[src="/search.png"] {
width: 100%;
aspect-ratio: 1 / 1;
}
</style>

@ -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.
---
<style>
: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);
}
}
</style>

@ -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({
}
})
```
<style>
img[src="/search.png"] {
width: 100%;
aspect-ratio: 1 / 1;
}
</style>

@ -36,25 +36,3 @@ features:
title: Быстрый запуск веб-сайтов
details: Быстрая начальная загрузка с помощью статического HTML, быстрая навигация после загрузки с помощью маршрутизации на стороне клиента.
---
<style>
: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);
}
}
</style>

@ -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({
}
})
```
<style>
img[src="/search.png"] {
width: 100%;
aspect-ratio: 1 / 1;
}
</style>

@ -36,24 +36,3 @@ features:
title: 速度真的很快!
details: 采用静态 HTML 实现快速的页面初次加载,使用客户端路由实现快速的页面切换导航。
---
<style>
: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);
}
}
</style>

@ -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({
}
})
```
<style>
img[src="/search.png"] {
width: 100%;
aspect-ratio: 1 / 1;
}
</style>

@ -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"
}
}
}

@ -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<string, string | number>;

@ -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: {}

@ -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`,

@ -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)
}
})
})

@ -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<void>
go: (
to: string,
options?: {
// @internal
initialLoad?: boolean
// Whether to smoothly scroll to the target position.
smoothScroll?: boolean
}
) => Promise<void>
/**
* 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<void>
/**
* @deprecated use `onAfterRouteChange` instead
*/
onAfterRouteChanged?: (to: string) => Awaitable<void>
}
export const RouterSymbol: InjectionKey<Router> = 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<HTMLAnchorElement | SVGAElement>('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<boolean> {
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
}

@ -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: {

@ -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

@ -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'

@ -144,9 +144,9 @@ export function createContentLoader<T = ContentData[]>(
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,

@ -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<string>
}
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<PageSplitSection>
| Generator<PageSplitSection>
| Awaitable<PageSplitSection[]>
}
}
}
export type { DefaultTheme }

@ -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'

@ -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<void>
preConfig?: (md: MarkdownItAsync) => Awaited<void>
/**
* Setup markdown-it instance
*/
config?: (md: MarkdownIt) => Awaited<void>
config?: (md: MarkdownItAsync) => Awaited<void>
/**
* 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)

@ -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<ShikiResolveLang>(
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<Logger, 'warn'> = console
): Promise<[(str: string, lang: string, attrs: string) => string, () => void]> {
): Promise<
[(str: string, lang: string, attrs: string) => Promise<string>, () => 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.`

@ -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 = [],

@ -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,

@ -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
}
}

@ -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

@ -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<string, Partial<Omit<LocalSearchOptions, 'locales'>>>
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<PageSplitSection>
| Generator<PageSplitSection>
| Awaitable<PageSplitSection[]>
}
/**
* Allows transformation of content before indexing (node only)
* Return empty string to skip indexing
*/
_render?: (
src: string,
env: MarkdownEnv,
md: MarkdownIt
) => Awaitable<string>
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 -------------------------------------------------------------------

Loading…
Cancel
Save