126 lines
3.6 KiB
TypeScript
126 lines
3.6 KiB
TypeScript
#!/usr/bin/env node
|
|
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import { glob } from 'glob';
|
|
|
|
class FrontmatterFixer {
|
|
private docsRoot: string;
|
|
|
|
constructor(docsRoot: string) {
|
|
this.docsRoot = docsRoot;
|
|
}
|
|
|
|
async fixAllFrontmatter(): Promise<void> {
|
|
console.log('🔧 Correction 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();
|
|
const value = line.substring(colonIndex + 1).trim();
|
|
|
|
// Si la valeur contient des caractères spéciaux YAML, l'entourer de guillemets
|
|
if (this.needsQuotes(value)) {
|
|
fixedLines.push(`${key}: "${value}"`);
|
|
} else {
|
|
fixedLines.push(line);
|
|
}
|
|
}
|
|
|
|
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 des frontmatter...');
|
|
|
|
try {
|
|
await this.fixAllFrontmatter();
|
|
console.log('✅ Correction 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 FrontmatterFixer(docsRoot);
|
|
fixer.run();
|
|
}
|
|
|
|
export { FrontmatterFixer };
|