UNPKG

i18n-llm-translate

Version:

Automatically translates namespace-based JSON translation files across multiple languages from any source language

137 lines (136 loc) 7.38 kB
"use strict"; 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.readTranslationsCache = readTranslationsCache; const util_1 = require("./util"); const fs_1 = require("fs"); const path_1 = __importDefault(require("path")); function readTranslationsCache(options) { return __awaiter(this, void 0, void 0, function* () { const baseLanguageCodeKey = (0, util_1.formatLanguageContainerDirectoryName)(options.baseLanguageCode, options); const cachePath = path_1.default.resolve(process.env.PWD, options.languagesDirectoryPath, options.namesMapping.jsonCache); let content = '{}'; try { content = yield fs_1.promises.readFile(cachePath, 'utf-8'); } catch (error) { console.warn(`Translation# Warning: "${cachePath}" not found. Initializing empty JSON.`); } try { content = JSON.parse(content); } catch (error) { console.error(`Translation# Error reading "${cachePath}". File is not a proper JSON!`); } return { cleanCache(namespaces) { let dirty = false; const namespaceFiles = namespaces.map(n => n.jsonFileName); for (let cachedFile in content) { if (!namespaceFiles.includes(cachedFile)) { (0, util_1.logWithColor)('yellow', `Translation# Warning: Namespace file "${cachedFile}" not found. Clearing it from cache`); delete content[cachedFile]; dirty = true; } } return dirty; }, syncCacheWithNamespaces(namespaces, writeNamespaceValues) { function deepCopy(obj) { return JSON.parse(JSON.stringify(obj)); } function walk(cache, baseTranslations, targetLanguagesTranslations) { // Remove keys which are no longer at base translations if (typeof baseTranslations === 'object') for (let cacheKey in cache) { if (cacheKey in baseTranslations) { continue; } delete cache[cacheKey]; console.log(`Translation# Cache# Removed unknown base path key: "${cacheKey}"`); } for (let baseKey in baseTranslations) { const baseValue = baseTranslations[baseKey]; const isTranslation = typeof baseValue === 'string'; let cacheValue = cache[baseKey] || {}; if (isTranslation) { // Remove unknown languages for (let languageCode of Object.keys(cacheValue)) { if (languageCode !== baseLanguageCodeKey && !options.targetLanguageCodes.includes(languageCode)) { delete cacheValue[languageCode]; console.log(`Translation# Cache# Removed unknown language code: "${languageCode}" in "${baseKey}"`); } } cacheValue[baseLanguageCodeKey] = writeNamespaceValues ? baseValue : cacheValue[baseLanguageCodeKey] || ''; for (let targetLanguage of targetLanguagesTranslations) { cacheValue[targetLanguage.languageCode] = writeNamespaceValues ? targetLanguage.translations[baseKey] || '' : cacheValue[targetLanguage.languageCode] || ''; } } else { const deeperTargetLanguages = deepCopy(targetLanguagesTranslations); for (let deeperTargetLanguage of deeperTargetLanguages) { deeperTargetLanguage.translations = deeperTargetLanguage.translations[baseKey] || {}; } cacheValue = walk(cacheValue, baseValue, deeperTargetLanguages); } cache[baseKey] = cacheValue; } return cache; } for (let namespace of namespaces) { const cacheNamespace = content[namespace.jsonFileName] || {}; content[namespace.jsonFileName] = walk(cacheNamespace, deepCopy(namespace.baseLanguageTranslations), deepCopy(namespace.targetLanguages)); } }, getBaseLanguageTranslationDifferences(namespace) { const fileCache = content[namespace.jsonFileName]; if (!fileCache) return namespace.baseLanguageTranslations; function walk(cache, baseTranslations) { var _a; if (typeof baseTranslations !== 'object') { return cache; } const diff = {}; for (const key of Object.keys(baseTranslations)) { if (typeof baseTranslations[key] === "object") { const result = walk(cache[key], baseTranslations[key]); if (result) diff[key] = result; continue; } if (baseTranslations[key] === ((_a = cache[key]) === null || _a === void 0 ? void 0 : _a[baseLanguageCodeKey])) { continue; } diff[key] = baseTranslations[key]; } if (Object.keys(diff).length === 0) return undefined; return diff; } return walk(fileCache, namespace.baseLanguageTranslations); }, write() { return __awaiter(this, void 0, void 0, function* () { yield fs_1.promises.writeFile(cachePath, JSON.stringify(content, null, 4), 'utf-8'); console.log(`Translation# Successfully wrote translations cache`); }); }, }; }); }