Files
octto-engenharia/frontend/scripts/translateSlug.cjs

127 lines
3.2 KiB
JavaScript

const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
const LIBRETRANSLATE_URL = process.env.LIBRETRANSLATE_URL || 'https://libretranslate.stackbyte.cloud';
const TARGET_LOCALES = ['en', 'es'];
const SKIP_KEYS = ['icon', 'image', 'img', 'url', 'href', 'id', 'slug', 'src', 'email', 'phone', 'whatsapp', 'link', 'linkText'];
async function translateText(text, targetLang) {
if (!text || typeof text !== 'string' || text.trim() === '' || targetLang === 'pt') {
return text;
}
const cached = await prisma.translation.findUnique({
where: {
sourceText_sourceLang_targetLang: {
sourceText: text,
sourceLang: 'pt',
targetLang,
},
},
});
if (cached) {
return cached.translatedText;
}
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) {
console.warn(`Translation API error (${targetLang}): ${response.status}`);
return text;
}
const data = await response.json();
const translatedText = data.translatedText || text;
await prisma.translation.upsert({
where: {
sourceText_sourceLang_targetLang: {
sourceText: text,
sourceLang: 'pt',
targetLang,
},
},
update: { translatedText },
create: {
sourceText: text,
sourceLang: 'pt',
targetLang,
translatedText,
},
});
return translatedText;
}
async function translateContent(content, targetLang) {
if (targetLang === 'pt') return content;
if (typeof content === 'string') {
return 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)) {
if (SKIP_KEYS.includes(key)) {
result[key] = value;
} else {
result[key] = await translateContent(value, targetLang);
}
}
return result;
}
return content;
}
async function main() {
const slug = process.argv[2];
if (!slug) {
console.error('Usage: node scripts/translateSlug.cjs <slug>');
process.exit(1);
}
const ptPage = await prisma.pageContent.findUnique({
where: { slug_locale: { slug, locale: 'pt' } },
});
if (!ptPage) {
console.error(`Slug "${slug}" not found in locale PT.`);
process.exit(1);
}
for (const locale of TARGET_LOCALES) {
console.log(`Translating ${slug} -> ${locale.toUpperCase()}...`);
const translatedContent = await translateContent(ptPage.content, locale);
await prisma.pageContent.upsert({
where: { slug_locale: { slug, locale } },
update: { content: translatedContent },
create: { slug, locale, content: translatedContent },
});
console.log(`${locale.toUpperCase()} done.`);
}
}
main()
.catch((err) => {
console.error(err);
process.exitCode = 1;
})
.finally(async () => {
await prisma.$disconnect();
});