|
|
#!/usr/bin/env node |
|
|
|
|
|
import fs from 'fs/promises'; |
|
|
import path from 'path'; |
|
|
import { fileURLToPath } from 'url'; |
|
|
import chalk from 'chalk'; |
|
|
|
|
|
const __filename = fileURLToPath(import.meta.url); |
|
|
const __dirname = path.dirname(__filename); |
|
|
|
|
|
|
|
|
const NEW_PIPE_OUTPUT = path.join(__dirname, 'output'); |
|
|
const PUBLIC_DIR = path.join(__dirname, '../../../public'); |
|
|
const PUBLIC_DATA_DIR = path.join(PUBLIC_DIR, 'data'); |
|
|
|
|
|
|
|
|
const FILES_TO_COPY = [ |
|
|
{ |
|
|
source: 'data/typography_data.json', |
|
|
destination: 'data/typography_data.json', |
|
|
description: 'Données UMAP avec embeddings' |
|
|
}, |
|
|
|
|
|
{ |
|
|
source: 'sprites/font-sprite.svg', |
|
|
destination: 'data/font-sprite.svg', |
|
|
description: 'Sprite SVG avec tous les symboles' |
|
|
} |
|
|
]; |
|
|
|
|
|
|
|
|
const DIRECTORIES_TO_COPY = [ |
|
|
{ |
|
|
source: 'svgs', |
|
|
destination: 'data/sentences', |
|
|
description: 'Sentences SVG individuelles', |
|
|
filter: '*_sentence.svg' |
|
|
}, |
|
|
{ |
|
|
source: 'svgs', |
|
|
destination: 'data/char', |
|
|
description: 'SVGs de la lettre A', |
|
|
filter: '*_a.svg' |
|
|
} |
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function copyFile(sourcePath, destPath, description) { |
|
|
try { |
|
|
await fs.copyFile(sourcePath, destPath); |
|
|
console.log(chalk.green(`✅ ${description}`)); |
|
|
console.log(chalk.blue(` 📁 ${path.relative(PUBLIC_DIR, destPath)}`)); |
|
|
|
|
|
|
|
|
const stats = await fs.stat(destPath); |
|
|
const sizeKB = (stats.size / 1024).toFixed(1); |
|
|
console.log(chalk.gray(` 📊 ${sizeKB} KB\n`)); |
|
|
|
|
|
return true; |
|
|
} catch (error) { |
|
|
console.error(chalk.red(`❌ Error during la copie de ${description}:`), error.message); |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function copyDirectory(sourceDir, destDir, description, filter) { |
|
|
try { |
|
|
|
|
|
await fs.mkdir(destDir, { recursive: true }); |
|
|
|
|
|
|
|
|
const files = await fs.readdir(sourceDir); |
|
|
const filteredFiles = files.filter(file => { |
|
|
if (filter === '*_sentence.svg') { |
|
|
return file.endsWith('_sentence.svg'); |
|
|
} |
|
|
if (filter === '*_a.svg') { |
|
|
return file.endsWith('_a.svg'); |
|
|
} |
|
|
return true; |
|
|
}); |
|
|
|
|
|
console.log(chalk.blue(`🔄 ${description}...`)); |
|
|
console.log(chalk.cyan(` 📁 ${filteredFiles.length} fichiers à copier`)); |
|
|
|
|
|
let copiedCount = 0; |
|
|
let errorCount = 0; |
|
|
|
|
|
for (const file of filteredFiles) { |
|
|
const sourcePath = path.join(sourceDir, file); |
|
|
const destPath = path.join(destDir, file); |
|
|
|
|
|
try { |
|
|
await fs.copyFile(sourcePath, destPath); |
|
|
copiedCount++; |
|
|
|
|
|
if (copiedCount % 100 === 0) { |
|
|
console.log(chalk.gray(` 📋 Copié ${copiedCount}/${filteredFiles.length} fichiers...`)); |
|
|
} |
|
|
} catch (error) { |
|
|
errorCount++; |
|
|
console.log(chalk.red(`❌ Erreur copie ${file}: ${error.message}`)); |
|
|
} |
|
|
} |
|
|
|
|
|
console.log(chalk.green(`✅ ${description}`)); |
|
|
console.log(chalk.blue(` 📁 ${path.relative(PUBLIC_DIR, destDir)}`)); |
|
|
console.log(chalk.cyan(` 📊 ${copiedCount} fichiers copiés, ${errorCount} erreurs\n`)); |
|
|
|
|
|
return { success: true, copied: copiedCount, errors: errorCount }; |
|
|
} catch (error) { |
|
|
console.error(chalk.red(`❌ Erreur lors de la copie du dossier ${description}:`), error.message); |
|
|
return { success: false, copied: 0, errors: 1 }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function checkSourceFile(sourcePath, description) { |
|
|
try { |
|
|
await fs.access(sourcePath); |
|
|
return true; |
|
|
} catch { |
|
|
console.error(chalk.red(`❌ Missing source file: ${description}`)); |
|
|
console.error(chalk.gray(` 📁 ${sourcePath}\n`)); |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function ensureDestinationDir(destPath) { |
|
|
const destDir = path.dirname(destPath); |
|
|
try { |
|
|
await fs.access(destDir); |
|
|
} catch { |
|
|
await fs.mkdir(destDir, { recursive: true }); |
|
|
console.log(chalk.yellow(`📁 Directory created: ${destDir}`)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function displayStats() { |
|
|
console.log(chalk.cyan('📊 Statistics des fichiers copiés:\n')); |
|
|
|
|
|
for (const file of FILES_TO_COPY) { |
|
|
const destPath = path.join(PUBLIC_DIR, file.destination); |
|
|
try { |
|
|
const stats = await fs.stat(destPath); |
|
|
const sizeKB = (stats.size / 1024).toFixed(1); |
|
|
console.log(chalk.white(` ${file.destination}: ${sizeKB} KB`)); |
|
|
} catch { |
|
|
console.log(chalk.red(` ${file.destination}: fichier non trouvé`)); |
|
|
} |
|
|
} |
|
|
console.log(''); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function showExistingFiles() { |
|
|
console.log(chalk.blue('📋 Fichiers existants dans public:\n')); |
|
|
|
|
|
try { |
|
|
const publicFiles = await fs.readdir(PUBLIC_DIR); |
|
|
const fontFiles = publicFiles.filter(file => |
|
|
file.includes('font') || |
|
|
file.includes('typography') || |
|
|
file.includes('sprite') |
|
|
); |
|
|
|
|
|
if (fontFiles.length > 0) { |
|
|
for (const file of fontFiles.sort()) { |
|
|
const filePath = path.join(PUBLIC_DIR, file); |
|
|
try { |
|
|
const stats = await fs.stat(filePath); |
|
|
const sizeKB = (stats.size / 1024).toFixed(1); |
|
|
console.log(chalk.gray(` ${file} (${sizeKB} KB)`)); |
|
|
} catch { |
|
|
console.log(chalk.gray(` ${file}`)); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
console.log(chalk.gray(' Aucun fichier de police trouvé')); |
|
|
} |
|
|
console.log(''); |
|
|
} catch (error) { |
|
|
console.error(chalk.red('❌ Error during la lecture du dossier public:'), error.message); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function cleanupOldData() { |
|
|
console.log(chalk.blue('🧹 Nettoyage des anciennes données...')); |
|
|
|
|
|
try { |
|
|
|
|
|
try { |
|
|
await fs.rm(PUBLIC_DATA_DIR, { recursive: true, force: true }); |
|
|
console.log(chalk.green(`✅ Ancien dossier data supprimé: ${PUBLIC_DATA_DIR}`)); |
|
|
} catch { |
|
|
console.log(chalk.gray(`📁 Dossier data n'existait pas`)); |
|
|
} |
|
|
|
|
|
|
|
|
const oldFiles = [ |
|
|
'typography_data_new.json', |
|
|
'font-sprite-mapping.json', |
|
|
'font-sprite-mapping-new.json', |
|
|
'font-sprite-new.svg' |
|
|
]; |
|
|
|
|
|
for (const file of oldFiles) { |
|
|
const filePath = path.join(PUBLIC_DIR, file); |
|
|
try { |
|
|
await fs.unlink(filePath); |
|
|
console.log(chalk.green(`✅ Ancien fichier supprimé: ${file}`)); |
|
|
} catch { |
|
|
console.log(chalk.gray(`📁 Fichier ${file} n'existait pas`)); |
|
|
} |
|
|
} |
|
|
|
|
|
console.log(''); |
|
|
} catch (error) { |
|
|
console.error(chalk.red('❌ Erreur lors du nettoyage:'), error.message); |
|
|
throw error; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function main() { |
|
|
console.log(chalk.blue.bold('📋 Copying files de données vers l\'application\n')); |
|
|
|
|
|
try { |
|
|
|
|
|
try { |
|
|
await fs.access(PUBLIC_DIR); |
|
|
console.log(chalk.green(`✅ Dossier public trouvé: ${PUBLIC_DIR}`)); |
|
|
} catch { |
|
|
throw new Error(`Dossier public non trouvé: ${PUBLIC_DIR}`); |
|
|
} |
|
|
|
|
|
|
|
|
try { |
|
|
await fs.access(NEW_PIPE_OUTPUT); |
|
|
console.log(chalk.green(`✅ Dossier output trouvé: ${NEW_PIPE_OUTPUT}\n`)); |
|
|
} catch { |
|
|
throw new Error(`Dossier output non trouvé: ${NEW_PIPE_OUTPUT}`); |
|
|
} |
|
|
|
|
|
|
|
|
await cleanupOldData(); |
|
|
|
|
|
|
|
|
await showExistingFiles(); |
|
|
|
|
|
|
|
|
let successCount = 0; |
|
|
let totalCount = FILES_TO_COPY.length; |
|
|
|
|
|
console.log(chalk.cyan('🔄 Copie des fichiers...\n')); |
|
|
|
|
|
for (const file of FILES_TO_COPY) { |
|
|
const sourcePath = path.join(NEW_PIPE_OUTPUT, file.source); |
|
|
const destPath = path.join(PUBLIC_DIR, file.destination); |
|
|
|
|
|
|
|
|
if (!(await checkSourceFile(sourcePath, file.description))) { |
|
|
continue; |
|
|
} |
|
|
|
|
|
|
|
|
await ensureDestinationDir(destPath); |
|
|
|
|
|
|
|
|
if (await copyFile(sourcePath, destPath, file.description)) { |
|
|
successCount++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
console.log(chalk.cyan('🔄 Copie des dossiers...\n')); |
|
|
|
|
|
for (const dir of DIRECTORIES_TO_COPY) { |
|
|
const sourceDir = path.join(NEW_PIPE_OUTPUT, dir.source); |
|
|
const destDir = path.join(PUBLIC_DIR, dir.destination); |
|
|
|
|
|
|
|
|
try { |
|
|
await fs.access(sourceDir); |
|
|
} catch { |
|
|
console.log(chalk.red(`❌ Dossier source manquant: ${dir.description}`)); |
|
|
console.log(chalk.gray(` 📁 ${sourceDir}\n`)); |
|
|
continue; |
|
|
} |
|
|
|
|
|
|
|
|
const result = await copyDirectory(sourceDir, destDir, dir.description, dir.filter); |
|
|
if (result.success) { |
|
|
successCount++; |
|
|
totalCount++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
await displayStats(); |
|
|
|
|
|
console.log(chalk.green.bold('🎉 Copie terminée !')); |
|
|
console.log(chalk.cyan(`📊 Summary:`)); |
|
|
console.log(chalk.white(` - ${successCount}/${totalCount} fichiers copiés avec succès`)); |
|
|
console.log(chalk.white(` - Destination: ${PUBLIC_DATA_DIR}`)); |
|
|
|
|
|
if (successCount === totalCount) { |
|
|
console.log(chalk.green('\n✅ Tous les fichiers ont été copiés avec succès !')); |
|
|
console.log(chalk.blue('💡 Les nouveaux fichiers sont maintenant disponibles dans public/data/')); |
|
|
console.log(chalk.blue('📁 Structure:')); |
|
|
console.log(chalk.white(' - public/data/typography_data.json')); |
|
|
console.log(chalk.white(' - public/data/font-sprite.svg')); |
|
|
console.log(chalk.white(' - public/data/sentences/')); |
|
|
console.log(chalk.white(' - public/data/char/')); |
|
|
} else { |
|
|
console.log(chalk.yellow(`\n⚠️ ${totalCount - successCount} fichier(s) n'ont pas pu être copiés.`)); |
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
console.error(chalk.red('💥 Erreur fatale:'), error.message); |
|
|
process.exit(1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
main(); |
|
|
|