auto-translatr
Version:
An automatic translation library
108 lines (107 loc) • 5.59 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { createTranslator } from './createTranslator';
import { isLeft, left, liftAsync, right } from './utils';
export const readTranslations = (reader) => __awaiter(void 0, void 0, void 0, function* () {
try {
console.log('📖 Reading translations...');
const result = yield reader();
if (isLeft(result)) {
console.log('❌ Failed to read translations:', result.value.message);
}
else {
const languageCount = Object.keys(result.value).length;
console.log(`✅ Successfully read translations for ${languageCount} languages`);
}
return result;
}
catch (error) {
console.log('❌ Error reading translations:', error.message);
return left(error);
}
});
export const getMissingTranslations = (defaultTranslations, targetTranslations) => {
const missingTranslationKeys = Object.keys(defaultTranslations).filter(key => !targetTranslations[key]);
return missingTranslationKeys.reduce((acc, key) => {
acc[key] = defaultTranslations[key];
return acc;
}, {});
};
export const extractDefaultAndOthers = (defaultLanguage, translations) => ({
default: { language: defaultLanguage, translations: translations[defaultLanguage] },
others: Object.keys(translations)
.filter(language => language !== defaultLanguage)
.map(language => ({ language, translations: translations[language] }))
});
export const extractMissingTranslations = (translations) => {
console.log(`🎯 Extracting missing translations for ${translations.others.length} target languages`);
var missingTranslations = translations.others.map(other => {
const missing = getMissingTranslations(translations.default.translations, other.translations);
const missingCount = Object.keys(missing).length;
if (missingCount > 0) {
console.log(`📝 Language '${other.language}': ${missingCount} missing translations`);
}
return {
language: other.language,
translations: missing
};
});
console.log(`🔍 Found ${missingTranslations.flatMap(x => Object.keys(x.translations)).length} missing translation keys`);
return missingTranslations;
};
export const addTranslator = (defaultLanguage, translator) => (translation) => (Object.assign(Object.assign({}, translation), { translate: createTranslator(defaultLanguage, translation.language, translator) }));
export const translate = (translation) => {
const { translations, translate } = translation;
const totalKeys = Object.keys(translations).length;
if (totalKeys === 0) {
return Promise.resolve(right({ language: translation.language, translations: {} }));
}
console.log(`🌐 Starting translation for '${translation.language}' (${totalKeys} keys)`);
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
try {
const translated = {};
let completedKeys = 0;
for (const key of Object.keys(translations)) {
const translatedText = yield translate(translations[key]);
translated[key] = translatedText;
completedKeys++;
}
console.log(`🎉 Finished translating '${translation.language}' (${completedKeys} keys completed)`);
resolve(right({ language: translation.language, translations: translated }));
}
catch (error) {
console.log(`❌ Translation failed for '${translation.language}':`, error.message);
reject(error);
}
}));
};
export const addMissingTranslations = (defaultLanguage, dependencies) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`🚀 Starting translation process with default language: '${defaultLanguage}'`);
const result = yield liftAsync(() => readTranslations(dependencies.reader))
.map(translations => extractDefaultAndOthers(defaultLanguage, translations))
.map(extractMissingTranslations)
.map(missingTranslations => {
if (missingTranslations.every(t => Object.keys(t.translations).length === 0)) {
console.log('✅ All translations are up to date!');
return [];
}
return missingTranslations;
})
.map(missingTranslations => missingTranslations.map(addTranslator(defaultLanguage, dependencies.translator)))
.flatMapAll(missingTranslationsWithTranslator => missingTranslationsWithTranslator.map(translate))
.flatMapAllVoid(translatedTranslations => translatedTranslations.map(t => dependencies.writer({ [t.language]: t.translations })))
.result();
if (isLeft(result)) {
console.error('💥 Translation process failed:', result.value);
}
else {
console.log('🎊 Translation process completed successfully!');
}
});