import fs from "fs"; import path from "path"; import matter from "gray-matter"; import yaml from "js-yaml"; // Configuration const inputDir = "./src/content/post/"; // Folder containing markdown files const backupDir = "./backup"; // Backup before modifying // Create backup directory if it doesn't exist if (!fs.existsSync(backupDir)) { fs.mkdirSync(backupDir); } // Preferred frontmatter key order const preferredKeyOrder = [ "title", "description", "publishDate", "updatedDate", "tags", "slug", "draft", ]; function sortFrontmatterKeys(data) { const sorted = {}; preferredKeyOrder.forEach((key) => { if (data[key] !== undefined) { sorted[key] = data[key]; } }); Object.keys(data).forEach((key) => { if (!sorted.hasOwnProperty(key)) { sorted[key] = data[key]; } }); return sorted; } // Format dates consistently function formatDate(value) { if (value instanceof Date) { return value.toISOString().split("T")[0]; } return value; } // Extract date from filename if present function extractDateFromFilename(filename) { const match = filename.match(/^(\d{4}-\d{2}-\d{2})-(.+)$/); if (match) { return { date: match[1], newFilename: match[2], }; } return null; } // Clean and fix a single file function fixFile(filePath) { const rawContent = fs.readFileSync(filePath, "utf8"); const { data: frontmatter, content } = matter(rawContent); let cleanedFrontmatter = { ...frontmatter }; const fileName = path.basename(filePath); const dateInfo = extractDateFromFilename(fileName); // Move date from filename into publishDate if missing if (dateInfo) { if (!cleanedFrontmatter.publishDate) { cleanedFrontmatter.publishDate = dateInfo.date; } } // Rename "date" -> "publishDate" if necessary if (cleanedFrontmatter.date && !cleanedFrontmatter.publishDate) { cleanedFrontmatter.publishDate = cleanedFrontmatter.date; delete cleanedFrontmatter.date; } // Fix date formats Object.keys(cleanedFrontmatter).forEach((key) => { if (key.toLowerCase().includes("date")) { cleanedFrontmatter[key] = formatDate(cleanedFrontmatter[key]); } }); // If publishDate missing, set draft: true if ( !cleanedFrontmatter.publishDate && cleanedFrontmatter.draft === undefined ) { cleanedFrontmatter.draft = true; } // Sort frontmatter keys cleanedFrontmatter = sortFrontmatterKeys(cleanedFrontmatter); const yamlContent = yaml.dump(cleanedFrontmatter, { lineWidth: 1000, quotingType: '"', }); const finalContent = `---\n${yamlContent}---\n\n${content.trim()}\n`; // Backup original const backupPath = path.join(backupDir, fileName); fs.copyFileSync(filePath, backupPath); // Determine new filename let outputPath = filePath; if (dateInfo) { const newFilename = dateInfo.newFilename; outputPath = path.join(path.dirname(filePath), newFilename); } // Write cleaned file (possibly with new filename) fs.writeFileSync(outputPath, finalContent, "utf8"); // If filename changed, delete the old file if (outputPath !== filePath) { fs.unlinkSync(filePath); console.log(`Fixed & Renamed: ${fileName} -> ${path.basename(outputPath)}`); } else { console.log(`Fixed: ${fileName}`); } } // Process all markdown files function fixAllFiles() { const files = fs.readdirSync(inputDir); files.forEach((file) => { if (file.endsWith(".md")) { fixFile(path.join(inputDir, file)); } }); } fixAllFiles();