valaxy 1.0.0-beta.2 → 1.0.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/valaxy.mjs +7 -3
- package/client/components/ValaxyDecrypt.vue +1 -1
- package/client/components/ValaxyGalleryDecrypt.vue +1 -1
- package/client/components/ValaxyMd.vue +18 -5
- package/client/composables/app/useValaxyApp.ts +19 -5
- package/client/composables/app/useValaxyHead.ts +16 -1
- package/client/composables/features/medium-zoom.ts +64 -47
- package/client/composables/index.ts +0 -1
- package/client/index.html +1 -1
- package/client/styles/global/reset.scss +0 -4
- package/client/utils/iframe.ts +34 -0
- package/client/utils/index.ts +2 -0
- package/client/utils/path.ts +29 -0
- package/dist/node/cli/index.d.mts +7 -4
- package/dist/node/cli/index.mjs +3 -4
- package/dist/node/index.d.mts +110 -26
- package/dist/node/index.mjs +2 -3
- package/dist/shared/{valaxy._QBHi6cy.mjs → valaxy.B2Ey6Ph7.mjs} +630 -311
- package/dist/shared/{valaxy.-usflxeS.d.mts → valaxy.CmvWuejN.d.mts} +2 -0
- package/dist/types/index.d.mts +2 -2
- package/package.json +11 -13
- package/types/addon.ts +2 -0
- package/types/markdown-it-container.d.ts +3 -5
- package/types/markdown-it-plugins.d.ts +22 -0
package/bin/valaxy.mjs
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
+
import process from 'node:process'
|
|
4
5
|
import { run } from '../dist/node/cli/index.mjs'
|
|
5
6
|
|
|
6
|
-
function main() {
|
|
7
|
-
run()
|
|
7
|
+
async function main() {
|
|
8
|
+
await run()
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
main()
|
|
11
|
+
main().catch((error) => {
|
|
12
|
+
console.error(error)
|
|
13
|
+
process.exitCode = 1
|
|
14
|
+
})
|
|
@@ -103,7 +103,7 @@ const hasWarning = computed(() => isClient && location.protocol !== 'https:')
|
|
|
103
103
|
</div>
|
|
104
104
|
<div v-else>
|
|
105
105
|
<ValaxyDeprecatedContent :html="decryptedContent" />
|
|
106
|
-
<div w-full text-center mt-8>
|
|
106
|
+
<div class="decrypt-action mb-8 sm:mb-0" w-full text-center mt-8>
|
|
107
107
|
<button m-auto class="btn" font-bold @click="encryptAgain">
|
|
108
108
|
Encrypt Again
|
|
109
109
|
</button>
|
|
@@ -65,7 +65,7 @@ defineExpose({
|
|
|
65
65
|
</div>
|
|
66
66
|
<div v-else>
|
|
67
67
|
<slot :photos="photos" />
|
|
68
|
-
<div w-full text-center mt-8>
|
|
68
|
+
<div class="decrypt-action mb-8 sm:mb-0" w-full text-center mt-8>
|
|
69
69
|
<button m-auto class="btn" font-bold @click="encryptAgain">
|
|
70
70
|
Encrypt Again
|
|
71
71
|
</button>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type { Post } from 'valaxy'
|
|
3
|
-
import { onContentUpdated, runContentUpdated, useCodePen, useCollapseCode, useCopyCode, useMediumZoom, wrapTable } from 'valaxy'
|
|
3
|
+
import { onContentUpdated, runContentUpdated, setIframeAspectRatios, useCodePen, useCollapseCode, useCopyCode, useMediumZoom, wrapTable } from 'valaxy'
|
|
4
4
|
import { onMounted, onUpdated, ref } from 'vue'
|
|
5
5
|
import { useI18n } from 'vue-i18n'
|
|
6
6
|
import { useCodeGroups } from '../composables/codeGroups'
|
|
@@ -13,9 +13,14 @@ const props = defineProps<{
|
|
|
13
13
|
|
|
14
14
|
const { t } = useI18n()
|
|
15
15
|
|
|
16
|
-
const contentRef = ref()
|
|
16
|
+
const contentRef = ref<HTMLElement>()
|
|
17
17
|
onContentUpdated(() => {
|
|
18
|
-
|
|
18
|
+
const content = contentRef.value
|
|
19
|
+
if (!content)
|
|
20
|
+
return
|
|
21
|
+
|
|
22
|
+
wrapTable(content)
|
|
23
|
+
setIframeAspectRatios(content)
|
|
19
24
|
})
|
|
20
25
|
|
|
21
26
|
onMounted(() => {
|
|
@@ -41,8 +46,8 @@ useVanillaLazyLoad()
|
|
|
41
46
|
</script>
|
|
42
47
|
|
|
43
48
|
<template>
|
|
44
|
-
<article v-if="$slots.default" :class="frontmatter.markdownClass || 'markdown-body'">
|
|
45
|
-
<slot
|
|
49
|
+
<article v-if="$slots.default" ref="contentRef" :class="frontmatter.markdownClass || 'markdown-body'">
|
|
50
|
+
<slot @vue:updated="runContentUpdated" />
|
|
46
51
|
|
|
47
52
|
<div v-if="frontmatter.url" text="center">
|
|
48
53
|
<a
|
|
@@ -75,4 +80,12 @@ useVanillaLazyLoad()
|
|
|
75
80
|
.medium-zoom-image--opened {
|
|
76
81
|
z-index: 999;
|
|
77
82
|
}
|
|
83
|
+
|
|
84
|
+
// Keep dimensioned embeds proportional when their width is constrained by the
|
|
85
|
+
// article. :where() deliberately leaves explicit author styles in control.
|
|
86
|
+
:where(iframe[data-va-responsive-iframe]) {
|
|
87
|
+
max-width: 100%;
|
|
88
|
+
height: auto;
|
|
89
|
+
aspect-ratio: var(--va-iframe-aspect-ratio);
|
|
90
|
+
}
|
|
78
91
|
</style>
|
|
@@ -5,10 +5,11 @@ import { useI18n } from 'vue-i18n'
|
|
|
5
5
|
import { useRoute } from 'vue-router'
|
|
6
6
|
import { useFrontmatter, useLocale, useValaxyHead, useValaxyI18n } from '../../composables'
|
|
7
7
|
import { useTimezone } from '../../composables/global'
|
|
8
|
+
import { useSiteConfig } from '../../config'
|
|
9
|
+
import { resolveSiteUrl } from '../../utils'
|
|
8
10
|
// https://github.com/vueuse/head
|
|
9
11
|
// you can use this to manipulate the document head in any components,
|
|
10
12
|
// they will be rendered correctly in the html results with vite-ssg
|
|
11
|
-
import { useSiteConfig } from '../../config'
|
|
12
13
|
|
|
13
14
|
export function useValaxyApp() {
|
|
14
15
|
const siteConfig = useSiteConfig()
|
|
@@ -27,8 +28,16 @@ export function useValaxyApp() {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
// seo
|
|
30
|
-
const siteUrl = computed(() =>
|
|
31
|
+
const siteUrl = computed(() => resolveSiteUrl(
|
|
32
|
+
siteConfig.value.url,
|
|
33
|
+
fm.value.url || route.path,
|
|
34
|
+
))
|
|
31
35
|
const description = computed(() => $tO(fm.value.excerpt) || $tO(fm.value.description) || $t(siteConfig.value.description))
|
|
36
|
+
const ogImage = computed(() => resolveSiteUrl(
|
|
37
|
+
siteConfig.value.url,
|
|
38
|
+
fm.value.ogImage || fm.value.cover || fm.value.firstImage || siteConfig.value.favicon,
|
|
39
|
+
))
|
|
40
|
+
const seoTitle = computed(() => $tO(fm.value.title) || $t(siteConfig.value.title))
|
|
32
41
|
|
|
33
42
|
useSeoMeta({
|
|
34
43
|
description,
|
|
@@ -36,10 +45,15 @@ export function useValaxyApp() {
|
|
|
36
45
|
ogLocale: computed(() => locale.value || fm.value.lang || siteConfig.value.lang || 'en'),
|
|
37
46
|
ogLocaleAlternate: computed(() => siteConfig.value.languages.filter(l => l !== locale.value)),
|
|
38
47
|
ogSiteName: computed(() => $t(siteConfig.value.title)),
|
|
39
|
-
ogTitle:
|
|
40
|
-
ogImage
|
|
48
|
+
ogTitle: seoTitle,
|
|
49
|
+
ogImage,
|
|
50
|
+
ogImageAlt: seoTitle,
|
|
41
51
|
ogType: 'website',
|
|
42
52
|
ogUrl: siteUrl,
|
|
53
|
+
twitterCard: 'summary_large_image',
|
|
54
|
+
twitterDescription: description,
|
|
55
|
+
twitterImage: ogImage,
|
|
56
|
+
twitterTitle: seoTitle,
|
|
43
57
|
})
|
|
44
58
|
|
|
45
59
|
// for SEO
|
|
@@ -48,7 +62,7 @@ export function useValaxyApp() {
|
|
|
48
62
|
// Personal Website or Blog
|
|
49
63
|
definePerson({
|
|
50
64
|
name: $t(siteConfig.value.author.name),
|
|
51
|
-
url:
|
|
65
|
+
url: siteConfig.value.url,
|
|
52
66
|
image: $t(siteConfig.value.author.avatar),
|
|
53
67
|
sameAs: siteConfig.value.social.map(s => s.link),
|
|
54
68
|
}),
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import { useHead } from '@unhead/vue'
|
|
2
2
|
import { computed, onMounted } from 'vue'
|
|
3
|
+
import { useRoute } from 'vue-router'
|
|
3
4
|
import pkg from '../../../package.json' with { type: 'json' }
|
|
4
5
|
|
|
5
6
|
import { useFrontmatter, useValaxyI18n } from '../../composables'
|
|
6
7
|
import { useSiteConfig } from '../../config'
|
|
8
|
+
import { resolveSiteUrl, withBase } from '../../utils'
|
|
7
9
|
|
|
8
10
|
export function useValaxyHead() {
|
|
9
11
|
const { $t, $tO, locale } = useValaxyI18n()
|
|
10
12
|
|
|
11
13
|
const fm = useFrontmatter()
|
|
14
|
+
const route = useRoute()
|
|
12
15
|
const siteConfig = useSiteConfig()
|
|
13
16
|
const $title = computed(() => $tO(fm.value.title))
|
|
17
|
+
const canonicalUrl = computed(() => {
|
|
18
|
+
const siteUrl = siteConfig.value.url
|
|
19
|
+
if (!/^https?:\/\//.test(siteUrl))
|
|
20
|
+
return ''
|
|
21
|
+
|
|
22
|
+
const pagePath = fm.value.url || route.path
|
|
23
|
+
return resolveSiteUrl(siteUrl, pagePath)
|
|
24
|
+
})
|
|
14
25
|
|
|
15
26
|
useHead({
|
|
16
27
|
htmlAttrs: {
|
|
@@ -24,7 +35,7 @@ export function useValaxyHead() {
|
|
|
24
35
|
link: [
|
|
25
36
|
{
|
|
26
37
|
rel: 'icon',
|
|
27
|
-
href: siteConfig.value.favicon,
|
|
38
|
+
href: withBase(siteConfig.value.favicon),
|
|
28
39
|
type: siteConfig.value.favicon?.endsWith('svg') ? 'image/svg+xml' : 'image/png',
|
|
29
40
|
},
|
|
30
41
|
],
|
|
@@ -48,6 +59,10 @@ export function useValaxyHead() {
|
|
|
48
59
|
},
|
|
49
60
|
})
|
|
50
61
|
|
|
62
|
+
useHead(computed(() => canonicalUrl.value
|
|
63
|
+
? { link: [{ rel: 'canonical', href: canonicalUrl.value }] }
|
|
64
|
+
: {}))
|
|
65
|
+
|
|
51
66
|
// Add mac detection class on client side only, after hydration
|
|
52
67
|
// to avoid SSR/client mismatch on the <html> element
|
|
53
68
|
onMounted(() => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { Zoom, ZoomSelector } from 'medium-zoom'
|
|
2
|
+
import type { MaybeRefOrGetter } from 'vue'
|
|
1
3
|
import mediumZoom from 'medium-zoom'
|
|
2
4
|
import { useSiteConfig } from 'valaxy'
|
|
3
|
-
import { onMounted } from 'vue'
|
|
5
|
+
import { computed, onBeforeUnmount, onMounted, toValue } from 'vue'
|
|
4
6
|
|
|
5
7
|
interface ZoomRectLike {
|
|
6
8
|
left: number
|
|
@@ -97,55 +99,70 @@ function freezeOpenedImage(element: HTMLElement): SavedZoomImageStyle | null {
|
|
|
97
99
|
/**
|
|
98
100
|
* @description image preview by medium-zoom
|
|
99
101
|
*/
|
|
100
|
-
export function useMediumZoom() {
|
|
102
|
+
export function useMediumZoom(selector?: MaybeRefOrGetter<ZoomSelector | null | undefined>) {
|
|
101
103
|
const siteConfig = useSiteConfig()
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
.map(freezeOpenedImage)
|
|
120
|
-
.filter((style): style is SavedZoomImageStyle => style !== null)
|
|
104
|
+
const enabled = computed(() => siteConfig.value.mediumZoom.enable)
|
|
105
|
+
let savedStyles: SavedZoomImageStyle[] = []
|
|
106
|
+
let zoom: Zoom | undefined
|
|
107
|
+
|
|
108
|
+
function restoreSavedStyles() {
|
|
109
|
+
if (!savedStyles.length)
|
|
110
|
+
return
|
|
111
|
+
|
|
112
|
+
for (const style of savedStyles) {
|
|
113
|
+
const { element } = style
|
|
114
|
+
if (!document.body.contains(element))
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
applyWithoutTransformTransition(element, () => {
|
|
118
|
+
element.style.transform = style.transform
|
|
119
|
+
element.style.width = style.width
|
|
120
|
+
element.style.height = style.height
|
|
121
121
|
})
|
|
122
122
|
|
|
123
|
-
zoom.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
123
|
+
// medium-zoom clears transform before emitting close. Restore that state
|
|
124
|
+
// after replacing the frozen dimensions so its transition can finish.
|
|
125
|
+
element.style.transform = ''
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
savedStyles = []
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function handleOpened() {
|
|
132
|
+
savedStyles = Array
|
|
133
|
+
.from(document.querySelectorAll<HTMLElement>('.medium-zoom-image--opened'))
|
|
134
|
+
.map(freezeOpenedImage)
|
|
135
|
+
.filter((style): style is SavedZoomImageStyle => style !== null)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
onMounted(() => {
|
|
139
|
+
if (!enabled.value)
|
|
140
|
+
return
|
|
141
|
+
|
|
142
|
+
const mediumZoomConfig = siteConfig.value.mediumZoom
|
|
143
|
+
const target = selector === undefined
|
|
144
|
+
? mediumZoomConfig.selector || '.markdown-body img'
|
|
145
|
+
: toValue(selector)
|
|
146
|
+
if (!target)
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
zoom = mediumZoom(target, {
|
|
150
|
+
background: 'var(--medium-zoom-c-bg, rgba(0, 0, 0, 0.8))',
|
|
151
|
+
...mediumZoomConfig.options,
|
|
149
152
|
})
|
|
153
|
+
zoom.on('opened', handleOpened)
|
|
154
|
+
zoom.on('close', restoreSavedStyles)
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
onBeforeUnmount(() => {
|
|
158
|
+
restoreSavedStyles()
|
|
159
|
+
zoom?.off('opened', handleOpened)
|
|
160
|
+
zoom?.off('close', restoreSavedStyles)
|
|
161
|
+
zoom?.detach()
|
|
162
|
+
zoom = undefined
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
enabled,
|
|
150
167
|
}
|
|
151
168
|
}
|
package/client/index.html
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
5
|
<!-- head -->
|
|
7
6
|
</head>
|
|
8
7
|
<body>
|
|
9
8
|
<div id="app"></div>
|
|
9
|
+
<div id="valaxy-teleports"></div>
|
|
10
10
|
<script type="module" src="./main.ts"></script>
|
|
11
11
|
<!-- body -->
|
|
12
12
|
</body>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const RESPONSIVE_IFRAME_ATTRIBUTE = 'data-va-responsive-iframe'
|
|
2
|
+
const IFRAME_ASPECT_RATIO_PROPERTY = '--va-iframe-aspect-ratio'
|
|
3
|
+
|
|
4
|
+
function parsePositiveDimension(value: string | null) {
|
|
5
|
+
if (value === null)
|
|
6
|
+
return
|
|
7
|
+
|
|
8
|
+
const dimension = Number(value)
|
|
9
|
+
if (Number.isFinite(dimension) && dimension > 0)
|
|
10
|
+
return dimension
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Make dimensioned iframes responsive without assuming a fixed video ratio.
|
|
15
|
+
* The generated custom property is consumed by the low-specificity markdown
|
|
16
|
+
* styles, so an author's explicit height or aspect-ratio still takes priority.
|
|
17
|
+
*/
|
|
18
|
+
export function setIframeAspectRatios(container: ParentNode = document) {
|
|
19
|
+
container.querySelectorAll<HTMLIFrameElement>('iframe').forEach((iframe) => {
|
|
20
|
+
const width = parsePositiveDimension(iframe.getAttribute('width'))
|
|
21
|
+
const height = parsePositiveDimension(iframe.getAttribute('height'))
|
|
22
|
+
|
|
23
|
+
if (width && height) {
|
|
24
|
+
iframe.setAttribute(RESPONSIVE_IFRAME_ATTRIBUTE, '')
|
|
25
|
+
iframe.style.setProperty(IFRAME_ASPECT_RATIO_PROPERTY, `${width} / ${height}`)
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (iframe.hasAttribute(RESPONSIVE_IFRAME_ATTRIBUTE)) {
|
|
30
|
+
iframe.removeAttribute(RESPONSIVE_IFRAME_ATTRIBUTE)
|
|
31
|
+
iframe.style.removeProperty(IFRAME_ASPECT_RATIO_PROPERTY)
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
}
|
package/client/utils/index.ts
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { EXTERNAL_URL_RE } from '../../shared'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Join two URL paths while resolving a slash collision.
|
|
5
|
+
*/
|
|
6
|
+
function joinPath(base: string, path: string): string {
|
|
7
|
+
return `${base}${path}`.replace(/\/+/g, '/')
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Append Vite's resolved base to an internal root-absolute URL.
|
|
12
|
+
* External and relative URLs are returned unchanged.
|
|
13
|
+
*/
|
|
14
|
+
export function withBase(path: string): string {
|
|
15
|
+
return EXTERNAL_URL_RE.test(path) || !path.startsWith('/')
|
|
16
|
+
? path
|
|
17
|
+
: joinPath(import.meta.env.BASE_URL, path)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Resolve an internal path against the configured canonical site URL.
|
|
22
|
+
* Root-absolute paths remain relative to a site URL's deployment subpath.
|
|
23
|
+
*/
|
|
24
|
+
export function resolveSiteUrl(siteUrl: string, path: string): string {
|
|
25
|
+
if (!path || EXTERNAL_URL_RE.test(path) || !/^https?:\/\//.test(siteUrl))
|
|
26
|
+
return path
|
|
27
|
+
|
|
28
|
+
return new URL(path.replace(/^\/+/, ''), `${siteUrl.replace(/\/+$/, '')}/`).href
|
|
29
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as yargs from 'yargs';
|
|
2
1
|
import { Argv } from 'yargs';
|
|
3
2
|
import { LogLevel, ViteDevServer } from 'vite';
|
|
4
3
|
|
|
@@ -11,7 +10,11 @@ declare function startValaxyDev({ root, port, remote, log, open, }: {
|
|
|
11
10
|
}): Promise<ViteDevServer>;
|
|
12
11
|
declare function registerDevCommand(cli: Argv): void;
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
interface CreateCliOptions {
|
|
14
|
+
userRoot?: string;
|
|
15
|
+
}
|
|
16
|
+
declare function createCli(argv?: string[], options?: CreateCliOptions): Promise<Argv<object>>;
|
|
17
|
+
declare function run(argv?: string[], options?: CreateCliOptions): Promise<void>;
|
|
16
18
|
|
|
17
|
-
export {
|
|
19
|
+
export { createCli, registerDevCommand, run, startValaxyDev };
|
|
20
|
+
export type { CreateCliOptions };
|
package/dist/node/cli/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import 'node:path';
|
|
1
2
|
import 'node:process';
|
|
2
3
|
import 'yargs';
|
|
3
4
|
import 'yargs/helpers';
|
|
4
|
-
export { c as
|
|
5
|
+
export { c as createCli, J as registerDevCommand, Y as run, _ as startValaxyDev } from '../../shared/valaxy.B2Ey6Ph7.mjs';
|
|
5
6
|
import 'node:os';
|
|
6
|
-
import 'node:path';
|
|
7
7
|
import 'consola';
|
|
8
8
|
import 'consola/utils';
|
|
9
9
|
import 'fast-glob';
|
|
@@ -26,7 +26,7 @@ import '@valaxyjs/utils';
|
|
|
26
26
|
import 'node:fs/promises';
|
|
27
27
|
import 'dayjs';
|
|
28
28
|
import 'feed';
|
|
29
|
-
import 'markdown-
|
|
29
|
+
import 'markdown-exit';
|
|
30
30
|
import 'table';
|
|
31
31
|
import 'hookable';
|
|
32
32
|
import 'node:fs';
|
|
@@ -38,7 +38,6 @@ import 'vitepress-plugin-group-icons';
|
|
|
38
38
|
import 'p-map';
|
|
39
39
|
import 'node:buffer';
|
|
40
40
|
import 'minisearch';
|
|
41
|
-
import 'markdown-it-async';
|
|
42
41
|
import '@shikijs/transformers';
|
|
43
42
|
import 'shiki';
|
|
44
43
|
import 'css-i18n';
|