UNPKG

@hug/ngx-g11n

Version:

Angular helpers for internationalizing and localizing your application

201 lines 10.9 kB
"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