Files
octto-engenharia/frontend/prisma/translate-pages.mjs

148 lines
4.0 KiB
JavaScript

// Script para traduzir todas as páginas PT para EN e ES
// Executar: node prisma/translate-pages.mjs
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const LIBRETRANSLATE_URL = process.env.LIBRETRANSLATE_URL || 'https://libretranslate.stackbyte.cloud';
const SUPPORTED_LOCALES = ['en', 'es'];
// Traduzir um texto
async function translateText(text, targetLang) {
if (!text || text.trim() === '' || targetLang === 'pt') return text;
// Verificar cache no banco primeiro
const cached = await prisma.translation.findUnique({
where: {
sourceText_sourceLang_targetLang: {
sourceText: text,
sourceLang: 'pt',
targetLang: targetLang,
},
},
});
if (cached) {
console.log(` [cache] "${text.substring(0, 25)}..."`);
return cached.translatedText;
}
try {
console.log(` [traduzindo] "${text.substring(0, 25)}..." -> ${targetLang}`);
const response = await fetch(`${LIBRETRANSLATE_URL}/translate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ q: text, source: 'pt', target: targetLang, format: 'text' }),
});
if (response.ok) {
const data = await response.json();
const translatedText = data.translatedText || text;
// Salvar no cache
try {
await prisma.translation.create({
data: {
sourceText: text,
sourceLang: 'pt',
targetLang: targetLang,
translatedText,
},
});
} catch {
// Ignorar se já existe
}
return translatedText;
}
} catch (error) {
console.error(` [erro] ${error.message}`);
}
return text;
}
// Traduzir objeto recursivamente
async function translateContent(content, targetLang) {
if (typeof content === 'string') {
return await translateText(content, targetLang);
}
if (Array.isArray(content)) {
const results = [];
for (const item of content) {
results.push(await translateContent(item, targetLang));
}
return results;
}
if (content && typeof content === 'object') {
const result = {};
for (const [key, value] of Object.entries(content)) {
// Não traduzir campos técnicos
if (['icon', 'image', 'img', 'url', 'href', 'id', 'slug', 'src', 'link', 'linkText'].includes(key)) {
result[key] = value;
} else {
result[key] = await translateContent(value, targetLang);
}
}
return result;
}
return content;
}
async function main() {
console.log('🌐 Iniciando tradução de páginas...\n');
console.log(`📡 LibreTranslate: ${LIBRETRANSLATE_URL}\n`);
// Buscar todas as páginas em português
const ptPages = await prisma.pageContent.findMany({
where: { locale: 'pt' }
});
if (ptPages.length === 0) {
console.log('❌ Nenhuma página encontrada em português');
return;
}
console.log(`📄 Encontradas ${ptPages.length} páginas em PT\n`);
for (const page of ptPages) {
console.log(`\n📝 Página: ${page.slug}`);
console.log('─'.repeat(40));
for (const targetLocale of SUPPORTED_LOCALES) {
console.log(`\n 🔄 Traduzindo para ${targetLocale.toUpperCase()}...`);
try {
const translatedContent = await translateContent(page.content, targetLocale);
await prisma.pageContent.upsert({
where: { slug_locale: { slug: page.slug, locale: targetLocale } },
update: { content: translatedContent },
create: { slug: page.slug, locale: targetLocale, content: translatedContent }
});
console.log(`${page.slug} -> ${targetLocale.toUpperCase()} concluído!`);
} catch (error) {
console.error(` ❌ Erro: ${error.message}`);
}
}
}
console.log('\n' + '═'.repeat(40));
console.log('✨ Tradução concluída!');
console.log('═'.repeat(40));
}
main()
.catch((e) => {
console.error('Erro:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});