Refactor project for i18n support: Rename project to "i18n-translator" and update package.json and package-lock.json accordingly. Enhance localization by integrating translation functions across various components, including AddToCartButton, Content, GoogleLoginButton, and others, to provide dynamic text rendering based on user language preferences. Update localization files for multiple languages, ensuring comprehensive support for internationalization.

This commit is contained in:
sebseb7
2025-07-16 05:59:48 +02:00
parent 859a2c06d8
commit 51471d4a55
33 changed files with 3949 additions and 13945 deletions

340
translate-i18n.js Executable file
View File

@@ -0,0 +1,340 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const OpenAI = require('openai');
// Configuration
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
const LOCALES_DIR = './src/i18n/locales';
const GERMAN_FILE = path.join(LOCALES_DIR, 'de/translation.js');
const ENGLISH_FILE = path.join(LOCALES_DIR, 'en/translation.js');
// Model configuration
const GERMAN_TO_ENGLISH_MODEL = 'gpt-4.1'; // High-quality model for German -> English (critical step)
const ENGLISH_TO_OTHER_MODEL = 'gpt-4.1-mini'; // Faster/cheaper model for English -> Other languages
// Supported languages for translation
const TARGET_LANGUAGES = {
'bg': 'Bulgarian',
'cs': 'Czech',
'es': 'Spanish',
'fr': 'French',
'el': 'Greek',
'hr': 'Croatian',
'hu': 'Hungarian',
'it': 'Italian',
'pl': 'Polish',
'ro': 'Romanian',
'ru': 'Russian',
'sk': 'Slovak',
'sl': 'Slovenian',
'sr': 'Serbian',
'sv': 'Swedish',
'tr': 'Turkish',
'uk': 'Ukrainian',
'ar': 'Arabic (Egyptian)',
'zh': 'Chinese (Simplified)'
};
// Initialize OpenAI client
const openai = new OpenAI({
apiKey: OPENAI_API_KEY,
});
// System prompt for German to English translation
const GERMAN_TO_ENGLISH_SYSTEM_PROMPT = `
You MUST translate German strings to English AND add the original German text as a comment after EVERY translated string.
CRITICAL REQUIREMENT: Every translated string must have the original German text as a comment.
Rules:
1. Translate all German strings to English
2. MANDATORY: Add the original German text as a comment after EVERY translated string using // format
3. Preserve all existing comments from the German version
4. Maintain the exact JavaScript object structure and formatting
5. Keep all interpolation variables like {{count}}, {{vat}}, etc. unchanged
6. Keep locale codes appropriate for English
7. For the locale section, use "en-US" as code
8. Do not translate technical terms that are already in English
9. Preserve any special formatting or HTML entities
10. Return a valid JavaScript object (not JSON) that can be exported
MANDATORY FORMAT for every string:
"englishTranslation": "English Translation", // Original German Text
Examples:
"login": "Login", // Anmelden
"email": "Email", // E-Mail
"password": "Password", // Passwort
"home": "Home", // Startseite
DO NOT output any string without its German comment. Every single translated string needs the German original as a comment.
`;
// System prompt template for English to other languages (file content will be inserted)
const ENGLISH_TO_OTHER_SYSTEM_PROMPT_TEMPLATE = `
Translate the English strings in the following file to {{targetLanguage}}, preserving the German comments.
Rules:
1. Translate only the English strings to {{targetLanguage}}
2. Keep all German comments unchanged
3. Maintain the exact JavaScript object structure and formatting
4. Keep all interpolation variables like {{count}}, {{vat}}, etc. unchanged
5. Update locale code appropriately for the target language
6. Do not translate technical terms, API keys, or code-related strings
7. Preserve any special formatting or HTML entities
8. Keep existing comments from the English version
9. Return a valid JavaScript object (not JSON) that can be exported
Here is the English translation file to translate:
{{englishFileContent}}
`;
// Function to read and parse JavaScript export file
function readTranslationFile(filePath) {
try {
const content = fs.readFileSync(filePath, 'utf8');
// Remove the export default and evaluate the object
const objectContent = content.replace(/^export default\s*/, '').replace(/;\s*$/, '');
return eval(`(${objectContent})`);
} catch (error) {
console.error(`Error reading ${filePath}:`, error.message);
return null;
}
}
// Function to write translation file (preserving comments as string)
function writeTranslationFile(filePath, translationString) {
try {
// Ensure directory exists
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
// Ensure the string has proper export format
const content = translationString.startsWith('export default')
? translationString
: `export default ${translationString}`;
// Ensure it ends with semicolon and newline
const finalContent = content.endsWith(';\n') ? content : content.replace(/;?\s*$/, ';\n');
fs.writeFileSync(filePath, finalContent, 'utf8');
console.log(`✅ Successfully wrote ${filePath}`);
} catch (error) {
console.error(`Error writing ${filePath}:`, error.message);
}
}
// Function to translate content using OpenAI (for German to English)
async function translateContent(content, systemPrompt, targetLanguage = null, model = 'gpt-4') {
try {
const prompt = targetLanguage
? systemPrompt.replace(/{{targetLanguage}}/g, targetLanguage)
: systemPrompt;
const response = await openai.chat.completions.create({
model: model,
messages: [
{ role: 'system', content: prompt },
{ role: 'user', content: `Please translate this translation file content:\n\n${content}` }
],
temperature: 0.1,
max_tokens: 4000
});
return response.choices[0].message.content;
} catch (error) {
console.error('OpenAI API error:', error.message);
throw error;
}
}
// Function to translate English to other languages (optimized for caching)
async function translateToTargetLanguage(englishContent, targetLanguage, model = 'gpt-4o-mini') {
try {
// Create system prompt with file content (cacheable)
const systemPrompt = ENGLISH_TO_OTHER_SYSTEM_PROMPT_TEMPLATE
.replace(/{{targetLanguage}}/g, targetLanguage)
.replace(/{{englishFileContent}}/g, englishContent);
const response = await openai.chat.completions.create({
model: model,
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: `Please translate to ${targetLanguage}` }
],
temperature: 0.1,
max_tokens: 4000
});
return response.choices[0].message.content;
} catch (error) {
console.error('OpenAI API error:', error.message);
throw error;
}
}
// Function to extract JavaScript object string from OpenAI response (preserving comments)
function extractJSObjectString(response) {
try {
// Remove code block markers if present
let cleaned = response.replace(/```javascript|```json|```/g, '').trim();
// Try to find the object in the response
const objectMatch = cleaned.match(/\{[\s\S]*\}/);
if (objectMatch) {
return objectMatch[0];
}
// If no object found, return the cleaned response
return cleaned;
} catch (error) {
console.error('Error parsing OpenAI response:', error.message);
console.log('Response was:', response);
return null;
}
}
// Main translation function
async function translateToEnglish() {
console.log(`🔄 Step 1: Translating German to English using ${GERMAN_TO_ENGLISH_MODEL}...`);
// Read German translation file
const germanContent = fs.readFileSync(GERMAN_FILE, 'utf8');
try {
const translatedContent = await translateContent(germanContent, GERMAN_TO_ENGLISH_SYSTEM_PROMPT, null, GERMAN_TO_ENGLISH_MODEL);
const englishObjectString = extractJSObjectString(translatedContent);
if (englishObjectString) {
writeTranslationFile(ENGLISH_FILE, englishObjectString);
console.log('✅ German to English translation completed');
return englishObjectString;
} else {
throw new Error('Failed to parse English translation');
}
} catch (error) {
console.error('❌ Error translating to English:', error.message);
return null;
}
}
// Function to translate English to other languages
async function translateToOtherLanguages(englishObjectString) {
console.log(`🔄 Step 2: Translating English to other languages using ${ENGLISH_TO_OTHER_MODEL}...`);
const englishContent = `export default ${englishObjectString};`;
for (const [langCode, langName] of Object.entries(TARGET_LANGUAGES)) {
try {
console.log(`🔄 Translating to ${langName} (${langCode})...`);
const translatedContent = await translateToTargetLanguage(
englishContent,
langName,
ENGLISH_TO_OTHER_MODEL
);
const translatedObjectString = extractJSObjectString(translatedContent);
if (translatedObjectString) {
// Update locale code in the string
const updatedString = translatedObjectString.replace(
/"code":\s*"[^"]*"/,
`"code": "${getLocaleCode(langCode)}"`
);
const targetFile = path.join(LOCALES_DIR, `${langCode}/translation.js`);
writeTranslationFile(targetFile, updatedString);
console.log(`${langName} translation completed`);
} else {
console.error(`❌ Failed to parse ${langName} translation`);
}
// Add delay to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
console.error(`❌ Error translating to ${langName}:`, error.message);
}
}
}
// Helper function to get locale codes
function getLocaleCode(langCode) {
const localeCodes = {
'bg': 'bg-BG',
'cs': 'cs-CZ',
'es': 'es-ES',
'fr': 'fr-FR',
'el': 'el-GR',
'hr': 'hr-HR',
'hu': 'hu-HU',
'it': 'it-IT',
'pl': 'pl-PL',
'ro': 'ro-RO',
'ru': 'ru-RU',
'sk': 'sk-SK',
'sl': 'sl-SI',
'sr': 'sr-RS',
'sv': 'sv-SE',
'tr': 'tr-TR',
'uk': 'uk-UA',
'ar': 'ar-EG',
'zh': 'zh-CN'
};
return localeCodes[langCode] || `${langCode}-${langCode.toUpperCase()}`;
}
// Main execution
async function main() {
console.log('🚀 Starting translation process...');
// Check if OpenAI API key is set
if (!OPENAI_API_KEY) {
console.error('❌ OPENAI_API_KEY environment variable is not set');
console.log('Please set your OpenAI API key: export OPENAI_API_KEY="your-api-key-here"');
process.exit(1);
}
// Check if German file exists
if (!fs.existsSync(GERMAN_FILE)) {
console.error(`❌ German translation file not found: ${GERMAN_FILE}`);
process.exit(1);
}
try {
// Step 1: Translate German to English
const englishObjectString = await translateToEnglish();
if (englishObjectString) {
// Step 2: Translate English to other languages
await translateToOtherLanguages(englishObjectString);
console.log('🎉 All translations completed successfully!');
} else {
console.error('❌ Failed to create English translation, stopping process');
}
} catch (error) {
console.error('❌ Translation process failed:', error.message);
process.exit(1);
}
}
// Run the script
if (require.main === module) {
main();
}
module.exports = {
translateToEnglish,
translateToOtherLanguages,
readTranslationFile,
writeTranslationFile
};