notes.ts

1import fs from 'fs'
2import path from 'path'
3import matter from 'gray-matter'
4
5export type Metadata = {
6	title: string
7	publishedAt: string
8	summary: string
9}
10
11export type NotePost = {
12	metadata: Metadata
13	slug: string
14	content: string
15}
16
17function parseFrontmatter(fileContent: string): {
18	metadata: Metadata
19	content: string
20} {
21	const { data, content } = matter(fileContent)
22	return {
23		metadata: {
24			title: data.title || '',
25			publishedAt: data.publishedAt || '',
26			summary: data.summary || '',
27		},
28		content: content.trim(),
29	}
30}
31
32function getMDXFiles(dir: string): string[] {
33	return fs
34		.readdirSync(dir)
35		.filter(
36			(file) => path.extname(file) === '.mdx' || path.extname(file) === '.md',
37		)
38}
39
40function readMDXFile(filePath: string) {
41	const rawContent = fs.readFileSync(filePath, 'utf-8')
42	return parseFrontmatter(rawContent)
43}
44
45function getMDXData(dir: string) {
46	const mdxFiles = getMDXFiles(dir)
47	return mdxFiles.map((file) => {
48		const { metadata, content } = readMDXFile(path.join(dir, file))
49		const slug = path.basename(file, path.extname(file))
50
51		return {
52			metadata,
53			slug,
54			content,
55		}
56	})
57}
58
59export function getNotePosts(amount = 5, page = 1) {
60	const posts = getMDXData(path.join(process.cwd(), 'content', 'notes'))
61
62	const start = (page - 1) * amount
63	const end = start + amount
64
65	return posts.reverse().slice(start, end)
66}
67
68export function getAllNotePosts() {
69	return getMDXData(path.join(process.cwd(), 'content', 'notes'))
70}
71
72export function getNotePost(slug: string): NotePost | undefined {
73	const posts = getMDXData(path.join(process.cwd(), 'content', 'notes'))
74	return posts.find((post) => post.slug === slug)
75}
76
77export function generateBlogTimetoRead(content: string) {
78	const wordsPerMinute = 200
79	const words = content.split(/\s/g).length
80	const minutes = words / wordsPerMinute
81	const readTime = Math.ceil(minutes)
82	return readTime
83}
84
85export function getNotePages(limit: number) {
86	const posts = getMDXData(path.join(process.cwd(), 'content', 'notes'))
87	return Math.ceil(posts.length / limit)
88}
89