@ngneat/transloco
Version:
The internationalization (i18n) library for Angular
131 lines • 17.5 kB
JavaScript
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==