#!/usr/bin/env node import * as fs from 'fs'; import * as path from 'path'; import { glob } from 'glob'; class FrontmatterFixerV2 { private docsRoot: string; constructor(docsRoot: string) { this.docsRoot = docsRoot; } async fixAllFrontmatter(): Promise { console.log('🔧 Correction avancée des frontmatter YAML...'); const patterns = [ 'current/**/*.md', 'vision/**/*.md' ]; const allFiles: string[] = []; for (const pattern of patterns) { const files = await glob(pattern, { cwd: this.docsRoot }); allFiles.push(...files); } console.log(`📄 ${allFiles.length} fichiers à vérifier`); let fixedCount = 0; for (const file of allFiles) { const fullPath = path.join(this.docsRoot, file); const content = fs.readFileSync(fullPath, 'utf-8'); const fixedContent = this.fixFrontmatter(content); if (fixedContent !== content) { fs.writeFileSync(fullPath, fixedContent); console.log(`✅ Corrigé: ${file}`); fixedCount++; } } console.log(`🎉 ${fixedCount} fichiers corrigés!`); } private fixFrontmatter(content: string): string { const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n/; const match = content.match(frontmatterRegex); if (!match) return content; const frontmatterText = match[1]; const lines = frontmatterText.split('\n'); const fixedLines: string[] = []; for (const line of lines) { if (line.trim() === '') { fixedLines.push(line); continue; } const colonIndex = line.indexOf(':'); if (colonIndex === -1) { fixedLines.push(line); continue; } const key = line.substring(0, colonIndex).trim(); let value = line.substring(colonIndex + 1).trim(); // Nettoyer les guillemets doubles imbriqués if (value.startsWith('""') && value.endsWith('""')) { value = value.slice(2, -2); } else if (value.startsWith('"') && value.endsWith('"')) { value = value.slice(1, -1); } // Si la valeur contient des caractères spéciaux YAML, l'entourer de guillemets simples if (this.needsQuotes(value)) { fixedLines.push(`${key}: '${value}'`); } else { fixedLines.push(`${key}: ${value}`); } } const fixedFrontmatter = fixedLines.join('\n'); return content.replace(frontmatterRegex, `---\n${fixedFrontmatter}\n---\n`); } private needsQuotes(value: string): boolean { // Caractères qui nécessitent des guillemets en YAML const specialChars = [':', '#', '@', '&', '*', '!', '|', '>', '[', ']', '{', '}', ',', '?', '`', '"', "'", '\\']; // Si la valeur commence ou finit par un espace if (value !== value.trim()) return true; // Si la valeur contient des caractères spéciaux if (specialChars.some(char => value.includes(char))) return true; // Si la valeur commence par des caractères spéciaux YAML if (value.startsWith('!') || value.startsWith('&') || value.startsWith('*')) return true; // Si la valeur ressemble à un booléen ou un nombre mais n'en est pas un if (value === 'true' || value === 'false' || value === 'null') return false; if (!isNaN(Number(value))) return false; return false; } async run(): Promise { console.log('🔧 Démarrage de la correction avancée des frontmatter...'); try { await this.fixAllFrontmatter(); console.log('✅ Correction avancée des frontmatter terminée!'); } catch (error) { console.error('❌ Erreur lors de la correction des frontmatter:', error); process.exit(1); } } } // Exécution du script if (require.main === module) { const docsRoot = process.argv[2] || path.join(__dirname, '..'); const fixer = new FrontmatterFixerV2(docsRoot); fixer.run(); } export { FrontmatterFixerV2 };