| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | import { PostFilesDirectory } from "@/consts/consts"; | 
					
						
							|  |  |  | import { getCurrentTime } from "@/lib/date"; | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  | import { stringifyFrontmatter } from "@/lib/frontmatter"; | 
					
						
							|  |  |  | import { type ChildProcessWithoutNullStreams, type SpawnSyncReturns, spawn, spawnSync } from "child_process"; | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | import colors from "colors"; | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  | import fs from "fs"; | 
					
						
							| 
									
										
										
										
											2024-08-14 12:57:22 +08:00
										 |  |  | import inquirer, { type QuestionCollection } from "inquirer"; | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | import _ from "lodash"; | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  | import path from "path"; | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | import { titleCase } from "title-case"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type TAnswer = { | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  |   inputTitle: string; | 
					
						
							|  |  |  |   inputSubtitle: string; | 
					
						
							|  |  |  |   inputTags: string; | 
					
						
							|  |  |  |   inputNoPrompt: boolean; | 
					
						
							|  |  |  |   inputPin: boolean; | 
					
						
							|  |  |  |   inputAllowShare: boolean; | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const questions: QuestionCollection<TAnswer> = [ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     type: "input", | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  |     name: "inputTitle", | 
					
						
							|  |  |  |     message: "What's the title? (Required)", | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  |     validate: (input: string) => (input.trim() === "" ? "Please enter a title." : true), | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  |   { | 
					
						
							|  |  |  |     type: "input", | 
					
						
							|  |  |  |     name: "inputSubtitle", | 
					
						
							|  |  |  |     message: "What's the subtitle? (Optional)", | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     type: "input", | 
					
						
							|  |  |  |     name: "inputTags", | 
					
						
							|  |  |  |     message: "Assign tags for the posts and separate them with commas. (Required, default: others)", | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     type: "confirm", | 
					
						
							|  |  |  |     name: "inputNoPrompt", | 
					
						
							|  |  |  |     message: "Do NOT prompt this post? (Required, Default:false)", | 
					
						
							|  |  |  |     default: false, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     type: "confirm", | 
					
						
							|  |  |  |     name: "inputPin", | 
					
						
							|  |  |  |     message: "Do you want to pin this post? (Required, Default:false)", | 
					
						
							|  |  |  |     default: false, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     type: "confirm", | 
					
						
							|  |  |  |     name: "inputAllowShare", | 
					
						
							|  |  |  |     message: "Do you allow everybody share this post? (Required, Default:true)", | 
					
						
							|  |  |  |     default: true, | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const writePostFile = (filePath: string, content: string): void => { | 
					
						
							|  |  |  |   fs.writeFile(filePath, content, "utf-8", (err) => { | 
					
						
							|  |  |  |     if (err) { | 
					
						
							|  |  |  |       console.error("Error writing file:", err); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     console.log(colors.green(colors.bold("Create Post Succeed."))); | 
					
						
							|  |  |  |     console.log(`Open the file ${colors.cyan(filePath)} to write your blog now.`); | 
					
						
							|  |  |  |     console.log("Some fields, such as summary, need to be filled in by yourself after opening the file."); | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  | const openPostFile = (filePath: string) => { | 
					
						
							|  |  |  |   const openFileCommand: Record<string, () => ChildProcessWithoutNullStreams | SpawnSyncReturns<Buffer>> = { | 
					
						
							|  |  |  |     win32: () => spawn("cmd", ["/c", "start", filePath]), | 
					
						
							|  |  |  |     darwin: () => spawnSync("open", [filePath]), | 
					
						
							|  |  |  |     linux: () => spawnSync("xdg-open", [filePath]), | 
					
						
							|  |  |  |     freebsd: () => spawnSync("xdg-open", [filePath]), | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  |   const command = openFileCommand[process.platform]; | 
					
						
							|  |  |  |   if (command) command(); | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     console.log("Unsupported platform. Open the file manually please."); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inquirer.prompt<TAnswer>(questions).then((answers) => { | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  |   // Process the answer
 | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  |   const { year, month, day } = getCurrentTime(); | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  |   const title = titleCase(answers.inputTitle); | 
					
						
							|  |  |  |   const subtitle = titleCase(answers.inputSubtitle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const tags = _.uniq( | 
					
						
							|  |  |  |     answers.inputTags | 
					
						
							|  |  |  |       .split(",") | 
					
						
							|  |  |  |       .map((tag) => tag.trim()) | 
					
						
							|  |  |  |       .filter((tag) => tag !== ""), | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   if (tags.length === 0) tags.push("others"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const pin = answers.inputPin; | 
					
						
							|  |  |  |   const noPrompt = answers.inputNoPrompt; | 
					
						
							|  |  |  |   const allowShare = answers.inputAllowShare; | 
					
						
							|  |  |  |   const time = `${year}-${month}-${day}`; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Stringify the frontmatters
 | 
					
						
							|  |  |  |   const stringifiedFrontmatter = stringifyFrontmatter({ | 
					
						
							|  |  |  |     title: title, | 
					
						
							|  |  |  |     subtitle: subtitle, | 
					
						
							|  |  |  |     summary: "", | 
					
						
							|  |  |  |     coverURL: null, | 
					
						
							|  |  |  |     time: time, | 
					
						
							|  |  |  |     tags: tags, | 
					
						
							|  |  |  |     pin: pin, | 
					
						
							|  |  |  |     noPrompt: noPrompt, | 
					
						
							|  |  |  |     allowShare: allowShare, | 
					
						
							|  |  |  |     closed: false, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Output the new post file
 | 
					
						
							|  |  |  |   const postFileName = `${year}-${month}-${day}-${_.kebabCase(answers.inputTitle)}.md`; | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  |   const postFilePath = path.resolve(path.join(PostFilesDirectory, postFileName)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-26 07:31:22 +08:00
										 |  |  |   writePostFile(postFilePath, `${stringifiedFrontmatter}\n`); | 
					
						
							|  |  |  |   openPostFile(postFilePath); | 
					
						
							| 
									
										
										
										
											2024-08-12 13:53:28 +08:00
										 |  |  | }); |