UNPKG

ng-extract-i18n-merge

Version:

Extract and merge i18n xliff translation files for angular projects.

114 lines (113 loc) 7.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ngAdd = void 0; const schematics_1 = require("@angular-devkit/schematics"); const workspace_1 = require("@schematics/angular/utility/workspace"); const core_1 = require("@angular-devkit/core"); function getTargetFiles(i18nExtension) { var _a; const locales = (i18nExtension === null || i18nExtension === void 0 ? void 0 : i18nExtension.locales) ? Object.values(i18nExtension === null || i18nExtension === void 0 ? void 0 : i18nExtension.locales) : undefined; const files = locales === null || locales === void 0 ? void 0 : locales.map(locale => typeof locale === 'string' ? locale : selectTargetFile(locale === null || locale === void 0 ? void 0 : locale.translation)); return (_a = files === null || files === void 0 ? void 0 : files.filter(f => f !== undefined)) !== null && _a !== void 0 ? _a : []; } function selectTargetFile(translation) { if (typeof translation === 'string') { return translation || undefined; } if (!translation || translation.length === 1) { return translation === null || translation === void 0 ? void 0 : translation[0]; } // simple heuristic: shortest path (translations from third parties are probably from node_modules..) const sorted = [...translation].sort((a, b) => a.length === b.length ? 0 : (a.length > b.length ? 1 : -1)); return sorted[0]; } function getFormatFromTargetFile(targetFilePath, tree, context) { var _a; if (targetFilePath) { const content = (_a = tree.read(targetFilePath)) === null || _a === void 0 ? void 0 : _a.toString(); const m = content === null || content === void 0 ? void 0 : content.match(/<xliff[^>]*version=["']([^"']+)["']/i); if (m) { switch (m[1]) { case '1.2': return 'xlf'; case '2.0': return 'xlf2'; default: context.logger.warn(`unexpected xliff version in ${targetFilePath}: ${m[1]}`); return undefined; } } } return undefined; } function getOutFileRelativeToOutputPath(outFile, outputPathFromExtractI18nOptions, outputPathFromTargetFiles, tree, outputPath) { const potentialBasePathsForOutFile = [ outputPathFromExtractI18nOptions, outputPathFromTargetFiles, 'src/locales', '.' ].filter(p => !!p); const basePathForOutFile = potentialBasePathsForOutFile.find(p => tree.exists((0, core_1.normalize)(`${p}/${outFile}`))); return basePathForOutFile ? (0, core_1.relative)(`/${outputPath}`, `/${basePathForOutFile}/${outFile}`) : outFile; } // noinspection JSUnusedGlobalSymbols function ngAdd(_options) { return (tree, context) => { return (0, workspace_1.updateWorkspace)(async (workspace) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; const projectName = _options.project || Array.from(workspace.projects.keys())[0]; const projectWorkspace = workspace.projects.get(projectName); if (!projectWorkspace) { throw new schematics_1.SchematicsException(`Project ${projectName} not found!`); } // infer target files: const i18nExtension = projectWorkspace.extensions.i18n; // alternative: search tree for *.xlf? --> not performant, contains node_modules const files = getTargetFiles(i18nExtension); if (!(files === null || files === void 0 ? void 0 : files.length)) { context.logger.warn('Could not infer translation target files, please setup angular i18n and re-run `ng add ng-extract-i18n-merge`: https://angular.io/guide/i18n-common-merge#define-locales-in-the-build-configuration'); } else { context.logger.info('Found target translation files: ' + JSON.stringify(files)); } // infer outputPath const existingI18nTargetOptions = (_a = projectWorkspace.targets.get('extract-i18n')) === null || _a === void 0 ? void 0 : _a.options; const outputPathFromExtractI18nOptions = existingI18nTargetOptions === null || existingI18nTargetOptions === void 0 ? void 0 : existingI18nTargetOptions.outputPath; const outputPathFromTargetFiles = (_b = files === null || files === void 0 ? void 0 : files[0]) === null || _b === void 0 ? void 0 : _b.substring(0, (_d = (_c = files === null || files === void 0 ? void 0 : files[0]) === null || _c === void 0 ? void 0 : _c.lastIndexOf('/')) !== null && _d !== void 0 ? _d : (_e = files === null || files === void 0 ? void 0 : files[0]) === null || _e === void 0 ? void 0 : _e.length); const outputPath = (0, core_1.normalize)((_f = outputPathFromExtractI18nOptions !== null && outputPathFromExtractI18nOptions !== void 0 ? outputPathFromExtractI18nOptions : outputPathFromTargetFiles) !== null && _f !== void 0 ? _f : 'src/locales'); context.logger.info(`inferred output path: ${outputPath}`); const buildTarget = (_h = (_g = existingI18nTargetOptions === null || existingI18nTargetOptions === void 0 ? void 0 : existingI18nTargetOptions.browserTarget) !== null && _g !== void 0 ? _g : existingI18nTargetOptions === null || existingI18nTargetOptions === void 0 ? void 0 : existingI18nTargetOptions.buildTarget) !== null && _h !== void 0 ? _h : `${projectName}:build`; // infer format: const formatFromExtractI18nOptions = existingI18nTargetOptions === null || existingI18nTargetOptions === void 0 ? void 0 : existingI18nTargetOptions.format; const formatFromTargetFiles = getFormatFromTargetFile(files === null || files === void 0 ? void 0 : files[0], tree, context); const format = (_j = formatFromExtractI18nOptions !== null && formatFromExtractI18nOptions !== void 0 ? formatFromExtractI18nOptions : formatFromTargetFiles) !== null && _j !== void 0 ? _j : 'xlf2'; context.logger.info(`inferred format: ${format}`); // remove path from files const filesWithoutOutputPath = files === null || files === void 0 ? void 0 : files.map(f => (0, core_1.relative)(`/${outputPath}`, `/${f}`)); const target = projectWorkspace.targets.get('extract-i18n'); const builderOptions = { buildTarget: buildTarget, format, outputPath, targetFiles: filesWithoutOutputPath !== null && filesWithoutOutputPath !== void 0 ? filesWithoutOutputPath : [] }; const outFileRelativeToOutputPath = getOutFileRelativeToOutputPath((_k = existingI18nTargetOptions === null || existingI18nTargetOptions === void 0 ? void 0 : existingI18nTargetOptions.outFile) !== null && _k !== void 0 ? _k : 'messages.xlf', outputPathFromExtractI18nOptions, outputPathFromTargetFiles, tree, outputPath); if (outFileRelativeToOutputPath !== 'messages.xlf') { builderOptions.sourceFile = outFileRelativeToOutputPath; } if (target) { context.logger.info(`Overwriting previous extract-i18n entry in project ${projectName}.`); target.builder = 'ng-extract-i18n-merge:ng-extract-i18n-merge'; target.options = builderOptions; } else { projectWorkspace.targets.add({ name: 'extract-i18n', builder: 'ng-extract-i18n-merge:ng-extract-i18n-merge', options: builderOptions, }); } }); }; } exports.ngAdd = ngAdd;