This repository has been archived by the owner on Jun 14, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 88
/
loader.ts
82 lines (71 loc) · 2.41 KB
/
loader.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
import matter from 'gray-matter';
import glob from 'glob';
import { globals } from './globals';
export type PostData = {
path: string;
title: string;
subtitle?: string;
content: string;
description?: string;
canonicalUrl?: string;
published: boolean;
datePublished: number;
author?: string;
authorPhoto?: string;
authorTwitter?: string;
tags?: string[];
bannerPhoto?: string;
thumbnailPhoto?: string;
};
type RawFile = { path: string; contents: string };
export const loadMarkdownFile = async (path: string): Promise<RawFile> => {
const mdFile = await import(`./md/${path}`);
return { path, contents: mdFile.default };
};
export const mdToPost = (file: RawFile): PostData => {
const metadata = matter(file.contents);
const path = file.path.replace('.md', '');
const post = {
path,
title: metadata.data.title,
subtitle: metadata.data.subtitle || null,
published: metadata.data.published || false,
datePublished: metadata.data.datePublished || null,
tags: metadata.data.tags || null,
description: metadata.data.description || null,
canonicalUrl: metadata.data.canonicalUrl || `${globals.url}/${path}`,
author: metadata.data.author || null,
authorPhoto: metadata.data.authorPhoto || null,
authorTwitter: metadata.data.authorTwitter || null,
bannerPhoto: metadata.data.bannerPhoto || null,
thumbnailPhoto: metadata.data.thumbnailPhoto || null,
content: metadata.content,
};
if (!post.title)
throw new Error(`Missing required field: title.`);
if (!post.content)
throw new Error(`Missing required field: content.`);
if (!post.datePublished)
throw new Error(`Missing required field: datePublished.`);
return post as PostData;
};
export const loadMarkdownFiles = async (path: string) => {
const blogPaths = glob.sync(`./md/${path}`);
const postDataList = await Promise.all(
blogPaths.map((blogPath) => {
const modPath = blogPath.slice(blogPath.indexOf(`md/`) + 3);
return loadMarkdownFile(`${modPath}`);
})
);
return postDataList;
};
export const loadPost = async (path: string): Promise<PostData> => {
const file = await loadMarkdownFile(path);
return mdToPost(file);
};
export const loadBlogPosts = async (): Promise<PostData[]> => {
return await (await loadMarkdownFiles(`blog/*.md`))
.map(mdToPost)
.filter((p) => p.published)
.sort((a, b) => (b.datePublished || 0) - (a.datePublished || 0));
};