veza/veza-docs/scripts/fix_frontmatter_v2.ts

133 lines
3.9 KiB
TypeScript

#!/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<void> {
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<void> {
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 };