Fork of Chiri for Astro for my blog
1/**
2 * Create a new post with frontmatter
3 * Usage: pnpm new <title>
4 */
5
6import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
7import { dirname, join } from 'node:path'
8import process from 'node:process'
9
10// Process title from all arguments
11const titleArgs: string[] = process.argv.slice(2)
12const rawTitle: string = titleArgs.length > 0 ? titleArgs.join(' ') : 'new-post'
13
14// Check if title starts with underscore (draft post)
15const isDraft: boolean = rawTitle.startsWith('_')
16const displayTitle: string = isDraft ? rawTitle.slice(1) : rawTitle
17
18const fileName: string = rawTitle
19 .toLowerCase()
20 .replace(/[^a-z0-9\s-_]/g, '') // Remove special characters but keep underscore and hyphen
21 .replace(/\s+/g, '-') // Replace spaces with hyphens
22 .replace(/-+/g, '-') // Replace multiple hyphens with single
23 .replace(/^-|-$/g, '') // Remove leading/trailing hyphens
24const targetFile: string = `${fileName}.md`
25const fullPath: string = join('src/content/posts', targetFile)
26
27// Check if the target file already exists
28if (existsSync(fullPath)) {
29 console.error(`😇 File already exists: ${fullPath}`)
30 process.exit(1)
31}
32
33// Ensure the directory structure exists
34mkdirSync(dirname(fullPath), { recursive: true })
35
36// Generate frontmatter with current date
37const content: string = `---
38title: ${displayTitle}
39pubDate: '${new Date().toISOString().split('T')[0]}'
40---
41
42`
43
44// Write the new post file
45try {
46 writeFileSync(fullPath, content)
47 if (isDraft) {
48 console.log(`📝 Draft created: ${fullPath}`)
49 } else {
50 console.log(`✅ Post created: ${fullPath}`)
51 }
52} catch (error) {
53 console.error('⚠️ Failed to create post:', error)
54 process.exit(1)
55}