UNPKG

@ngneat/transloco

Version:

The internationalization (i18n) library for Angular

131 lines 17.5 kB
import { Inject, inject, Injectable, InjectionToken, Injector, Optional, } from '@angular/core'; import { getValue, isDefined, isObject, isString, setValue } from './helpers'; import { defaultConfig, TRANSLOCO_CONFIG, } from './transloco.config'; import * as i0 from "@angular/core"; export const TRANSLOCO_TRANSPILER = new InjectionToken('TRANSLOCO_TRANSPILER'); export class DefaultTranspiler { interpolationMatcher; // TODO use inject in Transloco v7 constructor(config) { this.interpolationMatcher = resolveMatcher(config ?? defaultConfig); } transpile(value, params = {}, translation, key) { if (isString(value)) { return value.replace(this.interpolationMatcher, (_, match) => { match = match.trim(); if (isDefined(params[match])) { return params[match]; } return isDefined(translation[match]) ? this.transpile(translation[match], params, translation, key) : ''; }); } else if (params) { if (isObject(value)) { value = this.handleObject(value, params, translation, key); } else if (Array.isArray(value)) { value = this.handleArray(value, params, translation, key); } } return value; } /** * * @example * * const en = { * a: { * b: { * c: "Hello {{ value }}" * } * } * } * * const params = { * "b.c": { value: "Transloco "} * } * * service.selectTranslate('a', params); * * // the first param will be the result of `en.a`. * // the second param will be `params`. * parser.transpile(value, params, {}); * * */ handleObject(value, params = {}, translation, key) { let result = value; Object.keys(params).forEach((p) => { // get the value of "b.c" inside "a" => "Hello {{ value }}" const v = getValue(result, p); // get the params of "b.c" => { value: "Transloco" } const getParams = getValue(params, p); // transpile the value => "Hello Transloco" const transpiled = this.transpile(v, getParams, translation, key); // set "b.c" to `transpiled` result = setValue(result, p, transpiled); }); return result; } handleArray(value, params = {}, translation, key) { return value.map((v) => this.transpile(v, params, translation, key)); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DefaultTranspiler, deps: [{ token: TRANSLOCO_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DefaultTranspiler }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DefaultTranspiler, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [TRANSLOCO_CONFIG] }] }]; } }); function resolveMatcher(config) { const [start, end] = config.interpolation; return new RegExp(`${start}(.*?)${end}`, 'g'); } export function getFunctionArgs(argsString) { const splitted = argsString ? argsString.split(',') : []; const args = []; for (let i = 0; i < splitted.length; i++) { let value = splitted[i].trim(); while (value[value.length - 1] === '\\') { i++; value = value.replace('\\', ',') + splitted[i]; } args.push(value); } return args; } export class FunctionalTranspiler extends DefaultTranspiler { injector = inject(Injector); transpile(value, params = {}, translation, key) { let transpiled = value; if (isString(value)) { transpiled = value.replace(/\[\[\s*(\w+)\((.*?)\)\s*]]/g, (match, functionName, args) => { try { const func = this.injector.get(functionName); return func.transpile(...getFunctionArgs(args)); } catch (e) { let message = `There is an error in: '${value}'. Check that the you used the right syntax in your translation and that the implementation of ${functionName} is correct.`; if (e.message.includes('NullInjectorError')) { message = `You are using the '${functionName}' function in your translation but no provider was found!`; } throw new Error(message); } }); } return super.transpile(transpiled, params, translation, key); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FunctionalTranspiler, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FunctionalTranspiler }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FunctionalTranspiler, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsb2NvLnRyYW5zcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3RyYW5zbG9jby9zcmMvbGliL3RyYW5zbG9jby50cmFuc3BpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFVBQVUsRUFDVixjQUFjLEVBQ2QsUUFBUSxFQUNSLFFBQVEsR0FDVCxNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUM5RSxPQUFPLEVBQ0wsYUFBYSxFQUNiLGdCQUFnQixHQUVqQixNQUFNLG9CQUFvQixDQUFDOztBQUU1QixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLGNBQWMsQ0FDcEQsc0JBQXNCLENBQ3ZCLENBQUM7QUFlRixNQUFNLE9BQU8saUJBQWlCO0lBQ2xCLG9CQUFvQixDQUFTO0lBRXZDLGtDQUFrQztJQUNsQyxZQUFrRCxNQUF3QjtRQUN4RSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsY0FBYyxDQUFDLE1BQU0sSUFBSSxhQUFhLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQsU0FBUyxDQUNQLEtBQVUsRUFDVixTQUFrQixFQUFFLEVBQ3BCLFdBQXdCLEVBQ3hCLEdBQVc7UUFFWCxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNuQixPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFO2dCQUMzRCxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNyQixJQUFJLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtvQkFDNUIsT0FBTyxNQUFNLENBQUMsS0FBSyxD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QXNCLFlBQVksMkRBQTJELENBQUM7cUJBQ3pHO29CQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQzFCO1lBQ0gsQ0FBQyxDQUNGLENBQUM7U0FDSDtRQUVELE9BQU8sS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUMvRCxDQUFDO3VHQW5DVSxvQkFBb0I7MkdBQXBCLG9CQUFvQjs7MkZBQXBCLG9CQUFvQjtrQkFEaEMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEluamVjdCxcbiAgaW5qZWN0LFxuICBJbmplY3RhYmxlLFxuICBJbmplY3Rpb25Ub2tlbixcbiAgSW5qZWN0b3IsXG4gIE9wdGlvbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgSGFzaE1hcCwgVHJhbnNsYXRpb24gfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGdldFZhbHVlLCBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1N0cmluZywgc2V0VmFsdWUgfSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IHtcbiAgZGVmYXVsdENvbmZpZyxcbiAgVFJBTlNMT0NPX0NPTkZJRyxcbiAgVHJhbnNsb2NvQ29uZmlnLFxufSBmcm9tICcuL3RyYW5zbG9jby5jb25maWcnO1xuXG5leHBvcnQgY29uc3QgVFJBTlNMT0NPX1RSQU5TUElMRVIgPSBuZXcgSW5qZWN0aW9uVG9rZW48VHJhbnNsb2NvVHJhbnNwaWxlcj4oXG4gICdUUkFOU0xPQ09fVFJBTlNQSUxFUidcbik7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNsb2NvVHJhbnNwaWxlciB7XG4gIC8vIFRPRE86IENoYW5nZSBwYXJhbWV0ZXJzIHRvIG9iamVjdCBpbiB0aGUgbmV4dCBtYWpvciByZWxlYXNlXG4gIHRyYW5zcGlsZShcbiAgICB2YWx1ZTogYW55LFxuICAgIHBhcmFtczogSGFzaE1hcCxcbiAgICB0cmFuc2xhdGlvbjogVHJhbnNsYXRpb24sXG4gICAga2V5OiBzdHJpbmdcbiAgKTogYW55O1xuXG4gIG9uTGFuZ0NoYW5nZWQ/KGxhbmc6IHN0cmluZyk6IHZvaWQ7XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEZWZhdWx0VHJhbnNwaWxlciBpbXBsZW1lbnRzIFRyYW5zbG9jb1RyYW5zcGlsZXIge1xuICBwcm90ZWN0ZWQgaW50ZXJwb2xhdGlvbk1hdGNoZXI6IFJlZ0V4cDtcblxuICAvLyBUT0RPIHVzZSBpbmplY3QgaW4gVHJhbnNsb2NvIHY3XG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIEBJbmplY3QoVFJBTlNMT0NPX0NPTkZJRykgY29uZmlnPzogVHJhbnNsb2NvQ29uZmlnKSB7XG4gICAgdGhpcy5pbnRlcnBvbGF0aW9uTWF0Y2hlciA9IHJlc29sdmVNYXRjaGVyKGNvbmZpZyA/PyBkZWZhdWx0Q29uZmlnKTtcbiAgfVxuXG4gIHRyYW5zcGlsZShcbiAgICB2YWx1ZTogYW55LFxuICAgIHBhcmFtczogSGFzaE1hcCA9IHt9LFxuICAgIHRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbixcbiAgICBrZXk6IHN0cmluZ1xuICApOiBhbnkge1xuICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5yZXBsYWNlKHRoaXMuaW50ZXJwb2xhdGlvbk1hdGNoZXIsIChfLCBtYXRjaCkgPT4ge1xuICAgICAgICBtYXRjaCA9IG1hdGNoLnRyaW0oKTtcbiAgICAgICAgaWYgKGlzRGVmaW5lZChwYXJhbXNbbWF0Y2hdKSkge1xuICAgICAgICAgIHJldHVybiBwYXJhbXNbbWF0Y2hdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGlzRGVmaW5lZCh0cmFuc2xhdGlvblttYXRjaF0pXG4gICAgICAgICAgPyB0aGlzLnRyYW5zcGlsZSh0cmFuc2xhdGlvblttYXRjaF0sIHBhcmFtcywgdHJhbnNsYXRpb24sIGtleSlcbiAgICAgICAgICA6ICcnO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChwYXJhbXMpIHtcbiAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmhhbmRsZU9iamVjdCh2YWx1ZSwgcGFyYW1zLCB0cmFuc2xhdGlvbiwga2V5KTtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmhhbmRsZUFycmF5KHZhbHVlLCBwYXJhbXMsIHRyYW5zbGF0aW9uLCBrZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBjb25zdCBlbiA9IHtcbiAgICogIGE6IHtcbiAgICogICAgYjoge1xuICAgKiAgICAgIGM6IFwiSGVsbG8ge3sgdmFsdWUgfX1cIlxuICAgKiAgICB9XG4gICAqICB9XG4gICAqIH1cbiAgICpcbiAgICogY29uc3QgcGFyYW1zID0gIHtcbiAgICogIFwiYi5jXCI6IHsgdmFsdWU6IFwiVHJhbnNsb2NvIFwifVxuICAgKiB9XG4gICAqXG4gICAqIHNlcnZpY2Uuc2VsZWN0VHJhbnNsYXRlKCdhJywgcGFyYW1zKTtcbiAgICpcbiAgICogLy8gdGhlIGZpcnN0IHBhcmFtIHdpbGwgYmUgdGhlIHJlc3VsdCBvZiBgZW4uYWAuXG4gICAqIC8vIHRoZSBzZWNvbmQgcGFyYW0gd2lsbCBiZSBgcGFyYW1zYC5cbiAgICogcGFyc2VyLnRyYW5zcGlsZSh2YWx1ZSwgcGFyYW1zLCB7fSk7XG4gICAqXG4gICAqXG4gICAqL1xuICBwcm90ZWN0ZWQgaGFuZGxlT2JqZWN0KFxuICAgIHZhbHVlOiBhbnksXG4gICAgcGFyYW1zOiBIYXNoTWFwID0ge30sXG4gICAgdHJhbnNsYXRpb246IFRyYW5zbGF0aW9uLFxuICAgIGtleTogc3RyaW5nXG4gICkge1xuICAgIGxldCByZXN1bHQgPSB2YWx1ZTtcblxuICAgIE9iamVjdC5rZXlzKHBhcmFtcykuZm9yRWFjaCgocCkgPT4ge1xuICAgICAgLy8gZ2V0IHRoZSB2YWx1ZSBvZiBcImIuY1wiIGluc2lkZSBcImFcIiA9PiBcIkhlbGxvIHt7IHZhbHVlIH19XCJcbiAgICAgIGNvbnN0IHYgPSBnZXRWYWx1ZShyZXN1bHQsIHApO1xuICAgICAgLy8gZ2V0IHRoZSBwYXJhbXMgb2YgXCJiLmNcIiA9PiB7IHZhbHVlOiBcIlRyYW5zbG9jb1wiIH1cbiAgICAgIGNvbnN0IGdldFBhcmFtcyA9IGdldFZhbHVlKHBhcmFtcywgcCk7XG5cbiAgICAgIC8vIHRyYW5zcGlsZSB0aGUgdmFsdWUgPT4gXCJIZWxsbyBUcmFuc2xvY29cIlxuICAgICAgY29uc3QgdHJhbnNwaWxlZCA9IHRoaXMudHJhbnNwaWxlKHYsIGdldFBhcmFtcywgdHJhbnNsYXRpb24sIGtleSk7XG5cbiAgICAgIC8vIHNldCBcImIuY1wiIHRvIGB0cmFuc3BpbGVkYFxuICAgICAgcmVzdWx0ID0gc2V0VmFsdWUocmVzdWx0LCBwLCB0cmFuc3BpbGVkKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlQXJyYXkoXG4gICAgdmFsdWU6IHN0cmluZ1tdLFxuICAgIHBhcmFtczogSGFzaE1hcCA9IHt9LFxuICAgIHRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbixcbiAgICBrZXk6IHN0cmluZ1xuICApIHtcbiAgICByZXR1cm4gdmFsdWUubWFwKCh2KSA9PiB0aGlzLnRyYW5zcGlsZSh2LCBwYXJhbXMsIHRyYW5zbGF0aW9uLCBrZXkpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNvbHZlTWF0Y2hlcihjb25maWc6IFRyYW5zbG9jb0NvbmZpZyk6IFJlZ0V4cCB7XG4gIGNvbnN0IFtzdGFydCwgZW5kXSA9IGNvbmZpZy5pbnRlcnBvbGF0aW9uO1xuXG4gIHJldHVybiBuZXcgUmVnRXhwKGAke3N0YXJ0fSguKj8pJHtlbmR9YCwgJ2cnKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xvY29UcmFuc3BpbGVyRnVuY3Rpb24ge1xuICB0cmFuc3BpbGUoLi4uYXJnczogc3RyaW5nW10pOiBhbnk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGdW5jdGlvbkFyZ3MoYXJnc1N0cmluZzogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBzcGxpdHRlZCA9IGFyZ3NTdHJpbmcgPyBhcmdzU3RyaW5nLnNwbGl0KCcsJykgOiBbXTtcbiAgY29uc3QgYXJncyA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNwbGl0dGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IHZhbHVlID0gc3BsaXR0ZWRbaV0udHJpbSgpO1xuICAgIHdoaWxlICh2YWx1ZVt2YWx1ZS5sZW5ndGggLSAxXSA9PT0gJ1xcXFwnKSB7XG4gICAgICBpKys7XG4gICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoJ1xcXFwnLCAnLCcpICsgc3BsaXR0ZWRbaV07XG4gICAgfVxuICAgIGFyZ3MucHVzaCh2YWx1ZSk7XG4gIH1cblxuICByZXR1cm4gYXJncztcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uYWxUcmFuc3BpbGVyXG4gIGV4dGVuZHMgRGVmYXVsdFRyYW5zcGlsZXJcbiAgaW1wbGVtZW50cyBUcmFuc2xvY29UcmFuc3BpbGVyXG57XG4gIHByb3RlY3RlZCBpbmplY3RvciA9IGluamVjdChJbmplY3Rvcik7XG5cbiAgdHJhbnNwaWxlKFxuICAgIHZhbHVlOiBhbnksXG4gICAgcGFyYW1zOiBIYXNoTWFwID0ge30sXG4gICAgdHJhbnNsYXRpb246IFRyYW5zbGF0aW9uLFxuICAgIGtleTogc3RyaW5nXG4gICk6IGFueSB7XG4gICAgbGV0IHRyYW5zcGlsZWQgPSB2YWx1ZTtcbiAgICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICB0cmFuc3BpbGVkID0gdmFsdWUucmVwbGFjZShcbiAgICAgICAgL1xcW1xcW1xccyooXFx3KylcXCgoLio/KVxcKVxccypdXS9nLFxuICAgICAgICAobWF0Y2g6IHN0cmluZywgZnVuY3Rpb25OYW1lOiBzdHJpbmcsIGFyZ3M6IHN0cmluZykgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmdW5jOiBUcmFuc2xvY29UcmFuc3BpbGVyRnVuY3Rpb24gPVxuICAgICAgICAgICAgICB0aGlzLmluamVjdG9yLmdldChmdW5jdGlvbk5hbWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gZnVuYy50cmFuc3BpbGUoLi4uZ2V0RnVuY3Rpb25BcmdzKGFyZ3MpKTtcbiAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIGxldCBtZXNzYWdlID0gYFRoZXJlIGlzIGFuIGVycm9yIGluOiAnJHt2YWx1ZX0nLiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hlY2sgdGhhdCB0aGUgeW91IHVzZWQgdGhlIHJpZ2h0IHN5bnRheCBpbiB5b3VyIHRyYW5zbGF0aW9uIGFuZCB0aGF0IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiAke2Z1bmN0aW9uTmFtZX0gaXMgY29ycmVjdC5gO1xuICAgICAgICAgICAgaWYgKGUubWVzc2FnZS5pbmNsdWRlcygnTnVsbEluamVjdG9yRXJyb3InKSkge1xuICAgICAgICAgICAgICBtZXNzYWdlID0gYFlvdSBhcmUgdXNpbmcgdGhlICcke2Z1bmN0aW9uTmFtZX0nIGZ1bmN0aW9uIGluIHlvdXIgdHJhbnNsYXRpb24gYnV0IG5vIHByb3ZpZGVyIHdhcyBmb3VuZCFgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3VwZXIudHJhbnNwaWxlKHRyYW5zcGlsZWQsIHBhcmFtcywgdHJhbnNsYXRpb24sIGtleSk7XG4gIH1cbn1cbiJdfQ==