/
posts.data.ts
91 lines (77 loc) 路 2.06 KB
/
posts.data.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { createMarkdownRenderer, MarkdownRenderer } from 'vitepress'
import { fileURLToPath } from 'url'
let md: MarkdownRenderer
const dirname = path.dirname(fileURLToPath(import.meta.url))
const postDir = path.resolve(dirname, '../../posts')
export interface Post {
title: string
href: string
date: {
time: number
string: string
}
excerpt: string | undefined
data?: Record<string, any>
}
interface PostWithData extends Post {
data: Record<string, any>
}
declare const data: Post[]
export { data }
async function load(): Promise<Post[]>
async function load(asFeed: boolean): Promise<PostWithData[]>
async function load(asFeed = false) {
md = md || (await createMarkdownRenderer(process.cwd()))
return fs
.readdirSync(postDir)
.map((file) => getPost(file, postDir, asFeed))
.sort((a, b) => b.date.time - a.date.time)
}
export default {
watch: path.join(postDir, '*.md'),
load
}
const cache = new Map()
function getPost(file: string, postDir: string, asFeed = false): Post {
const fullePath = path.join(postDir, file)
const timestamp = fs.statSync(fullePath).mtimeMs
const cached = cache.get(fullePath)
if (cached && timestamp === cached.timestamp) {
return cached.post
}
const src = fs.readFileSync(fullePath, 'utf-8')
const { data, excerpt } = matter(src, { excerpt: true })
const post: Post = {
title: data.title,
href: `/posts/${file.replace(/\.md$/, '.html')}`,
date: formatDate(data.date),
excerpt: excerpt && md.render(excerpt)
}
if (asFeed) {
// only attach these when building the RSS feed to avoid bloating the
// client bundle size
post.data = data
}
cache.set(fullePath, {
timestamp,
post
})
return post
}
function formatDate(date: string | Date): Post['date'] {
if (!(date instanceof Date)) {
date = new Date(date)
}
date.setUTCHours(12)
return {
time: +date,
string: date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
}
}