diff --git a/packages/plugin-auto-frontmatter/README.md b/packages/plugin-auto-frontmatter/README.md index f5f912b9..1804150a 100644 --- a/packages/plugin-auto-frontmatter/README.md +++ b/packages/plugin-auto-frontmatter/README.md @@ -15,7 +15,7 @@ export default { plugins: [ autoFrontmatterPlugin({ formatter: { - createTime(formatTime, matter, file) { + createTime(formatTime, file, matter) { if (formatTime) return formatTime return file.createTime } @@ -48,10 +48,11 @@ export default { relativePath: string content: string createTime: Date + stats: fs.Stats } interface FormatterFn { - (value: T, data: K, file: MarkdownFile): T + (value: T, file: MarkdownFile, data: K): T } type FormatterObject = Record< @@ -60,7 +61,7 @@ export default { > type FormatterArray = { - include: string + include: string | string[] formatter: FormatterObject }[] @@ -75,7 +76,7 @@ export default { * --- */ const formatterObj: Formatter = { - createTime(formatTime, matter, file) { + createTime(formatTime, file, matter) { if (formatTime) return formatTime return file.createTime } @@ -87,7 +88,7 @@ export default { include: '**/{README,index}.md', // formatter 仅对 glob命中的文件有效 formatter: { - home(value, matter, file) { + home(value, file, matter) { return value } }, diff --git a/packages/plugin-auto-frontmatter/src/node/index.ts b/packages/plugin-auto-frontmatter/src/node/index.ts index 9031d476..8efa6479 100644 --- a/packages/plugin-auto-frontmatter/src/node/index.ts +++ b/packages/plugin-auto-frontmatter/src/node/index.ts @@ -1,8 +1,12 @@ -import type { AutoFrontmatterOptions } from '../shared/index.js' +import type { + AutoFrontmatterOptions, + FormatterArray, + FormatterObject, +} from '../shared/index.js' import { autoFrontmatterPlugin } from './plugin.js' export * from './plugin.js' -export { AutoFrontmatterOptions } +export { AutoFrontmatterOptions, FormatterArray, FormatterObject } export default autoFrontmatterPlugin diff --git a/packages/plugin-auto-frontmatter/src/node/plugin.ts b/packages/plugin-auto-frontmatter/src/node/plugin.ts index 47c391fb..2eb66e95 100644 --- a/packages/plugin-auto-frontmatter/src/node/plugin.ts +++ b/packages/plugin-auto-frontmatter/src/node/plugin.ts @@ -40,26 +40,26 @@ export const autoFrontmatterPlugin = ({ } }) - function formatMarkdown(file: MarkdownFile): void { + async function formatMarkdown(file: MarkdownFile): Promise { const { filepath, relativePath } = file const current = otherFormatters.find(({ filter }) => filter(relativePath)) const formatter = current?.formatter || globFormatter const { data, content } = grayMatter(file.content) - Object.keys(formatter).forEach((key) => { - const value = formatter[key](data[key], data, file) + for (const key in formatter) { + const value = await formatMarkdown[key](data[key], file, data) data[key] = value ?? data[key] - }) + } try { const yaml = isEmptyObject(data) - ? '---\n' + ? '' : jsonToYaml .stringify(data) .replace(/\n\s{2}/g, '\n') .replace(/"/g, '') - const newContent = `${yaml}---\n${content}` + const newContent = yaml ? `${yaml}---\n${content}` : content fs.writeFileSync(filepath, newContent, 'utf-8') } catch (e) { @@ -71,7 +71,9 @@ export const autoFrontmatterPlugin = ({ name: '@vuepress-plume/vuepress-plugin-auto-frontmatter', onInitialized: async (app) => { const markdownList = await readMarkdownList(app.dir.source(), globFilter) - markdownList.forEach((file) => formatMarkdown(file)) + for (const file of markdownList) { + await formatMarkdown(file) + } }, onWatched: async (app, watchers) => { const watcher = chokidar.watch('**/*.md', { @@ -80,9 +82,9 @@ export const autoFrontmatterPlugin = ({ ignored: /(node_modules|\.vuepress)\//, }) - watcher.on('add', (relativePath) => { + watcher.on('add', async (relativePath) => { if (!globFilter(relativePath)) return - formatMarkdown(readMarkdown(app.dir.source(), relativePath)) + await formatMarkdown(readMarkdown(app.dir.source(), relativePath)) }) watchers.push(watcher) diff --git a/packages/plugin-auto-frontmatter/src/node/readFiles.ts b/packages/plugin-auto-frontmatter/src/node/readFiles.ts index fa9e227a..e6b41fef 100644 --- a/packages/plugin-auto-frontmatter/src/node/readFiles.ts +++ b/packages/plugin-auto-frontmatter/src/node/readFiles.ts @@ -24,14 +24,16 @@ export const readMarkdown = ( relativePath: string ): MarkdownFile => { const filepath = path.join(sourceDir, relativePath) + const stats = fs.statSync(filepath) return { filepath, relativePath, content: fs.readFileSync(filepath, 'utf-8'), - createTime: getFileCreateTime(fs.statSync(filepath)), + createTime: getFileCreateTime(stats), + stats, } } -export const getFileCreateTime = (stat: fs.Stats): Date => { - return stat.birthtime.getFullYear() !== 1970 ? stat.birthtime : stat.atime +export const getFileCreateTime = (stats: fs.Stats): Date => { + return stats.birthtime.getFullYear() !== 1970 ? stats.birthtime : stats.atime } diff --git a/packages/plugin-auto-frontmatter/src/shared/index.ts b/packages/plugin-auto-frontmatter/src/shared/index.ts index c02c2680..221824d1 100644 --- a/packages/plugin-auto-frontmatter/src/shared/index.ts +++ b/packages/plugin-auto-frontmatter/src/shared/index.ts @@ -1,21 +1,24 @@ +import type fs from 'node:fs' export interface MarkdownFile { filepath: string relativePath: string content: string createTime: Date + stats: fs.Stats } -export interface FormatterFn { - (value: T, data: K, file: MarkdownFile): T -} +export type FormatterFn = ( + value: T, + file: MarkdownFile, + data: K +) => T | PromiseLike -export type FormatterObject = Record< - string, - FormatterFn -> +export type FormatterObject = { + [P: string]: FormatterFn +} export type FormatterArray = { - include: string + include: string | string[] formatter: FormatterObject }[] @@ -29,10 +32,10 @@ export interface AutoFrontmatterOptions { /** * { - * key(value, data, file) { + * key(value, file, data) { * return value * } * } */ - formatter?: FormatterObject | FormatterArray + formatter?: FormatterArray | FormatterObject } diff --git a/packages/theme/src/node/autoFrontmatter.ts b/packages/theme/src/node/autoFrontmatter.ts index 55590d09..50cc9950 100644 --- a/packages/theme/src/node/autoFrontmatter.ts +++ b/packages/theme/src/node/autoFrontmatter.ts @@ -1,6 +1,9 @@ import { createRequire } from 'node:module' import path from 'node:path' -import type { AutoFrontmatterOptions } from '@vuepress-plume/vuepress-plugin-auto-frontmatter' +import type { + AutoFrontmatterOptions, + FormatterArray, +} from '@vuepress-plume/vuepress-plugin-auto-frontmatter' import type { NotesDataOptions, NotesItem, @@ -60,14 +63,14 @@ export default function ( // note 首页链接 include: path.join(notesDir, `**/{readme,README,index}.md`), formatter: { - title(title: string, _, { filepath }) { + title(title: string, { filepath }) { if (title) return title const note = findNote(filepath) if (note?.text) return note.text return getCurrentDirname(note, filepath) || '' }, ...baseFormatter, - permalink(permalink: string, _, { filepath }) { + permalink(permalink: string, { filepath }) { if (permalink) return permalink const note = findNote(filepath) const dirname = getCurrentDirname(note, filepath) @@ -78,13 +81,13 @@ export default function ( { include: path.join(notesDir, '**/*.md'), formatter: { - title(title: string, _, { filepath }) { + title(title: string, { filepath }) { if (title) return title const basename = path.basename(filepath, '.md') return basename }, ...baseFormatter, - permalink(permalink: string, _, { filepath }) { + permalink(permalink: string, { filepath }) { if (permalink) return permalink const note = findNote(filepath) const dirname = getCurrentDirname(note, filepath) @@ -99,7 +102,7 @@ export default function ( { include: '*', formatter: { - title(title: string, _, { filepath }) { + title(title: string, { filepath }) { if (title) return title const basename = path.basename(filepath, '.md') return basename @@ -111,6 +114,6 @@ export default function ( }, }, }, - ], + ] as FormatterArray, } }