@ngneat/transloco
Version:
The internationalization (i18n) library for Angular
77 lines (67 loc) • 2.39 kB
text/typescript
import { Rule, Tree, SchematicContext } from '@angular-devkit/schematics';
import { TranslationFileFormat } from '../types';
import {
getTranslationsRoot,
getTranslationEntryPaths,
getTranslationFiles,
hasFiles,
setFileContent,
hasSubdirs,
getTranslationKey
} from '../utils/transloco';
import { SchemaOptions } from './schema';
type Parser = (content: string) => any;
function reduceTranslations(host: Tree, dirPath: string, translationJson, lang: string, key = '') {
const dir = host.getDir(dirPath);
if (!hasFiles(dir)) return translationJson;
dir.subfiles
.filter(fileName => fileName.includes(`${lang}.json`))
.forEach(fileName => {
if (!translationJson[key]) {
return translationJson;
}
setFileContent(host, dir.path, fileName, translationJson[key]);
delete translationJson[key];
});
if (hasSubdirs(dir)) {
dir.subdirs.forEach(subDirName => {
const subDir = dir.dir(subDirName);
const nestedKey = getTranslationKey(key, subDirName);
reduceTranslations(host, subDir.path, translationJson, lang, nestedKey);
});
}
return translationJson;
}
function parserFactory(format: TranslationFileFormat): Parser {
switch (format) {
case TranslationFileFormat.JSON:
return JSON.parse;
case TranslationFileFormat.PO:
// TODO:
// return jsonBuilder;
case TranslationFileFormat.XLIFF:
// TODO:
// return jsonBuilder;
default:
return JSON.parse;
}
}
export default function(options: SchemaOptions): Rule {
return (host: Tree, context: SchematicContext) => {
const root = getTranslationsRoot(host, options);
const parser = parserFactory(options.format);
const translatedFiles = getTranslationFiles(host, options.source, parser);
const translationEntryPaths = getTranslationEntryPaths(host, root);
const newTranslation = {};
translatedFiles.forEach(t => {
newTranslation[t.lang] = translationEntryPaths.reduce((acc, path) => {
return reduceTranslations(host, path.path, t.translation, t.lang, path.scope);
}, t.translation);
});
host.getDir(root).subfiles.forEach(fileName => {
const lang = fileName.split('.')[0];
setFileContent(host, root, fileName, newTranslation[lang]);
});
return host;
};
}