refactor: use isolatedDeclarations in tsconfig (#594)

This commit is contained in:
pengzhanbo 2025-05-12 16:17:47 +08:00 committed by GitHub
parent 1f8a9ce251
commit aaa473572c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
106 changed files with 455 additions and 216 deletions

View File

@ -8,7 +8,11 @@ import { createPackageJson } from './packageJson.js'
import { createRender } from './render.js'
import { getTemplate, readFiles, readJsonFile, writeFiles } from './utils/index.js'
export async function generate(mode: Mode, data: ResolvedData, cwd = process.cwd()): Promise<void> {
export async function generate(
mode: Mode,
data: ResolvedData,
cwd: string = process.cwd(),
): Promise<void> {
let userPkg: Record<string, any> = {}
if (mode === Mode.init) {
const pkgPath = path.join(cwd, 'package.json')

View File

@ -11,7 +11,7 @@ import { prompt } from './prompt.js'
import { t } from './translate.js'
import { getPackageManager } from './utils/index.js'
export async function run(mode: Mode, root?: string) {
export async function run(mode: Mode, root?: string): Promise<void> {
intro(colors.cyan('Welcome to VuePress and vuepress-theme-plume !'))
const result = await prompt(mode, root)

View File

@ -1,15 +1,23 @@
import type { Langs, Locale } from './types.js'
import { locales } from './locales/index.js'
function createTranslate(lang?: Langs) {
interface Translate {
setLang: (lang: Langs) => void
t: (key: keyof Locale) => string
}
function createTranslate(lang?: Langs): Translate {
let current: Langs = lang || 'en-US'
return {
setLang: (lang: Langs) => {
setLang: (lang) => {
current = lang
},
t: (key: keyof Locale) => locales[current][key],
t: key => locales[current][key],
}
}
export const { t, setLang } = createTranslate()
const translate = createTranslate()
export const t: Translate['t'] = translate.t
export const setLang: Translate['setLang'] = translate.setLang

View File

@ -22,7 +22,7 @@ export async function writeFiles(
files: File[],
target: string,
rewrite?: (path: string) => string,
) {
): Promise<void> {
for (const { filepath, content } of files) {
let root = path.join(target, filepath).replace(/\.handlebars$/, '')
if (rewrite)

View File

@ -1,11 +1,11 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'
export const __dirname = path.dirname(fileURLToPath(import.meta.url))
export const __dirname: string = path.dirname(fileURLToPath(import.meta.url))
export const resolve = (...args: string[]) => path.resolve(__dirname, '../', ...args)
export const resolve = (...args: string[]): string => path.resolve(__dirname, '../', ...args)
export const getTemplate = (dir: string) => resolve('templates', dir)
export const getTemplate = (dir: string): string => resolve('templates', dir)
export * from './fs.js'
export * from './getPackageManager.js'

View File

@ -1,3 +1,4 @@
import type { ClientConfig } from 'vuepress/client'
import { h } from 'vue'
import { Layout } from 'vuepress-theme-plume/client'
import { defineClientConfig } from 'vuepress/client'
@ -13,4 +14,4 @@ export default defineClientConfig({
'aside-outline-after': () => h(AsideNav),
}),
},
})
}) as ClientConfig

View File

@ -1,3 +1,4 @@
import type { UserConfig } from 'vuepress'
import fs from 'node:fs'
import path from 'node:path'
import { viteBundler } from '@vuepress/bundler-vite'
@ -48,4 +49,4 @@ export default defineUserConfig({
shouldPrefetch: false,
theme,
})
}) as UserConfig

View File

@ -1,7 +1,8 @@
import type { ThemeNavItem } from 'vuepress-theme-plume'
import { defineNavbarConfig } from 'vuepress-theme-plume'
import { version } from '../../package.json'
export const zhNavbar = defineNavbarConfig([
export const zhNavbar: ThemeNavItem[] = defineNavbarConfig([
{
text: '指南',
icon: 'icon-park-outline:guide-board',
@ -54,7 +55,7 @@ export const zhNavbar = defineNavbarConfig([
},
])
export const enNavbar = defineNavbarConfig([
export const enNavbar: ThemeNavItem[] = defineNavbarConfig([
{
text: 'Guide',
icon: 'icon-park-outline:guide-board',

View File

@ -1,8 +1,9 @@
import type { ThemeNoteListOptions } from 'vuepress-theme-plume'
import { defineNotesConfig } from 'vuepress-theme-plume'
import { themeConfig } from './theme-config'
import { themeGuide } from './theme-guide'
export const enNotes = defineNotesConfig({
export const enNotes: ThemeNoteListOptions = defineNotesConfig({
dir: 'en/notes',
link: '/',
notes: [

View File

@ -1,6 +1,7 @@
import type { ThemeNote } from 'vuepress-theme-plume'
import { defineNoteConfig } from 'vuepress-theme-plume'
export const themeConfig = defineNoteConfig({
export const themeConfig: ThemeNote = defineNoteConfig({
dir: 'theme/config',
link: '/config/',
sidebar: [

View File

@ -1,6 +1,7 @@
import type { ThemeNote } from 'vuepress-theme-plume'
import { defineNoteConfig } from 'vuepress-theme-plume'
export const themeGuide = defineNoteConfig({
export const themeGuide: ThemeNote = defineNoteConfig({
dir: 'theme/guide',
link: '/guide/',
sidebar: [

View File

@ -1,10 +1,11 @@
import type { ThemeNoteListOptions } from 'vuepress-theme-plume'
import { defineNotesConfig } from 'vuepress-theme-plume'
// import { plugins } from './plugins'
import { themeConfig } from './theme-config'
import { themeGuide } from './theme-guide'
import { tools } from './tools'
export const zhNotes = defineNotesConfig({
export const zhNotes: ThemeNoteListOptions = defineNotesConfig({
dir: 'notes',
link: '/',
notes: [

View File

@ -1,6 +1,7 @@
import type { ThemeNote } from 'vuepress-theme-plume'
import { defineNoteConfig } from 'vuepress-theme-plume'
export const plugins = defineNoteConfig({
export const plugins: ThemeNote = defineNoteConfig({
dir: 'plugins',
link: '/plugins/',
sidebar: [

View File

@ -1,6 +1,7 @@
import type { ThemeNote } from 'vuepress-theme-plume'
import { defineNoteConfig } from 'vuepress-theme-plume'
export const themeConfig = defineNoteConfig({
export const themeConfig: ThemeNote = defineNoteConfig({
dir: 'theme/config',
link: '/config/',
sidebar: [

View File

@ -1,6 +1,7 @@
import type { ThemeNote } from 'vuepress-theme-plume'
import { defineNoteConfig } from 'vuepress-theme-plume'
export const themeGuide = defineNoteConfig({
export const themeGuide: ThemeNote = defineNoteConfig({
dir: 'theme/guide',
link: '/guide/',
sidebar: [

View File

@ -1,6 +1,7 @@
import type { ThemeNote } from 'vuepress-theme-plume'
import { defineNoteConfig } from 'vuepress-theme-plume'
export const tools = defineNoteConfig({
export const tools: ThemeNote = defineNoteConfig({
dir: 'tools',
link: '/tools/',
sidebar: [

View File

@ -1,3 +1,4 @@
import type { ThemeConfig } from 'vuepress-theme-plume'
import path from 'node:path'
import { defineThemeConfig } from 'vuepress-theme-plume'
import { enNavbar, zhNavbar } from './navbar.js'
@ -49,4 +50,4 @@ export default defineThemeConfig({
contentFile: path.join(__dirname, 'bulletin.md'),
enablePage: page => page.path === '/guide/features/bulletin/',
},
})
}) as ThemeConfig

View File

@ -1,4 +1,4 @@
import type { Ref } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import { onClickOutside, useDebounceFn, useEventListener, useLocalStorage } from '@vueuse/core'
import { computed, onMounted, readonly, ref, watch } from 'vue'
@ -35,7 +35,14 @@ const embedTypes: SelectItem[] = [
{ label: 'image', value: 'image' },
]
export function useCaniuseVersionSelect() {
export function useCaniuseVersionSelect(): {
past: Ref<string>
future: Ref<string>
embedType: Ref<string>
pastList: Readonly<SelectItem[]>
futureList: Readonly<SelectItem[]>
embedTypeList: Readonly<SelectItem[]>
} {
const past = ref('2')
const future = ref('1')
const embedType = ref('')
@ -57,7 +64,12 @@ export function useCaniuseVersionSelect() {
export function useCaniuseFeaturesSearch(
inputEl: Ref<HTMLInputElement | null>,
listEl: Ref<HTMLUListElement | null>,
) {
): {
featureList: Ref<Feature[] | undefined>
isFocus: Ref<boolean>
feature: ComputedRef<string>
onSelect: (item: Feature) => void
} {
const features = useLocalStorage('plume:caniuse-feature-list', [] as Feature[])
const featuresUpdated = useLocalStorage('plume:caniuse-feature-list-updated', Date.now())
const maxAge = 1000 * 60 * 60 * 24 * 3 // 3 days
@ -104,7 +116,7 @@ export function useCaniuseFeaturesSearch(
isFocus.value = true
})
function onSelect(item: Feature) {
function onSelect(item: Feature): void {
selected.value = item
isFocus.value = false
if (inputEl.value)
@ -124,7 +136,10 @@ export function useCaniuse({ feature, embedType, past, future }: {
embedType: Ref<string>
past: Ref<string>
future: Ref<string>
}) {
}): {
output: ComputedRef<string>
rendered: ComputedRef<string>
} {
const output = computed(() => {
let content = '@[caniuse'
if (embedType.value)

View File

@ -2,6 +2,8 @@ import type { InjectionKey, Ref } from 'vue'
import { useSessionStorage, useStyleTag } from '@vueuse/core'
import { inject, provide, watch } from 'vue'
declare const __VUEPRESS_DEV__: boolean
export interface ThemeColor {
name: string
key: string
@ -82,14 +84,16 @@ const preset: ThemeColorsGroup[] = [
},
]
const themeColorSymbol: InjectionKey<{
interface ThemeColorResult {
lightColors: Ref<ThemeColorsGroup[]>
darkColors: Ref<ThemeColorsGroup[]>
css: Ref<string>
reset: () => void
}> = Symbol(__VUEPRESS_DEV__ ? 'theme-color' : '')
}
export function setupThemeColors() {
const themeColorSymbol: InjectionKey<ThemeColorResult> = Symbol(__VUEPRESS_DEV__ ? 'theme-color' : '')
export function setupThemeColors(): void {
const lightColors = useSessionStorage<ThemeColorsGroup[]>('custom-theme-colors-light', resolveDefaultColors('light'))
const darkColors = useSessionStorage<ThemeColorsGroup[]>('custom-theme-colors-dark', resolveDefaultColors('dark'))
@ -138,7 +142,7 @@ function resolveDefaultColors(type: 'light' | 'dark') {
}))
}
export function useThemeColors() {
export function useThemeColors(): ThemeColorResult {
const result = inject(themeColorSymbol)
if (!result) {

View File

@ -38,4 +38,4 @@ export default defineConfig(() => {
])
}
return options
})
}) as Options[]

View File

@ -1,4 +1,4 @@
import type { MaybeRef } from 'vue'
import type { MaybeRef, Ref } from 'vue'
import { onMounted, onUnmounted, ref, toValue, watch } from 'vue'
const mimeTypes = {
@ -36,9 +36,23 @@ export interface AudioPlayerOptions {
onwaiting?: HTMLAudioElement['onwaiting']
}
interface UseAudioPlayerResult {
player: HTMLAudioElement | null
isSupported: Ref<boolean>
loaded: Ref<boolean>
paused: Ref<boolean>
currentTime: Ref<number>
duration: Ref<number>
play: () => void
pause: () => void
seek: (time: number) => void
setVolume: (volume: number) => void
destroy: () => void
}
const playerList: HTMLAudioElement[] = []
export function useAudioPlayer(source: MaybeRef<string>, options: AudioPlayerOptions = {}) {
export function useAudioPlayer(source: MaybeRef<string>, options: AudioPlayerOptions = {}): UseAudioPlayerResult {
let player: HTMLAudioElement | null = null
let unknownSupport = false
@ -194,7 +208,7 @@ export function useAudioPlayer(source: MaybeRef<string>, options: AudioPlayerOpt
return false
}
function destroy() {
function destroy(): void {
player?.pause()
player?.remove()
playerList.splice(playerList.indexOf(player!), 1)

View File

@ -38,7 +38,10 @@ export function resolveCode(el: HTMLElement): string {
return clone.textContent || ''
}
export function resolveCodeInfo(el: HTMLDivElement) {
export function resolveCodeInfo(el: HTMLDivElement): {
lang: Lang
code: string
} {
const wrapper = el.querySelector('div[class*=language-]')
const lang = wrapper?.className.match(RE_LANGUAGE)?.[1]
const codeEl = wrapper?.querySelector('pre') as HTMLElement
@ -50,7 +53,20 @@ export function resolveCodeInfo(el: HTMLDivElement) {
return { lang: resolveLang(lang) as Lang, code }
}
export function useCodeRepl(el: Ref<HTMLDivElement | null>) {
interface UseCodeReplResult {
lang: Ref<Lang | undefined>
loaded: Ref<boolean>
firstRun: Ref<boolean>
finished: Ref<boolean>
stdout: Ref<string[]>
stderr: Ref<string[]>
error: Ref<string>
backendVersion: Ref<string>
onCleanRun: () => void
onRunCode: () => Promise<void>
}
export function useCodeRepl(el: Ref<HTMLDivElement | null>): UseCodeReplResult {
const lang = ref<Lang>()
const loaded = ref(true)
const firstRun = ref(true)
@ -74,7 +90,7 @@ export function useCodeRepl(el: Ref<HTMLDivElement | null>) {
rust: executeRust,
}
function onCleanRun() {
function onCleanRun(): void {
loaded.value = false
finished.value = false
stdout.value = []
@ -84,7 +100,7 @@ export function useCodeRepl(el: Ref<HTMLDivElement | null>) {
backendVersion.value = ''
}
async function onRunCode() {
async function onRunCode(): Promise<void> {
if (!el.value || !loaded.value)
return
const info = resolveCodeInfo(el.value)

View File

@ -1,4 +1,4 @@
import type { MaybeRefOrGetter, ShallowRef } from 'vue'
import type { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue'
import { onClickOutside, useEventListener } from '@vueuse/core'
import { computed, getCurrentInstance, onMounted, ref, toValue, useId, watch } from 'vue'
import { isPlainObject } from 'vuepress/shared'
@ -11,7 +11,7 @@ export interface DemoConfig {
cssLib: string[]
}
export function useExpand(defaultExpand = true) {
export function useExpand(defaultExpand = true): readonly [Ref<boolean>, () => void] {
const expanded = ref(defaultExpand)
function toggle() {
expanded.value = !expanded.value
@ -19,11 +19,24 @@ export function useExpand(defaultExpand = true) {
return [expanded, toggle] as const
}
export function useResources(el: ShallowRef<HTMLDivElement | null>, config: MaybeRefOrGetter<DemoConfig | undefined>) {
const resources = computed<{
name: string
items: { name: string, url: string }[]
}[]>(() => {
interface ResourceItem {
name: string
items: SubResourceItem[]
}
interface SubResourceItem {
name: string
url: string
}
interface UseResourcesResult {
resources: ComputedRef<ResourceItem[]>
showResources: Ref<boolean>
toggleResources: () => void
}
export function useResources(el: ShallowRef<HTMLDivElement | null>, config: MaybeRefOrGetter<DemoConfig | undefined>): UseResourcesResult {
const resources = computed<ResourceItem[]>(() => {
const conf = toValue(config)
if (!conf)
return []
@ -39,7 +52,7 @@ export function useResources(el: ShallowRef<HTMLDivElement | null>, config: Mayb
const showResources = ref(false)
function toggleResources() {
function toggleResources(): void {
showResources.value = !showResources.value
}
@ -54,14 +67,16 @@ export function useResources(el: ShallowRef<HTMLDivElement | null>, config: Mayb
}
}
export function useFence(fence: ShallowRef<HTMLDivElement | null>, config: MaybeRefOrGetter<DemoConfig | undefined>) {
const data = ref<{
js: string
css: string
html: string
jsType: string
cssType: string
}>({ js: '', css: '', html: '', jsType: '', cssType: '' })
interface FenceData {
js: string
css: string
html: string
jsType: string
cssType: string
}
export function useFence(fence: ShallowRef<HTMLDivElement | null>, config: MaybeRefOrGetter<DemoConfig | undefined>): Ref<FenceData> {
const data = ref<FenceData>({ js: '', css: '', html: '', jsType: '', cssType: '' })
onMounted(() => {
if (!fence.value)
@ -93,7 +108,7 @@ export function useNormalDemo(
draw: ShallowRef<HTMLIFrameElement | null>,
title: MaybeRefOrGetter<string | undefined>,
config: MaybeRefOrGetter<DemoConfig | undefined>,
) {
): { id: string, height: Ref<string> } {
const current = getCurrentInstance()
const id = useId()
const isDark = computed(() => current?.appContext.config.globalProperties.$isDark.value)
@ -157,7 +172,7 @@ function createHTMLTemplate(title: string, id: string, config?: DemoConfig): str
</html>`
}
export function parseData(data: any) {
export function parseData(data: any): any {
try {
if (typeof data === 'string') {
return JSON.parse(data)

View File

@ -66,7 +66,7 @@ function send(type: string, payload: Record<string, any>, meta: Record<string, a
export async function rustExecute(
code: string,
{ onEnd, onError, onStderr, onStdout, onBegin }: RustExecuteOptions,
) {
): Promise<void> {
await connect()
const meta = { sequenceNumber: uuid++ }
const payload = {

View File

@ -5,15 +5,19 @@ declare const __MD_POWER_DASHJS_INSTALLED__: boolean
declare const __MD_POWER_HLSJS_INSTALLED__: boolean
declare const __MD_POWER_MPEGTSJS_INSTALLED__: boolean
export const pluginOptions = __MD_POWER_INJECT_OPTIONS__
export const pluginOptions: MarkdownPowerPluginOptions = __MD_POWER_INJECT_OPTIONS__
export const installed = {
export const installed: {
dashjs: boolean
hlsjs: boolean
mpegtsjs: boolean
} = {
dashjs: __MD_POWER_DASHJS_INSTALLED__,
hlsjs: __MD_POWER_HLSJS_INSTALLED__,
mpegtsjs: __MD_POWER_MPEGTSJS_INSTALLED__,
}
export const ART_PLAYER_SUPPORTED_VIDEO_TYPES = ['mp4', 'mp3', 'webm', 'ogg']
export const ART_PLAYER_SUPPORTED_VIDEO_TYPES: string[] = ['mp4', 'mp3', 'webm', 'ogg']
if (installed.dashjs) {
ART_PLAYER_SUPPORTED_VIDEO_TYPES.push('mpd', 'dash')
@ -27,10 +31,10 @@ if (installed.mpegtsjs) {
ART_PLAYER_SUPPORTED_VIDEO_TYPES.push('ts', 'flv')
}
export const INJECT_TIMELINE_KEY = Symbol(
export const INJECT_TIMELINE_KEY: symbol = Symbol(
__VUEPRESS_DEV__ ? 'timeline' : '',
)
export const INJECT_COLLAPSE_KEY = Symbol(
export const INJECT_COLLAPSE_KEY: symbol = Symbol(
__VUEPRESS_DEV__ ? 'collapse' : '',
)

View File

@ -13,7 +13,7 @@ interface CardMasonryAttrs {
gap?: number
}
export function cardPlugin(md: Markdown) {
export function cardPlugin(md: Markdown): void {
/**
* ::: card title="xxx" icon="xxx"
* xxx

View File

@ -111,7 +111,7 @@ function parseFileNodes(files: string[]): FileTreeNode[] {
return nodes
}
export function codeTreePlugin(md: Markdown, app: App, options: CodeTreeOptions = {}) {
export function codeTreePlugin(md: Markdown, app: App, options: CodeTreeOptions = {}): void {
const getIcon = (filename: string, type: 'folder' | 'file', mode?: FileTreeIconMode): string => {
mode ||= options.icon || 'colored'
if (mode === 'simple')

View File

@ -15,7 +15,7 @@ export function createContainerPlugin(
md: Markdown,
type: string,
{ before, after }: ContainerOptions = {},
) {
): void {
const render: RenderRule = (tokens, index, options, env): string => {
const token = tokens[index]
const info = token.info.trim().slice(type.length).trim() || ''
@ -51,7 +51,7 @@ export function createContainerSyntaxPlugin(
md: Markdown,
type: string,
render?: RenderRule,
) {
): void {
const maker = ':'
const markerMinLen = 3

View File

@ -12,7 +12,7 @@ interface FieldAttrs {
default?: string
}
export function fieldPlugin(md: Markdown) {
export function fieldPlugin(md: Markdown): void {
createContainerPlugin(md, 'field', {
before: (info) => {
const { attrs } = resolveAttrs<FieldAttrs>(info)

View File

@ -94,7 +94,7 @@ export function parseFileTreeNodeInfo(info: string): FileTreeNodeProps {
return { filename, comment, focus, expanded, type, diff }
}
export function fileTreePlugin(md: Markdown, options: FileTreeOptions = {}) {
export function fileTreePlugin(md: Markdown, options: FileTreeOptions = {}): void {
const getIcon = (filename: string, type: 'folder' | 'file', mode?: FileTreeIconMode): string => {
mode ||= options.icon || 'colored'
if (mode === 'simple')

View File

@ -21,7 +21,7 @@ export async function containerPlugin(
app: App,
md: Markdown,
options: MarkdownPowerPluginOptions,
) {
): Promise<void> {
// ::: left / right / center / justify
alignPlugin(md)
// ::: tabs

View File

@ -18,7 +18,7 @@ export async function langReplPlugin(app: App, md: markdownIt, {
go = false,
kotlin = false,
rust = false,
}: ReplOptions) {
}: ReplOptions): Promise<void> {
const container = (lang: string): void => createContainerPlugin(md, `${lang}-repl`, {
before(info) {
const { attrs } = resolveAttrs<CodeReplMeta>(info)

View File

@ -10,7 +10,7 @@ import { createContainerPlugin } from './createContainer.js'
* 3. ...
* :::
*/
export function stepsPlugin(md: Markdown) {
export function stepsPlugin(md: Markdown): void {
createContainerPlugin(md, 'steps', {
before: () => '<div class="vp-steps">',
})

View File

@ -40,7 +40,7 @@ const RE_KEY = /(\w+)=\s*/
const RE_SEARCH_KEY = /\s+\w+=\s*|$/
const RE_CLEAN_VALUE = /(?<quote>["'])(.*?)(\k<quote>)/
export function timelinePlugin(md: Markdown) {
export function timelinePlugin(md: Markdown): void {
createContainerPlugin(md, 'timeline', {
before(info, tokens, index) {
parseTimeline(tokens, index)

View File

@ -11,7 +11,7 @@ import { normalContainerRender, normalEmbed } from './normal.js'
import { normalizeAlias } from './supports/alias.js'
import { vueContainerRender, vueEmbed } from './vue.js'
export function demoEmbed(app: App, md: Markdown) {
export function demoEmbed(app: App, md: Markdown): void {
createEmbedRuleBlock<DemoMeta>(md, {
type: 'demo',
syntaxPattern: /^@\[demo(?:\s(vue|normal|markdown))?\s?(.*)\]\((.*)\)/,
@ -50,7 +50,7 @@ const renderMap: Record<string, DemoContainerRender> = {
markdown: markdownContainerRender,
}
export function demoContainer(app: App, md: Markdown) {
export function demoContainer(app: App, md: Markdown): void {
let currentRender: DemoContainerRender | undefined
const render: RenderRule = (
tokens: Token[],

View File

@ -3,7 +3,7 @@ import type { Markdown } from 'vuepress/markdown'
import { demoContainer, demoEmbed } from './demo.js'
import { createDemoRender } from './watcher.js'
export function demoPlugin(app: App, md: Markdown) {
export function demoPlugin(app: App, md: Markdown): void {
createDemoRender()
demoEmbed(app, md)
demoContainer(app, md)

View File

@ -67,7 +67,7 @@ function codeToHtml(md: Markdown, source: NormalCode, info: string): string {
return md.render(content, {})
}
export async function compileCode(code: NormalCode, output: string) {
export async function compileCode(code: NormalCode, output: string): Promise<void> {
markDemoRender()
const res = { jsLib: [], cssLib: [], script: '', css: '', html: '' }
if (!fs.existsSync(output))

View File

@ -2,7 +2,7 @@ import type { DemoFile, MarkdownDemoEnv } from '../../../shared/demo.js'
const SCRIPT_RE = /<script.*?>/
export function insertSetupScript({ export: name, path }: DemoFile, env: MarkdownDemoEnv) {
export function insertSetupScript({ export: name, path }: DemoFile, env: MarkdownDemoEnv): void {
const imports = `import ${name ? `${name} from ` : ''}'${path}';`
const scriptSetup = env.sfcBlocks!.scriptSetup ??= {
type: 'script',

View File

@ -14,13 +14,13 @@ let renderDone: null | ((...args: any[]) => void) = null
let renderCount = 0
let renderPromise!: Promise<void>
export function createDemoRender() {
export function createDemoRender(): void {
renderPromise = new Promise((resolve) => {
renderDone = resolve
})
}
export async function waitDemoRender() {
export async function waitDemoRender(): Promise<void> {
if (renderCount === 0) {
renderDone?.()
renderDone = null
@ -28,11 +28,11 @@ export async function waitDemoRender() {
await renderPromise
}
export function markDemoRender() {
export function markDemoRender(): void {
renderCount++
}
export function checkDemoRender() {
export function checkDemoRender(): void {
if (renderCount > 0) {
renderCount--
}
@ -47,7 +47,7 @@ let watcher: FSWatcher | null = null
const tasks: Record<string, string> = {}
const target = 'md-power/demo/watcher.txt'
export function demoWatcher(app: App, watchers: any[]) {
export function demoWatcher(app: App, watchers: any[]): void {
if (!watcher) {
watcher = watch([], { ignoreInitial: true })
}
@ -89,7 +89,7 @@ export function demoWatcher(app: App, watchers: any[]) {
})
}
export function addTask(app: App, path: string, output: string) {
export function addTask(app: App, path: string, output: string): void {
if (tasks[path])
return
tasks[path] = output

View File

@ -11,7 +11,7 @@ import { artPlayerPlugin } from './video/artPlayer.js'
import { bilibiliPlugin } from './video/bilibili.js'
import { youtubePlugin } from './video/youtube.js'
export function embedSyntaxPlugin(md: Markdown, options: MarkdownPowerPluginOptions) {
export function embedSyntaxPlugin(md: Markdown, options: MarkdownPowerPluginOptions): void {
if (options.caniuse) {
const caniuse = options.caniuse === true ? {} : options.caniuse
// @[caniuse](feature_name)

View File

@ -32,7 +32,7 @@ export async function imageSizePlugin(
app: App,
md: Markdown,
type: boolean | 'local' | 'all' = false,
) {
): Promise<void> {
if (!app.env.isBuild || !type)
return
@ -159,7 +159,7 @@ function resolveImageUrl(src: string, env: MarkdownEnv, app: App): string {
return path.resolve(src)
}
export async function scanRemoteImageSize(app: App) {
export async function scanRemoteImageSize(app: App): Promise<void> {
if (!app.env.isBuild)
return
const cwd = app.dir.source()

View File

@ -10,7 +10,7 @@ const CLIENT_FOLDER = ensureEndingSlash(
path.resolve(__dirname, '../client'),
)
export async function prepareConfigFile(app: App, options: MarkdownPowerPluginOptions) {
export async function prepareConfigFile(app: App, options: MarkdownPowerPluginOptions): Promise<string> {
const imports = new Set<string>()
const enhances = new Set<string>()

View File

@ -1,3 +1,3 @@
import { customAlphabet } from 'nanoid'
export const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 5)
export const nanoid: (size?: number) => string = customAlphabet('abcdefghijklmnopqrstuvwxyz', 5)

View File

@ -51,4 +51,4 @@ export default defineConfig(() => {
}) as Options))
}
return options
})
}) as Options[]

View File

@ -1,6 +1,6 @@
export const PLUGIN_NAME = 'vuepress-plugin-replace-assets'
export const KNOWN_IMAGE_EXTENSIONS = [
export const KNOWN_IMAGE_EXTENSIONS: string[] = [
'png',
'jpg',
'jpeg',
@ -10,7 +10,7 @@ export const KNOWN_IMAGE_EXTENSIONS = [
'avif',
]
export const KNOWN_MEDIA_EXTENSIONS = [
export const KNOWN_MEDIA_EXTENSIONS: string[] = [
'mp4',
'webm',
'ogg',
@ -25,7 +25,7 @@ export const KNOWN_MEDIA_EXTENSIONS = [
'pdf',
]
export const KNOWN_ASSET_EXTENSIONS = [
export const KNOWN_ASSET_EXTENSIONS: string[] = [
...KNOWN_IMAGE_EXTENSIONS,
...KNOWN_MEDIA_EXTENSIONS,
]

View File

@ -1,10 +1,18 @@
import type { VitePlugin, WebpackPluginInstance } from 'unplugin'
import type { ReplacementRule } from '../options.js'
import {
createVitePlugin as _createVitePlugin,
createWebpackPlugin as _createWebpackPlugin,
} from 'unplugin'
import { unpluginFactory } from './factory.js'
export const createVitePlugin = () => _createVitePlugin(unpluginFactory)
export const createWebpackPlugin = () => _createWebpackPlugin(unpluginFactory)
export const createVitePlugin: () => (
options: ReplacementRule[]
) => VitePlugin<any> | VitePlugin<any>[] = () => _createVitePlugin(unpluginFactory)
export const createWebpackPlugin: () => (
options: ReplacementRule[]
) => WebpackPluginInstance = () => _createWebpackPlugin(unpluginFactory)
export * from './transform.js'

View File

@ -1,6 +1,6 @@
import { removeEndingSlash, removeLeadingSlash } from '@vuepress/helper'
export function createAssetPattern(prefix: string) {
export function createAssetPattern(prefix: string): RegExp {
const s = `(${prefix}.*?)`
return new RegExp(
[
@ -17,7 +17,7 @@ export function createAssetPattern(prefix: string) {
const htmlLangRE = /\.(?:html|htm)$/
export const isHTMLRequest = (request: string) => htmlLangRE.test(request)
export const isHTMLRequest = (request: string): boolean => htmlLangRE.test(request)
const nonJsRe = /\.json(?:$|\?)/

View File

@ -21,4 +21,4 @@ export default defineConfig(() => {
}
return options
})
}) as Options[]

View File

@ -1,5 +1,5 @@
import type { MaybeRef } from 'vue'
import type { SearchBoxLocales } from '../../shared/index.js'
import type { ComputedRef, MaybeRef } from 'vue'
import type { SearchBoxLocales, SearchLocaleOptions } from '../../shared/index.js'
import { computed, toRef } from 'vue'
import { useRouteLocale } from 'vuepress/client'
@ -21,7 +21,7 @@ const defaultLocales: SearchBoxLocales = {
},
}
export function useLocale(locales: MaybeRef<SearchBoxLocales>) {
export function useLocale(locales: MaybeRef<SearchBoxLocales>): ComputedRef<Partial<SearchLocaleOptions>> {
const localesRef = toRef(locales)
const routeLocale = useRouteLocale()

View File

@ -1,11 +1,14 @@
import type { ShallowRef } from 'vue'
import { searchIndex } from '@internal/minisearchIndex'
import { shallowRef } from 'vue'
declare const __VUE_HMR_RUNTIME__: Record<string, any>
const searchIndexData = shallowRef(searchIndex)
type SearchIndexData = Record<string, () => Promise<{ default: string }>>
export function useSearchIndex() {
const searchIndexData = shallowRef<SearchIndexData>(searchIndex)
export function useSearchIndex(): ShallowRef<SearchIndexData> {
return searchIndexData
}

View File

@ -47,7 +47,7 @@ export async function prepareSearchIndex({
app,
isSearchable,
searchOptions,
}: SearchIndexOptions) {
}: SearchIndexOptions): Promise<void> {
const start = performance.now()
const pages = isSearchable ? app.pages.filter(isSearchable) : app.pages
await pMap(pages, p => indexFile(p, searchOptions), {
@ -69,7 +69,7 @@ export async function onSearchIndexUpdated(
isSearchable,
searchOptions,
}: SearchIndexOptions,
) {
): Promise<void> {
const pages = isSearchable ? app.pages.filter(isSearchable) : app.pages
if (pages.some(p => p.filePathRelative?.endsWith(filepath))) {
await indexFile(app.pages.find(p => p.filePathRelative?.endsWith(filepath))!, searchOptions)
@ -84,7 +84,7 @@ export async function onSearchIndexRemoved(
isSearchable,
searchOptions,
}: SearchIndexOptions,
) {
): Promise<void> {
const pages = isSearchable ? app.pages.filter(isSearchable) : app.pages
if (pages.some(p => p.filePathRelative?.endsWith(filepath))) {
const page = app.pages.find(p => p.filePathRelative?.endsWith(filepath))!

View File

@ -78,4 +78,4 @@ export default defineConfig(() => {
}
return options
})
}) as Options[]

View File

@ -1,12 +1,12 @@
<script setup lang="ts">
import type { BlogCategoryItem } from '../../composables/index.js'
import type { CategoryItem } from '../../composables/index.js'
import VPCategories from '@theme/Blog/VPCategories.vue'
import { computed, onMounted, ref, watch } from 'vue'
import { useRoute } from 'vuepress/client'
import { useData } from '../../composables/index.js'
const props = withDefaults(defineProps<{
item: BlogCategoryItem
item: CategoryItem
depth?: number
}>(), {
depth: 0,
@ -42,7 +42,7 @@ watch(
{ immediate: true },
)
function hasExpand(item: BlogCategoryItem, id: string) {
function hasExpand(item: CategoryItem, id: string) {
return item.id === id
|| item.items.filter(item => item.type === 'category').some(item => hasExpand(item, id))
}

View File

@ -25,7 +25,7 @@ const styles = computed(() => {
<script lang="ts">
export default {
inheritAttrs: false,
}
} as { inheritAttrs: boolean }
</script>
<template>

View File

@ -1,8 +1,11 @@
import type { ComputedRef } from 'vue'
import { useMediaQuery } from '@vueuse/core'
import { computed } from 'vue'
import { useSidebar } from './sidebar.js'
export function useAside() {
export function useAside(): {
isAsideEnabled: ComputedRef<boolean>
} {
const { hasSidebar } = useSidebar()
const is960 = useMediaQuery('(min-width: 960px)')
const is1280 = useMediaQuery('(min-width: 1280px)')

View File

@ -1,3 +1,4 @@
import type { ComputedRef } from 'vue'
import type { ThemeBlogPostItem } from '../../shared/index.js'
import { computed } from 'vue'
import { useLocalePostList } from './blog-data.js'
@ -6,12 +7,18 @@ import { useThemeData } from './theme-data.js'
export type ShortPostItem = Pick<ThemeBlogPostItem, 'title' | 'path' | 'createTime'>
export function useArchives() {
interface ArchiveItem {
title: string
label: string
list: ShortPostItem[]
}
export function useArchives(): { archives: ComputedRef<ArchiveItem[]> } {
const themeData = useThemeData()
const list = useLocalePostList()
const { theme } = useData()
const archives = computed(() => {
const archives = computed<ArchiveItem[]>(() => {
const archives: { title: string, label: string, list: ShortPostItem[] }[] = []
const countLocale = theme.value.archiveTotalText || themeData.value.archiveTotalText

View File

@ -1,3 +1,4 @@
import type { ComputedRef } from 'vue'
import { computed } from 'vue'
import { useLocalePostList } from './blog-data.js'
@ -17,10 +18,10 @@ export interface CategoryItem {
export type BlogCategory = (CategoryItem | CategoryItemWithPost)[]
export function useBlogCategory() {
export function useBlogCategory(): { categories: ComputedRef<BlogCategory> } {
const postList = useLocalePostList()
const categories = computed(() => {
const categories = computed<BlogCategory>(() => {
const list: BlogCategory = []
postList.value.forEach((item) => {

View File

@ -1,4 +1,4 @@
import type { Ref } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import type { ThemeBlogPostList } from '../../shared/index.js'
import {
blogPostData as blogPostDataRaw,
@ -14,7 +14,7 @@ export function usePostList(): BlogDataRef {
return blogPostData as BlogDataRef
}
export function useLocalePostList() {
export function useLocalePostList(): ComputedRef<ThemeBlogPostList> {
const locale = usePageLang()
return computed(() => blogPostData.value.filter(item => item.lang === locale.value))
}

View File

@ -1,3 +1,4 @@
import type { ComputedRef } from 'vue'
import type { BlogCategory } from './blog-category.js'
import { computed } from 'vue'
import { useBlogCategory } from './blog-category.js'
@ -6,32 +7,43 @@ import { useTags } from './blog-tags.js'
import { useData } from './data.js'
import { useInternalLink } from './internal-link.js'
export function useBlogExtract() {
interface BlogExtractLink {
link?: string
text?: string
total: number
}
export function useBlogExtract(): {
hasBlogExtract: ComputedRef<boolean>
tags: ComputedRef<BlogExtractLink>
archives: ComputedRef<BlogExtractLink>
categories: ComputedRef<BlogExtractLink>
} {
const { blog } = useData()
const postList = useLocalePostList()
const { tags: tagsList } = useTags()
const { categories: categoryList } = useBlogCategory()
const links = useInternalLink()
const hasBlogExtract = computed(() =>
const hasBlogExtract = computed<boolean>(() =>
blog.value.archives !== false
|| blog.value.tags !== false
|| blog.value.categories !== false,
)
const tags = computed(() => ({
const tags = computed<BlogExtractLink>(() => ({
link: links.tags.value?.link,
text: links.tags.value?.text,
total: tagsList.value.length,
}))
const archives = computed(() => ({
const archives = computed<BlogExtractLink>(() => ({
link: links.archive.value?.link,
text: links.archive.value?.text,
total: postList.value.length,
}))
const categories = computed(() => ({
const categories = computed<BlogExtractLink>(() => ({
link: links.categories.value?.link,
text: links.categories.value?.text,
total: getCategoriesTotal(categoryList.value),

View File

@ -1,4 +1,4 @@
import type { Ref } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import type { ThemeBlogPostItem } from '../../shared/index.js'
import { useMediaQuery } from '@vueuse/core'
import { computed } from 'vue'
@ -8,7 +8,21 @@ import { useRouteQuery } from './route-query.js'
const DEFAULT_PER_PAGE = 15
export function usePostListControl(homePage: Ref<boolean>) {
interface UsePostListControlResult {
postList: ComputedRef<ThemeBlogPostItem[]>
page: Ref<number>
totalPage: ComputedRef<number>
pageRange: ComputedRef<{
value: number | string
more?: true
}[]>
isLastPage: ComputedRef<boolean>
isFirstPage: ComputedRef<boolean>
isPaginationEnabled: ComputedRef<boolean>
changePage: (page: number) => void
}
export function usePostListControl(homePage: Ref<boolean>): UsePostListControlResult {
const { blog } = useData()
const list = useLocalePostList()
@ -113,7 +127,7 @@ export function usePostListControl(homePage: Ref<boolean>) {
return range
})
const changePage = (current: number) => {
const changePage = (current: number): void => {
if (page.value === current)
return
page.value = current

View File

@ -1,3 +1,4 @@
import type { ComputedRef, Ref } from 'vue'
import type { ThemeBlogPostItem } from '../../shared/index.js'
import { computed } from 'vue'
import { toArray } from '../utils/index.js'
@ -8,13 +9,26 @@ import { useTagColors } from './tag-colors.js'
type ShortPostItem = Pick<ThemeBlogPostItem, 'title' | 'path' | 'createTime'>
export function useTags() {
interface BlogTagItem {
name: string
count: string | number
className: string
}
interface UseTagsResult {
tags: ComputedRef<BlogTagItem[]>
currentTag: Ref<string>
postList: ComputedRef<ShortPostItem[]>
handleTagClick: (tag: string) => void
}
export function useTags(): UseTagsResult {
const { blog } = useData()
const list = useLocalePostList()
const colors = useTagColors()
const tags = computed(() => {
const tags = computed<BlogTagItem[]>(() => {
const tagTheme = blog.value.tagsTheme ?? 'colored'
const tagMap: Record<string, number> = {}
@ -53,7 +67,7 @@ export function useTags() {
}))
})
const handleTagClick = (tag: string) => {
const handleTagClick = (tag: string): void => {
currentTag.value = tag
}

View File

@ -6,11 +6,13 @@ import { isPlainObject } from 'vuepress/shared'
import { useData } from '../composables/data.js'
import { useThemeData } from './theme-data.js'
export function useContributors(): {
interface useContributorsResult {
mode: ComputedRef<'inline' | 'block'>
contributors: ComputedRef<GitContributor[]>
hasContributors: ComputedRef<boolean>
} {
}
export function useContributors(): useContributorsResult {
const { frontmatter } = useData()
const list = _useContributors()

View File

@ -1,5 +1,11 @@
import type { ComputedRef } from 'vue'
import type { CopyrightFrontmatter, CopyrightLicense, CopyrightOptions, GitContributor, KnownCopyrightLicense } from '../../shared/index.js'
import type {
CopyrightFrontmatter,
CopyrightLicense,
CopyrightOptions,
GitContributor,
KnownCopyrightLicense,
} from '../../shared/index.js'
import { computed } from 'vue'
import { useRouteLocale } from 'vuepress/client'
import { useContributors } from './contributors.js'
@ -37,7 +43,18 @@ const LICENSE_URL: Record<KnownCopyrightLicense, { url: string, icons: string[]
},
}
export function useCopyright(copyright: ComputedRef<CopyrightFrontmatter>) {
interface useCopyrightResult {
license: ComputedRef<License>
author: ComputedRef<Exclude<CopyrightFrontmatter['author'], string>>
hasCopyright: ComputedRef<boolean>
creation: ComputedRef<CopyrightFrontmatter['creation']>
creationText: ComputedRef<string>
sourceUrl: ComputedRef<string | undefined>
}
export function useCopyright(
copyright: ComputedRef<CopyrightFrontmatter>,
): useCopyrightResult {
const { theme } = useData<'post'>()
const routeLocale = useRouteLocale()
const { contributors } = useContributors()

View File

@ -9,7 +9,7 @@ export const darkModeSymbol: InjectionKey<DarkModeRef> = Symbol(
__VUEPRESS_DEV__ ? 'darkMode' : '',
)
export function enableTransitions() {
export function enableTransitions(): boolean {
if (typeof document === 'undefined')
return false
return 'startViewTransition' in document

View File

@ -81,7 +81,7 @@ function toMatch(match: string, pagePath: string, filePathRelative: string | nul
return pagePath.startsWith(match) || relativePath.startsWith(match)
}
export function setupEncrypt() {
export function setupEncrypt(): void {
const { page } = useData()
const route = useRoute()
const encrypt = useEncryptData()
@ -148,13 +148,16 @@ export function useEncrypt(): Encrypt {
return result
}
export function useEncryptCompare() {
export function useEncryptCompare(): {
compareGlobal: (password: string) => Promise<boolean>
comparePage: (password: string) => Promise<boolean>
} {
const encrypt = useEncryptData()
const { page } = useData()
const route = useRoute()
const { hashList } = useEncrypt()
async function compareGlobal(password: string) {
async function compareGlobal(password: string): Promise<boolean> {
if (!password)
return false
@ -168,7 +171,7 @@ export function useEncryptCompare() {
return false
}
async function comparePage(password: string) {
async function comparePage(password: string): Promise<boolean> {
if (!password)
return false

View File

@ -8,12 +8,12 @@ interface UseFlyoutOptions {
onBlur?: () => void
}
export const focusedElement = ref<HTMLElement>()
export const focusedElement: Ref<HTMLElement | undefined> = ref()
let active = false
let listeners = 0
export function useFlyout(options: UseFlyoutOptions) {
export function useFlyout(options: UseFlyoutOptions): Readonly<Ref<boolean>> {
const focus = ref(false)
if (inBrowser) {

View File

@ -25,7 +25,7 @@ export function useHomeHeroTintPlate(
canvas: Ref<HTMLCanvasElement | undefined>,
enable: Ref<boolean>,
tintPlate: Ref<ThemeHomeHero['tintPlate']>,
) {
): void {
const isDark = useDarkMode()
let ctx: CanvasRenderingContext2D | null = null

View File

@ -1,3 +1,4 @@
import type { ComputedRef } from 'vue'
import type { PresetLocale } from '../../shared/index.js'
import { computed } from 'vue'
import { useRouteLocale } from 'vuepress/client'
@ -9,7 +10,13 @@ export interface InternalLink {
link: string
}
export function useInternalLink() {
export function useInternalLink(): {
home: ComputedRef<InternalLink>
blog: ComputedRef<InternalLink>
tags: ComputedRef<InternalLink | undefined>
archive: ComputedRef<InternalLink | undefined>
categories: ComputedRef<InternalLink | undefined>
} {
const { blog, theme } = useData()
const themeData = useThemeData()
const routeLocale = useRouteLocale()

View File

@ -1,3 +1,4 @@
import type { ComputedRef } from 'vue'
import { computed } from 'vue'
import { resolveRoute, useRouteLocale } from 'vuepress/client'
import { removeLeadingSlash } from 'vuepress/shared'
@ -6,9 +7,23 @@ import { useData } from './data.js'
import { useBlogPageData } from './page.js'
import { useThemeData } from './theme-data.js'
interface Lang {
label?: string
link: string
}
interface UseLangOptions {
removeCurrent?: boolean
}
interface UseLangResult {
localeLinks: ComputedRef<Lang[]>
currentLang: ComputedRef<Lang>
}
export function useLangs({
removeCurrent = true,
} = {}) {
}: UseLangOptions = {}): UseLangResult {
const theme = useThemeData()
const { page } = useData()
const routeLocale = useRouteLocale()

View File

@ -1,9 +1,14 @@
import type { ComputedRef, Ref } from 'vue'
import { computed, onMounted, ref, watchEffect } from 'vue'
import { usePageLang } from 'vuepress/client'
import { useData } from './data.js'
import { useThemeData } from './theme-data.js'
export function useLastUpdated() {
export function useLastUpdated(): {
datetime: Ref<string>
isoDatetime: ComputedRef<string | undefined>
lastUpdatedText: ComputedRef<string>
} {
const { theme, page, frontmatter } = useData()
const themeData = useThemeData()
const lang = usePageLang()

View File

@ -1,13 +1,18 @@
import type { MaybeRefOrGetter } from 'vue'
import type { ComputedRef, MaybeRefOrGetter } from 'vue'
import { isLinkExternal } from '@vuepress/helper/client'
import { computed, toValue } from 'vue'
import { resolveRouteFullPath, useRoute } from 'vuepress/client'
import { useData } from './data.js'
interface UseLinkResult {
isExternal: ComputedRef<boolean>
link: ComputedRef<string | undefined>
}
export function useLink(
href: MaybeRefOrGetter<string | undefined>,
target?: MaybeRefOrGetter<string | undefined>,
) {
): UseLinkResult {
const route = useRoute()
const { page } = useData()

View File

@ -1,8 +1,12 @@
import type { ComputedRef } from 'vue'
import { computed } from 'vue'
import { usePostList } from './blog-data.js'
import { useData } from './data.js'
export function useBlogPageData() {
export function useBlogPageData(): {
isBlogPost: ComputedRef<boolean>
isBlogLayout: ComputedRef<boolean>
} {
const { page } = useData()
const postList = usePostList()

View File

@ -1,9 +1,13 @@
import type { PresetLocale } from '../../shared/index.js'
declare const __PLUME_PRESET_LOCALE__: Record<string, PresetLocale>
interface PresetLocales {
[locale: string]: PresetLocale
}
export const presetLocales = __PLUME_PRESET_LOCALE__
declare const __PLUME_PRESET_LOCALE__: PresetLocales
export function getPresetLocaleData(locale: string, name: keyof PresetLocale) {
export const presetLocales: PresetLocales = __PLUME_PRESET_LOCALE__
export function getPresetLocaleData(locale: string, name: keyof PresetLocale): string {
return presetLocales[locale]?.[name] || presetLocales['/'][name]
}

View File

@ -1,4 +1,4 @@
import type { Ref } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import type { NavItemWithLink, ThemeBlogPostItem, ThemeSidebarItem } from '../../shared/index.js'
import { computed } from 'vue'
import { resolveRouteFullPath, usePageLang, useRoute } from 'vuepress/client'
@ -9,7 +9,12 @@ import { useData } from './data.js'
import { useBlogPageData } from './page.js'
import { useSidebar } from './sidebar.js'
export function usePrevNext() {
interface UsePrevNextResult {
prev: ComputedRef<NavItemWithLink | null>
next: ComputedRef<NavItemWithLink | null>
}
export function usePrevNext(): UsePrevNextResult {
const route = useRoute()
const { frontmatter, theme } = useData()
const { sidebar } = useSidebar()

View File

@ -3,7 +3,7 @@ import { nextTick } from 'vue'
import { inBrowser } from '../utils/index.js'
import { useScrollPromise } from './scroll-promise.js'
export function enhanceScrollBehavior(router: Router) {
export function enhanceScrollBehavior(router: Router): void {
router.options.scrollBehavior = async (to, from, savedPosition) => {
await useScrollPromise().wait()
if (savedPosition)

View File

@ -52,7 +52,7 @@ const sidebarSymbol: InjectionKey<Ref<ResolvedSidebarItem[]>> = Symbol(
__VUEPRESS_DEV__ ? 'sidebar' : '',
)
export function setupSidebar() {
export function setupSidebar(): void {
const { page, frontmatter } = useData()
const routeLocale = useRouteLocale()

View File

@ -52,7 +52,7 @@ function resolveThemeLocaleData(theme: ThemeData, routeLocale: RouteLocale): The
}
}
export function setupThemeData(app: App) {
export function setupThemeData(app: App): void {
// provide theme data & theme locale data
const themeData = useThemeData()
const clientData: ClientData

View File

@ -1,3 +1,4 @@
import type { ClientConfig } from 'vuepress/client'
import { defineClientConfig } from 'vuepress/client'
import {
enhanceScrollBehavior,
@ -28,4 +29,4 @@ export default defineClientConfig({
setupWatermark()
},
layouts: { Layout, NotFound },
})
}) as ClientConfig

View File

@ -1,7 +1,12 @@
import type { MaybeRef } from 'vue'
import type { MaybeRef, Ref } from 'vue'
import { useLocalStorage } from '@vueuse/core'
import { computed, ref, toValue, watch } from 'vue'
interface GithubRepoLicense {
name: string
url: string
}
export interface GithubRepoInfo {
name: string
fullName: string
@ -17,10 +22,7 @@ export interface GithubRepoInfo {
visibility: 'Private' | 'Public' // private, public
template: boolean
ownerType: 'User' | 'Organization'
license: {
name: string
url: string
} | null
license: GithubRepoLicense | null
}
/**
@ -32,7 +34,12 @@ const storage = useLocalStorage('__VUEPRESS_GITHUB_REPO__', {} as Record<string,
updatedAt: number
}>)
export function useGithubRepo(repo: MaybeRef<string>) {
interface UseGithubRepoResult {
data: Ref<GithubRepoInfo | null>
loaded: Ref<boolean>
}
export function useGithubRepo(repo: MaybeRef<string>): UseGithubRepoResult {
const repoRef = computed(() => {
const info = toValue(repo)
const [owner = '', name = ''] = info.split('/')

View File

@ -81,7 +81,7 @@ export function useNpmBadge(opt: Ref<NpmBadgeOptions>): ComputedRef<NpmBadgeInfo
})
}
export function useNpmBadgeGroup(opt: Ref<NpmBadgeGroupOptions>) {
export function useNpmBadgeGroup(opt: Ref<NpmBadgeGroupOptions>): void {
const baseOptions = computed<NpmBadgeBaseOptions>(() => {
const o = toValue(opt)
return {

View File

@ -11,7 +11,7 @@ import VPIcon from '@theme/VPIcon.vue'
import { hasGlobalComponent } from '@vuepress/helper/client'
import { h, resolveComponent } from 'vue'
export function globalComponents(app: App) {
export function globalComponents(app: App): void {
app.component('Badge', VPBadge)
app.component('VPBadge', VPBadge)

View File

@ -1,9 +1,9 @@
export const EXTERNAL_URL_RE = /^[a-z]+:/i
export const PATHNAME_PROTOCOL_RE = /^pathname:\/\//
export const HASH_RE = /#.*$/
export const EXT_RE = /(index|README)?\.(md|html)$/
export const EXTERNAL_URL_RE: RegExp = /^[a-z]+:/i
export const PATHNAME_PROTOCOL_RE: RegExp = /^pathname:\/\//
export const HASH_RE: RegExp = /#.*$/
export const EXT_RE: RegExp = /(index|README)?\.(md|html)$/
export const inBrowser = typeof document !== 'undefined'
export const inBrowser: boolean = typeof document !== 'undefined'
export function toArray<T>(value: T | T[]): T[] {
return Array.isArray(value) ? value : [value]

View File

@ -32,7 +32,7 @@ export interface Generate {
let generate: Generate | null = null
export function initAutoFrontmatter() {
export function initAutoFrontmatter(): void {
const { autoFrontmatter = {}, ...options } = getThemeConfig()
if (autoFrontmatter === false)
return
@ -86,7 +86,7 @@ export function initAutoFrontmatter() {
}
}
export async function generateAutoFrontmatter(app: App) {
export async function generateAutoFrontmatter(app: App): Promise<void> {
perf.mark('generate:frontmatter')
if (!generate)
return
@ -111,7 +111,7 @@ export async function generateAutoFrontmatter(app: App) {
perf.log('generate:frontmatter')
}
export async function watchAutoFrontmatter(app: App, watchers: any[]) {
export async function watchAutoFrontmatter(app: App, watchers: any[]): Promise<void> {
if (!generate)
return

View File

@ -4,7 +4,7 @@ import { pathJoin } from '../utils/index.js'
export function resolveLinkBySidebar(
sidebar: 'auto' | (string | ThemeSidebarItem)[],
_prefix: string,
) {
): Record<string, string> {
const res: Record<string, string> = {}
if (sidebar === 'auto') {

View File

@ -3,7 +3,7 @@ import { uniq } from '@pengzhanbo/utils'
import { entries, removeLeadingSlash } from '@vuepress/helper'
import { normalizePath, withBase } from '../utils/index.js'
export function resolveNotesLinkList(options: ThemeOptions) {
export function resolveNotesLinkList(options: ThemeOptions): string[] {
const locales = options.locales || {}
const notesLinks: string[] = []
for (const [locale, opt] of entries(locales)) {

View File

@ -1,7 +1,8 @@
import type { ThemeObject } from 'vuepress'
import { fs, path } from 'vuepress/utils'
import { resolve } from '../utils/index.js'
export function setupAlias() {
export function setupAlias(): ThemeObject['alias'] {
return {
...Object.fromEntries(
fs.readdirSync(

View File

@ -6,7 +6,7 @@ import { getThemePackage } from '../utils/index.js'
export function templateBuildRenderer(
template: string,
context: TemplateRendererContext,
) {
): Promise<string> | string {
const options = getThemeConfig()
const pkg = getThemePackage()
template = template

View File

@ -33,7 +33,7 @@ const t = createTranslate({
*
*
*/
export function detectDependencies(options: ThemeOptions, plugins: ThemeBuiltinPlugins) {
export function detectDependencies(options: ThemeOptions, plugins: ThemeBuiltinPlugins): void {
const shouldInstall: Record<string, string[]> = {}
const markdown = options.markdown || {}

View File

@ -1,4 +1,4 @@
import type { ThemeOptions } from '../../shared/index.js'
import type { ThemeBuiltinPlugins, ThemeOptions } from '../../shared/index.js'
import { detectDependencies } from './dependency.js'
import { detectMarkdown } from './markdown.js'
import { detectPlugins } from './plugins.js'
@ -10,7 +10,11 @@ export function detectThemeOptions({
plugins = {},
configFile,
...themeOptions
}: ThemeOptions) {
}: ThemeOptions): {
configFile: string | undefined
plugins: ThemeBuiltinPlugins
themeOptions: Omit<ThemeOptions, 'plugins' | 'configFile'>
} {
detectDependencies(themeOptions, plugins)
// detect options

View File

@ -8,7 +8,7 @@ const t = createTranslate({
zh: { message: '{{ plugins }} 不支持以下字段: {{ unsupported }}, 请检查你的配置。' },
})
export function detectPlugins(plugins: ThemeBuiltinPlugins) {
export function detectPlugins(plugins: ThemeBuiltinPlugins): void {
// 部分用户可能混淆 plugins 选项与 vuepress 的 plugins 选项,误传入插件数组
if (Array.isArray(plugins)) {
logger.warn(`${colors.green('plugins')} only accept object config, please check your config.`)

View File

@ -16,7 +16,7 @@ const t = createTranslate({
},
})
export function detectVersions(app: App) {
export function detectVersions(app: App): void {
detectVuepressVersion()
detectThemeVersion(app)
}

View File

@ -33,7 +33,7 @@ let loader: Loader | null = null
export async function initConfigLoader(
app: App,
{ configFile, onChange, defaultConfig }: InitConfigLoaderOptions,
) {
): Promise<void> {
perf.mark('load-config')
loader = {
configFile,
@ -68,7 +68,7 @@ export async function initConfigLoader(
perf.log('load-config')
}
export function watchConfigFile(app: App, watchers: any[], onChange: ChangeEvent) {
export function watchConfigFile(app: App, watchers: any[], onChange: ChangeEvent): void {
if (!loader || !loader.configFile)
return
@ -100,7 +100,7 @@ export function watchConfigFile(app: App, watchers: any[], onChange: ChangeEvent
watchers.push(watcher)
}
export async function onConfigChange(onChange: ChangeEvent) {
export async function onConfigChange(onChange: ChangeEvent): Promise<void> {
if (loader && !loader.changeEvents.includes(onChange)) {
loader.changeEvents.push(onChange)
if (loader.loaded) {
@ -109,7 +109,7 @@ export async function onConfigChange(onChange: ChangeEvent) {
}
}
export function waitForConfigLoaded() {
export function waitForConfigLoaded(): Promise<ThemeOptions> {
return new Promise<ThemeOptions>((resolve) => {
if (loader?.loaded) {
resolve(loader.config)
@ -120,7 +120,7 @@ export function waitForConfigLoaded() {
})
}
export function getThemeConfig() {
export function getThemeConfig(): ThemeOptions {
return loader!.config
}

View File

@ -13,7 +13,7 @@ let LOCALE_RE: RegExp
export function autoCategory(
page: Page<ThemePageData>,
options: ThemeOptions,
) {
): void {
const pagePath = page.filePathRelative
const blog = isPlainObject(options.blog) ? options.blog : {}
const enabled = blog.categories !== false

View File

@ -13,7 +13,7 @@ function getRootLang(app: App): string {
return app.siteData.lang
}
export async function createPages(app: App) {
export async function createPages(app: App): Promise<void> {
const options = getThemeConfig()
if (options.blog === false)

View File

@ -6,7 +6,7 @@ import { enableBulletin } from './pageBulletin.js'
export function extendsPageData(
page: Page<ThemePageData>,
) {
): void {
const options = getThemeConfig()
cleanPageData(page)
autoCategory(page, options)

View File

@ -5,7 +5,7 @@ import { isFunction, isPlainObject } from '@vuepress/helper'
export function enableBulletin(
page: Page<ThemePageData>,
options: ThemeOptions,
) {
): void {
if (isPlainObject(options.bulletin)) {
const enablePage = options.bulletin.enablePage
page.data.bulletin = (isFunction(enablePage) ? enablePage(page) : enablePage) ?? true

View File

@ -20,7 +20,7 @@ const separator = ':'
let contentHash = ''
let fsCache: FsCache<[string, EncryptConfig]> | null = null
export async function prepareEncrypt(app: App) {
export async function prepareEncrypt(app: App): Promise<void> {
perf.mark('prepare:encrypt')
const { encrypt } = getThemeConfig()
if (!fsCache && app.env.isDev) {
@ -72,7 +72,7 @@ function resolveEncrypt(encrypt?: EncryptOptions): EncryptConfig {
return [encrypt?.global ?? false, separator, admin, keys, rules]
}
export function isEncryptPage(page: Page<ThemePageData>, encrypt?: EncryptOptions) {
export function isEncryptPage(page: Page<ThemePageData>, encrypt?: EncryptOptions): boolean {
if (!encrypt)
return false

View File

@ -38,7 +38,7 @@ function isIconify(icon: any): icon is string {
return icon[0] !== '{' && ICONIFY_NAME.test(icon)
}
export async function prepareIcons(app: App) {
export async function prepareIcons(app: App): Promise<void> {
perf.mark('prepare:icons:total')
const options = getThemeConfig()
if (!isInstalled) {

View File

@ -16,7 +16,7 @@ import {
import { getThemeConfig } from '../loadConfig/loader.js'
import { normalizeLink, perf, resolveContent, writeTemp } from '../utils/index.js'
export async function prepareSidebar(app: App) {
export async function prepareSidebar(app: App): Promise<void> {
perf.mark('prepare:sidebar')
const options = getThemeConfig()
const sidebar = getAllSidebar(options)

View File

@ -1,6 +1,6 @@
import { createHash } from 'node:crypto'
import { customAlphabet } from 'nanoid'
export const hash = (content: string) => createHash('md5').update(content).digest('hex')
export const hash = (content: string): string => createHash('md5').update(content).digest('hex')
export const nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 8)
export const nanoid: (size?: number) => string = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 8)

Some files were not shown because too many files have changed in this diff Show More