@hug/ngx-g11n
Version:
Angular helpers for internationalizing and localizing your application
201 lines • 10.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_OPTIONS = void 0;
const schematics_1 = require("@angular-devkit/schematics");
const ngx_schematics_utilities_1 = require("@hug/ngx-schematics-utilities");
const node_path_1 = require("node:path");
const node_util_1 = require("node:util");
exports.DEFAULT_OPTIONS = {
defaultLanguage: 'fr-CH',
defaultCurrency: 'CHF',
useNavigatorLanguage: true,
loadLocaleExtra: false,
rootTranslationsPath: '/translations',
translationScopes: [],
queryParamName: 'lang',
};
const resolveExtractI18nBuilder = () => {
try {
require.resolve('@angular/build/package.json');
return '@angular/build:extract-i18n';
}
catch {
return '@angular-devkit/build-angular:extract-i18n';
}
};
const customizeProject = ({ project, tree }, options, ngVersion) => {
const rules = [];
// Normalize array options
if (typeof options.translationScopes === 'string') {
options.translationScopes = options.translationScopes.split(',').map(s => s.trim()).filter(Boolean);
}
// tsconfig.json
if (Number(ngVersion.major) <= 14) {
rules.push((0, ngx_schematics_utilities_1.modifyJsonFile)('tsconfig.json', ['angularCompilerOptions', 'skipLibCheck'], true));
}
// package.json
rules.push((0, ngx_schematics_utilities_1.modifyJsonFile)('package.json', ['scripts', 'i18n'], `ng extract-i18n ${project.name}`, false));
// .gitignore
if (options.useEnhancedBuilder) {
const gitignoreContent = tree.readText('.gitignore');
rules.push((0, ngx_schematics_utilities_1.createOrUpdateFile)('.gitignore', `${gitignoreContent}\n\n*.bak.json`));
}
// angular.json
const locale = new Intl.Locale(options.defaultLanguage);
const builder = options.useEnhancedBuilder ? '@hug/ngx-g11n:extract-i18n' : resolveExtractI18nBuilder();
const architectPath = ['projects', project.name, 'architect'];
const extractPath = [...architectPath, 'extract-i18n'];
const extractOptionsPath = [...extractPath, 'options'];
rules.push((0, ngx_schematics_utilities_1.modifyJsonFile)('angular.json', ['projects', project.name, 'i18n', 'sourceLocale'], options.defaultLanguage), (0, ngx_schematics_utilities_1.modifyJsonFile)('angular.json', [...architectPath, 'build', 'options', 'i18nMissingTranslation'], 'error'), (0, ngx_schematics_utilities_1.modifyJsonFile)('angular.json', [...extractPath, 'builder'], builder), (0, ngx_schematics_utilities_1.modifyJsonFile)('angular.json', [...extractOptionsPath, 'format'], 'json'), (0, ngx_schematics_utilities_1.modifyJsonFile)('angular.json', [...extractOptionsPath, 'outFile'], `${locale.language}.json`));
if (project.assetsPath) {
rules.push((0, ngx_schematics_utilities_1.modifyJsonFile)('angular.json', [...extractOptionsPath, 'outputPath'], (0, node_path_1.join)(project.assetsPath, options.rootTranslationsPath)));
}
if (options.useEnhancedBuilder) {
rules.push((0, ngx_schematics_utilities_1.modifyJsonFile)('angular.json', [...extractOptionsPath, 'backupIgnoredTranslations'], false), (0, ngx_schematics_utilities_1.modifyJsonFile)('angular.json', [...extractOptionsPath, 'ignoreKeyPatterns'], ['_.*']));
}
// Provide library
let configFile;
if (project.isStandalone) {
configFile = project.mainConfigFilePath;
}
else if (tree.exists(project.pathFromSourceRoot('app/app-module.ts'))) {
configFile = project.pathFromSourceRoot('app/app-module.ts'); // for Angular 20+
}
else {
configFile = project.pathFromSourceRoot('app/app.module.ts'); // for Angular < 20
}
if (configFile && tree.exists(configFile)) {
const libName = Number(ngVersion.major) >= 15 ? '@hug/ngx-g11n' : '@hug/ngx-g11n/legacy';
let provider = project.isStandalone ? 'provideG11n(' : 'G11nModule.forRoot(';
// ---- locales
if (options.defaultLocales && options.material) {
rules.push((0, ngx_schematics_utilities_1.addImportToFile)(configFile, 'withDefaultLocales', '@hug/ngx-g11n/locales'));
provider += '\nwithDefaultLocales()';
}
else {
rules.push((0, ngx_schematics_utilities_1.addImportToFile)(configFile, 'withLocales', libName));
const getLocale = (value) => {
let str = `'${value}': {`;
str += `\n base: () => import('@angular/common/locales/${value}')`;
if (options.loadLocaleExtra) {
str += `,\n extra: () => import('@angular/common/locales/extra/${value}')`;
}
if (options.material) {
str += `,\n datefns: () => import('date-fns/locale/${value}')`;
}
str += '\n }';
return str;
};
provider += '\nwithLocales({';
if (options.defaultLocales) {
provider += `\n ${getLocale('fr-CH')}`;
provider += `,\n ${getLocale('de-CH')}`;
}
else {
provider += `\n ${getLocale(options.defaultLanguage)}`;
}
provider += '\n})';
}
// ---- options
const opts = {};
Object.entries(options).forEach(([key, value]) => {
if (key in exports.DEFAULT_OPTIONS && JSON.stringify(exports.DEFAULT_OPTIONS[key]) !== JSON.stringify(value)) {
// @ts-expect-error error expected
opts[key] = value;
}
});
if (Object.keys(opts).length) {
rules.push((0, ngx_schematics_utilities_1.addImportToFile)(configFile, 'withOptions', libName));
provider += `,\nwithOptions(${JSON.stringify(opts, null, 4)
.replace(/"([^"]+)":/g, '$1:')
.replace(/"/g, '\'')})`;
}
// ---- material
if (options.material) {
rules.push((0, ngx_schematics_utilities_1.addImportToFile)(configFile, 'withDateFnsMaterial', '@hug/ngx-g11n/material'));
provider += ',\nwithDateFnsMaterial()';
}
// ---- interceptor
if (options.interceptor) {
rules.push((0, ngx_schematics_utilities_1.addImportToFile)(configFile, 'withInterceptor', libName));
provider += ',\nwithInterceptor()';
}
provider += '\n)';
provider = provider.split('\n').map((line, i, arr) => `${i === 0 || i === arr.length - 1 ? '' : ' '}${line}`).join('\n');
if (project.isStandalone) {
rules.push(async (ruleTree, ruleContext) => {
try {
await (0, ngx_schematics_utilities_1.addProviderToBootstrapApplication)(project.mainFilePath, provider, libName)(ruleTree, ruleContext);
return (0, schematics_1.noop)();
}
catch (err) {
const errorMessage = (err instanceof Error) ? err.message : 'An unknown error occurred';
if (errorMessage.includes('Application config is not an object literal')) {
const fileContent = ruleTree.read(configFile)?.toString('utf-8') ?? '';
const patternToReplace = /providers: \[/sm;
if (!(patternToReplace.exec(fileContent))) {
const conflictContent = '\n'
+ '<<<<<<< HEAD\n'
+ '=======\n'
+ '\n'
+ '// This code was auto-generated by \'@hug/ngx-g11n\' schematic.\n'
+ '// Unfortunately the schematic was not able to merged it with your current code.\n'
+ '// Please resolve it manually.\n'
+ '\n'
+ 'export const appConfig: ApplicationConfig = {\n'
+ ' providers: [\n'
+ ` ${provider.split('\n').join('\n ')}\n`
+ ' ]\n'
+ '};\n'
+ '\n'
+ '>>>>>>>\n';
return (0, schematics_1.chain)([
(0, ngx_schematics_utilities_1.replaceInFile)(configFile, /$/g, conflictContent),
(0, ngx_schematics_utilities_1.runAtEnd)((0, ngx_schematics_utilities_1.logError)(`There were some conflicts during the installation, please have a look at ${(0, node_util_1.styleText)('bold', `'${configFile}'`)} file and resolve them.`)),
]);
}
else {
return (0, ngx_schematics_utilities_1.replaceInFile)(configFile, patternToReplace, `providers: [\n ${provider.split('\n').join('\n ')},`);
}
}
else {
return (0, ngx_schematics_utilities_1.logError)(`${errorMessage} (skipping)`);
}
}
});
}
else {
rules.push((0, ngx_schematics_utilities_1.addImportToNgModule)(configFile, provider, libName));
}
}
else {
const error = `Could not find application ${project.isStandalone ? 'config' : 'module'} file (skipping)`;
rules.push((0, ngx_schematics_utilities_1.logError)(error));
}
return (0, schematics_1.chain)(rules);
};
exports.default = (options) => async () => {
const ngVersion = await (0, ngx_schematics_utilities_1.getAngularVersion)();
return (0, ngx_schematics_utilities_1.schematic)('@hug/ngx-g11n', [
(0, ngx_schematics_utilities_1.workspace)()
.spawn('ng', ['add', '@angular/localize', '--skip-confirmation'])
.rule(() => options.material ? (0, schematics_1.chain)([
(0, ngx_schematics_utilities_1.addPackageJsonDependencies)([{
name: '@angular/material-date-fns-adapter',
version: `^${ngVersion.major}.0.0`,
}]),
(0, ngx_schematics_utilities_1.packageInstallTask)(),
]) : (0, schematics_1.noop)())
.toRule(),
(0, ngx_schematics_utilities_1.application)(options.project)
.rule(({ project }) => {
if (!project.assetsPath) {
return (0, ngx_schematics_utilities_1.logError)('Deploying assets failed: no assets path found');
}
return (0, ngx_schematics_utilities_1.deployFiles)(options, './files', (0, node_path_1.join)(project.assetsPath, options.rootTranslationsPath));
})
.rule(context => customizeProject(context, options, ngVersion))
.toRule(),
], options);
};
//# sourceMappingURL=index.js.map