UNPKG

@jsverse/transloco-keys-manager

Version:

Extract translatable keys from projects that uses Transloco

110 lines 4.3 kB
import { getGlobalConfig } from '@jsverse/transloco-utils'; import df from 'deep-diff'; import { flatten, unflatten } from 'flat'; import { messages } from '../messages.js'; import { readFile, writeFile } from '../utils/file.utils.js'; import { getLogger } from '../utils/logger.js'; import { getScopeAndLangFromPath } from '../utils/path.utils.js'; import { buildTable } from './build-table.js'; import { getTranslationFilesPath } from './get-translation-files-path.js'; import { normalizedGlob } from '../utils/normalize-glob-path.js'; export function compareKeysToFiles({ scopeToKeys, translationsPath, addMissingKeys, emitErrorOnExtraKeys, fileFormat, unflat, }) { const logger = getLogger(); logger.startSpinner(`${messages.checkMissing} ✨`); const diffsPerLang = {}; /** An array of the existing translation files paths */ const translationFiles = getTranslationFilesPath(translationsPath, fileFormat); let result = []; const scopePaths = getGlobalConfig().scopePathMap || {}; for (const [scope, path] of Object.entries(scopePaths)) { const keys = scopeToKeys[scope]; if (keys) { const res = { keys, scope, baseFilesPath: path, }; result.push({ ...res, files: normalizedGlob(`${res.baseFilesPath}/*.${fileFormat}`), }); } } const cache = {}; for (const filePath of translationFiles) { const { scope = '__global' } = getScopeAndLangFromPath({ filePath, translationsPath, fileFormat, }); if (cache[scope]) { continue; } cache[scope] = true; const keys = scope ? scopeToKeys[scope] : scopeToKeys.__global; if (keys) { const isGlobal = scope === '__global'; const res = { keys, scope, baseFilesPath: translationsPath, }; result.push({ ...res, files: normalizedGlob(`${res.baseFilesPath}/${isGlobal ? '' : scope}/*.${fileFormat}`), }); } } for (const { files, keys, scope, baseFilesPath } of result) { for (const filePath of files) { const { lang } = getScopeAndLangFromPath({ filePath, translationsPath: baseFilesPath, fileFormat, }); const translation = readFile(filePath, { parse: true }); // We always build the keys flatten, so we need to make sure we compare to a flat file const flat = flatten(translation, { safe: true, }); // Compare the current file with the extracted keys const differences = df.diff(flat, keys); if (differences) { const langPath = `${scope !== '__global' ? scope + '/' : ''}${lang}`; diffsPerLang[langPath] = { missing: [], extra: [], }; for (const diff of differences) { if (diff.kind === 'N') { diffsPerLang[langPath].missing.push(diff); if (addMissingKeys) { df.applyChange(translation, keys, diff); } } else if (diff.kind === 'D') { const isComment = diff.path.join('.').endsWith('.comment'); if (!isComment) { diffsPerLang[langPath].extra.push(diff); } } } if (addMissingKeys) { writeFile(filePath, unflat ? unflatten(translation) : translation); } } } } logger.success(`${messages.checkMissing} ✨`); const langs = Object.keys(diffsPerLang).filter((lang) => { const { missing, extra } = diffsPerLang[lang]; return missing.length || extra.length; }); buildTable({ langs, diffsPerLang, addMissingKeys, emitErrorOnExtraKeys, }); } //# sourceMappingURL=compare-keys-to-files.js.map