UNPKG

@ngneat/transloco

Version:

The internationalization (i18n) library for Angular

104 lines (92 loc) 3.51 kB
import { Rule, Tree, SchematicContext, SchematicsException, EmptyTree } from '@angular-devkit/schematics'; import { TranslationFileFormat } from '../types'; import { getTranslationsRoot, getTranslationFiles, getTranslationEntryPaths, hasFiles, getJsonFileContent, hasSubdirs, getTranslationKey, getDefaultLang } from '../utils/transloco'; import { SchemaOptions } from './schema'; import { normalize } from '@angular-devkit/core'; const fs = require('fs-extra'); type Builder = (tree: Tree, path: string, content: Object) => void; function reduceTranslations(host: Tree, dirPath: string, translationJson, lang: string, key = '') { const dir = host.getDir(dirPath); if (!fs.existsSync(dirPath)) { throw new SchematicsException(`Could not resolve path to dir: ${dirPath}`); } if (!hasFiles(dir) && !hasSubdirs(dir)) return translationJson; dir.subfiles .filter(fileName => fileName.includes(`${lang}.json`)) .forEach(fileName => { if (translationJson[key]) { throw new SchematicsException( `key: ${key} already exist in translation file, please rename it and rerun the command.` ); } translationJson[key] = getJsonFileContent(fileName, dir); }); if (hasSubdirs(dir)) { dir.subdirs.forEach(subDirName => { const subDir = dir.dir(subDirName); const nestedKey = getTranslationKey(key, subDirName); reduceTranslations(host, normalize(subDir.path).substr(1), translationJson, lang, nestedKey); }); } return translationJson; } function deletePrevFiles(host: Tree, options: SchemaOptions) { if (fs.existsSync(options.outDir)) { fs.removeSync(options.outDir); } } const jsonBuilder: Builder = (tree: Tree, path: string, content: Object) => { tree.create(`${path}.json`, JSON.stringify(content, null, 2)); }; function builderFactory(format: TranslationFileFormat): Builder { switch (format) { case TranslationFileFormat.JSON: return jsonBuilder; case TranslationFileFormat.PO: // TODO: return jsonBuilder; case TranslationFileFormat.XLIFF: // TODO: return jsonBuilder; default: return jsonBuilder; } } export default function(options: SchemaOptions): Rule { return (host: Tree, context: SchematicContext) => { deletePrevFiles(host, options); const root = getTranslationsRoot(host, options); const defaultLang = getDefaultLang(options); if (!options.includeDefaultLang && !defaultLang) { throw new SchematicsException( `Please specify the default project's language using --default-Lang or in transloco.config.js file.` ); } let rootTranslations = getTranslationFiles(host, root); const translationEntryPaths = getTranslationEntryPaths(host, root); if (!options.includeDefaultLang) { rootTranslations = rootTranslations.filter(t => t.lang !== defaultLang); } const output = rootTranslations.map(t => ({ lang: t.lang, translation: translationEntryPaths.reduce((acc, entryPath) => { return reduceTranslations(host, entryPath.path, t.translation, t.lang, entryPath.scope); }, t.translation) })); const treeSource = new EmptyTree(); const builder = builderFactory(options.format); output.forEach(o => { builder(treeSource, `${options.outDir}/${o.lang}`, o.translation); }); return treeSource; }; }