-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
blog.api.ts
78 lines (70 loc) · 2.34 KB
/
blog.api.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
import { readFileSync, readdirSync } from 'fs';
import { join, basename } from 'path';
import { extractFrontmatter } from '@nx/nx-dev/ui-markdoc';
import { sortPosts } from './blog.util';
import { BlogPostDataEntry } from './blog.model';
export class BlogApi {
constructor(
private readonly options: {
id: string;
blogRoot: string;
}
) {
if (!options.id) {
throw new Error('id cannot be undefined');
}
if (!options.blogRoot) {
throw new Error('public blog root cannot be undefined');
}
}
getBlogPosts(): BlogPostDataEntry[] {
const files: string[] = readdirSync(this.options.blogRoot);
const allPosts: BlogPostDataEntry[] = [];
for (const file of files) {
const filePath = join(this.options.blogRoot, file);
// filter out directories (e.g. images)
if (!filePath.endsWith('.md')) continue;
const content = readFileSync(filePath, 'utf8');
const frontmatter = extractFrontmatter(content);
const slug = this.calculateSlug(filePath, frontmatter);
const post = {
content,
frontmatter: {
title: frontmatter.title,
description: frontmatter.description,
authors: frontmatter.authors,
date: this.calculateDate(file, frontmatter),
cover_image: frontmatter.cover_image ?? null,
tags: frontmatter.tags,
reposts: frontmatter.reposts,
pinned: frontmatter.pinned ?? false,
},
filePath,
slug,
};
if (!frontmatter.draft || process.env.NODE_ENV === 'development') {
allPosts.push(post);
}
}
return sortPosts(allPosts);
}
private calculateSlug(filePath: string, frontmatter: any): string {
const baseName = basename(filePath, '.md');
return frontmatter.slug || baseName;
}
private calculateDate(filename: string, frontmatter: any): string {
const date: Date = new Date();
const timeString = date.toTimeString();
if (frontmatter.date) {
return new Date(frontmatter.date + ' ' + timeString).toISOString();
} else {
const regexp = /^(\d\d\d\d-\d\d-\d\d).+$/;
const match = filename.match(regexp);
if (match) {
return new Date(match[1] + ' ' + timeString).toISOString();
} else {
throw new Error(`Could not parse date from filename: ${filename}`);
}
}
}
}