feat(plugin-notes-data): 支持 数组形式的插件配置项

This commit is contained in:
pengzhanbo 2024-01-05 01:34:09 +08:00
parent 1fe16bd579
commit 66f1f037e4
3 changed files with 32 additions and 22 deletions

View File

@ -3,7 +3,7 @@ import { getDirname, path } from '@vuepress/utils'
import type { NotesDataOptions } from '../shared/index.js'
import { prepareNotesData, watchNotesData } from './prepareNotesData.js'
export function notesDataPlugin(options: NotesDataOptions): Plugin {
export function notesDataPlugin(options: NotesDataOptions | NotesDataOptions[]): Plugin {
return (app: App) => {
return {
name: '@vuepress-plume/plugin-notes-data',

View File

@ -5,7 +5,7 @@ import { createFilter } from 'create-filter'
import type {
NotesData,
NotesDataOptions,
NotesItem,
NotesItemOptions,
NotesSidebar,
NotesSidebarItem,
} from '../shared/index.js'
@ -32,10 +32,11 @@ interface NotePage {
link: string
}
export async function prepareNotesData(app: App, { include, exclude, notes, dir, link }: NotesDataOptions) {
function resolvedNotesData(app: App, options: NotesDataOptions, result: NotesData) {
const { include, exclude, notes, dir: _dir, link } = options
if (!notes || notes.length === 0)
return
dir = normalizePath(dir)
const dir = normalizePath(_dir)
const filter = createFilter(ensureArray(include), ensureArray(exclude), {
resolve: false,
})
@ -47,23 +48,27 @@ export async function prepareNotesData(app: App, { include, exclude, notes, dir,
&& page.filePathRelative.startsWith(dir)
&& filter(page.filePathRelative),
)
.map((page) => {
return {
relativePath: page.filePathRelative?.replace(DIR_PATTERN, '') || '',
title: page.title,
link: page.path,
}
})
const notesData: NotesData = {}
.map(page => ({
relativePath: page.filePathRelative?.replace(DIR_PATTERN, '') || '',
title: page.title,
link: page.path,
}))
notes.forEach((note) => {
notesData[normalizePath(path.join('/', link, note.link))] = initSidebar(
result[normalizePath(path.join('/', link, note.link))] = initSidebar(
note,
notesPageList.filter(page =>
page.relativePath.startsWith(note.dir.trim().replace(/^\/|\/$/g, '')),
),
)
})
}
export async function prepareNotesData(app: App, options: NotesDataOptions | NotesDataOptions[]) {
const notesData: NotesData = {}
const allOptions = ensureArray<NotesDataOptions>(options)
allOptions.forEach(option => resolvedNotesData(app, option, notesData))
let content = `
export const notesData = ${JSON.stringify(notesData, null, 2)}
`
@ -73,22 +78,25 @@ export const notesData = ${JSON.stringify(notesData, null, 2)}
await app.writeTemp('internal/notesData.js', content)
}
export function watchNotesData(app: App, watchers: any[], options: NotesDataOptions): void {
if (!options.notes || options.notes.length === 0 || !options.dir)
return
const dir = path.join('pages', options.dir, '**/*')
export function watchNotesData(app: App, watchers: any[], options: NotesDataOptions | NotesDataOptions[]): void {
const allOptions = ensureArray<NotesDataOptions>(options)
const [firstLink, ...links] = allOptions.map(option => option.link)
const dir = path.join('pages', firstLink, '**/*')
const watcher = chokidar.watch(dir, {
cwd: app.dir.temp(),
ignoreInitial: true,
})
links.length && watcher.add(links.map(link => path.join('pages', link, '**/*')))
watcher.on('add', () => prepareNotesData(app, options))
watcher.on('change', () => prepareNotesData(app, options))
watcher.on('unlink', () => prepareNotesData(app, options))
watchers.push(watcher)
}
function initSidebar(note: NotesItem, pages: NotePage[]): NotesSidebarItem[] {
function initSidebar(note: NotesItemOptions, pages: NotePage[]): NotesSidebarItem[] {
if (!note.sidebar)
return []
if (note.sidebar === 'auto')
@ -97,7 +105,7 @@ function initSidebar(note: NotesItem, pages: NotePage[]): NotesSidebarItem[] {
}
function initSidebarByAuto(
note: NotesItem,
note: NotesItemOptions,
pages: NotePage[],
): NotesSidebarItem[] {
pages = pages.sort((prev, next) => {
@ -135,7 +143,7 @@ function initSidebarByAuto(
}
function initSidebarByConfig(
{ text, dir, sidebar }: NotesItem,
{ text, dir, sidebar }: NotesItemOptions,
pages: NotePage[],
): NotesSidebarItem[] {
return (sidebar as NotesSidebar).map((item) => {

View File

@ -3,9 +3,11 @@ export interface NotesDataOptions {
link: string
include?: string | string[]
exclude?: string | string[]
notes: NotesItem[]
notes: NotesItemOptions[]
}
export type NotesItemOptions = (Omit<NotesItem, 'text'> & { text?: string })
export interface NotesItem {
dir: string
link: string