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

View File

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

View File

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