-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.mjs
112 lines (91 loc) · 4.13 KB
/
cli.mjs
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import fs from "fs";
import path from "path";
import matter from "gray-matter";
import { program } from "commander";
import { globSync } from "glob";
const updatePost = (updateFunction) => {
return (id, date, options) => {
const [postPath] = globSync(`./src/content/blog/${date ?? "*/*"}/${id}/index.mdx`);
if(!postPath)
throw `There is no post with ID ${id}.`
const post = fs.readFileSync(postPath, 'utf-8')
const { data, content } = matter(post);
const output = updateFunction(data, content, options);
fs.writeFileSync(postPath, output);
console.log("Post updated successfully!");
}
}
program
.command("new")
.description("Creates a new post and its associated assets folder.")
.argument('<title>', 'title of the post')
.option('--id <id>', 'internal ID of the post')
.action(async (title, options) => {
const id = options.id
? options.id.replaceAll(/[&\/\\#,+()$~%.'":*?<>{}]/g, "").replaceAll(/\s/g, "-").toLowerCase()
: title.replaceAll(/[&\/\\#,+()$~%.'":*?<>{}]/g, "").replaceAll(/\s/g, "-").toLowerCase();
const today = new Date();
const year = today.getUTCFullYear().toString();
const month = (today.getUTCMonth()+1).toString().padStart(2, '0');
const postDir = path.resolve(process.cwd(), "./src/content/blog/", year, month, id);
const postPath = path.resolve(postDir, "index.mdx");
if(!fs.existsSync(postDir)) {
fs.mkdirSync(postDir, {recursive: true})
} else if(fs.existsSync(postPath)) {
throw `A post with the ID ${id} already exists. Try with another ID.`
}
const frontmatter = {
title,
description: "Insert description here",
pubDate: today.toISOString(),
hero: {
modern: "./hero.png",
legacy: "./hero-legacy.png"
},
draft: true,
category: "misc",
tags: ['tags','here']
}
const content =`
Image imports go here...
<div class="feed-preview">
Anything inside this element will be inside the content of the RSS feed.
(No leading whitespaces!)
</div>
Body of the post here...`;
const output = matter.stringify(content, frontmatter);
fs.writeFileSync(postPath, output);
console.log("Created MDX post!");
const placeholderModern = Buffer.from(await (await fetch("https://placehold.co/1920x1080/png")).arrayBuffer());
const placeholderLegacy = Buffer.from(await (await fetch("https://placehold.co/454x303/png")).arrayBuffer());
fs.writeFileSync(path.resolve(postDir, "hero.png"), placeholderModern);
fs.writeFileSync(path.resolve(postDir, "hero-legacy.png"), placeholderLegacy);
});
program
.command("publish")
.description("Sets post for publishing. This also updates the publish date.")
.argument("<id>", "ID of the post")
.argument("[date-folder]", "The date folder it is included, in YYYY/MM format. If not specified, it gets the first find.")
.option("-d", "do not update the publish date.")
.action(updatePost((data, content, options) => {
if(!options?.d)
data.pubDate = new Date().toISOString();
data.draft = false;
return matter.stringify({data, content});
}));
program
.command("update")
.description("Marks posts that has been updated. The updated date will be set.")
.argument("<id>", "ID of the post")
.argument("[date-folder]", "The date folder it is included, in YYYY/MM format. If not specified, it gets the first find.")
.option("-p --publish", "Alter the publish date instead.")
.action(updatePost((data, content, options) => {
if(options?.publish) {
console.log("Updating pubDate instead of updatedDate.")
data.pubDate = new Date().toISOString();
} else {
data.updatedDate = new Date().toISOString();
}
return matter.stringify({data, content});
}))
program.parse();