diff --git a/package-lock.json b/package-lock.json index 9664391..73d708d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,33 +99,21 @@ "integrity": "sha512-PCNLExLlI5HiPdaJs4pMXwOTHkSCpNQ1QJH9ykZLKtKEyKu3p9HgmH5l97vM8c0IUz6d54l+xEu2GG9yuYrFzA==", "dev": true }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, "gettext-parser": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.3.0.tgz", - "integrity": "sha512-iloxjcw+uTPnQ8DrGICWtqkHNgk3mAiDI77pLmXQCnhM+BxFQXstzTA4zj3EpIYMysRQnnNzHyHzBUEazz80Sw==", + "version": "1.3.1", + "resolved": "http://registry.npmjs.org/gettext-parser/-/gettext-parser-1.3.1.tgz", + "integrity": "sha512-W4t55eB/c7WrH0gbCHFiHuaEnJ1WiPJVnbFFiNEoh2QkOmuSLxs0PmJDGAmCQuTJCU740Fmb6D+2D/2xECWZGQ==", "requires": { "encoding": "^0.1.12", "safe-buffer": "^5.1.1" - }, - "dependencies": { - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - } } }, "has-flag": { @@ -134,6 +122,14 @@ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "rxjs": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.1.0.tgz", @@ -151,6 +147,16 @@ } } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "tslib": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz", diff --git a/src/index.ts b/src/index.ts index 65fa876..a8f986a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,56 +1,96 @@ import { HttpClient } from '@angular/common/http'; import { TranslateLoader } from '@ngx-translate/core'; import * as gettext from 'gettext-parser'; -import { Observable } from 'rxjs'; +import { Observable, forkJoin } from 'rxjs'; import { map } from 'rxjs/operators'; -export class TranslatePoHttpLoader implements TranslateLoader { +export abstract class AbstractPoHttpLoader implements TranslateLoader { - /** + /** * Translation domain */ - public domain = ''; + public domain = ''; + + public abstract getTranslation(lang: string): Observable; + /** + * Parse po file + * @param contents + * @returns {any} + */ + public parse(contents: string): any { + let translations: { [key: string]: string } = {}; + + const po = gettext.po.parse(contents, 'utf-8'); + if (!po.translations.hasOwnProperty(this.domain)) { + return translations; + } + + Object.keys(po.translations[this.domain]) + .forEach(key => { + const translation: string = po.translations[this.domain][key].msgstr.pop(); + if (key.length > 0 && translation.length > 0) { + translations[key] = translation; + } + }); + + return translations; + } + +} + +export interface ITranslationResource { + prefix: string; + suffix: string; +} + +export class TranslatePoHttpLoader extends AbstractPoHttpLoader { - constructor( - protected _http: HttpClient, - protected _prefix: string = 'i18n', - protected _suffix: string = '.po' - ) { - } + constructor( + protected _http: HttpClient, + protected _prefix: string = 'i18n', + protected _suffix: string = '.po' + ) { + super(); + } /** * Gets the translations from file * @param lang * @returns {any} */ - public getTranslation(lang: string): Observable { - return this._http - .get(`${this._prefix}/${lang}${this._suffix}`, { responseType: 'text' }) - .pipe(map((contents: string) => this.parse(contents))); - } + public getTranslation(lang: string): Observable { + return this._http + .get(`${this._prefix}/${lang}${this._suffix}`, { responseType: 'text' }) + .pipe( + map(contents => this.parse(contents)) + ); + } - /** - * Parse po file - * @param contents - * @returns {any} - */ - public parse(contents: string): any { - let translations: { [key: string]: string } = {}; +} - const po = gettext.po.parse(contents, 'utf-8'); - if (!po.translations.hasOwnProperty(this.domain)) { - return translations; - } +export class MultiTranslatePoHttpLoader extends AbstractPoHttpLoader { - Object.keys(po.translations[this.domain]) - .forEach(key => { - const translation: string = po.translations[this.domain][key].msgstr.pop(); - if (key.length > 0 && translation.length > 0) { - translations[key] = translation; - } - }); + constructor( + protected _http: HttpClient, + protected resources: ITranslationResource[] + ) { + super(); + } - return translations; - } + /** + * Gets the translations from file/s + * @param lang + * @returns {any} + */ + public getTranslation(lang: string): Observable { + const requests = this.resources.map(resource => { + return this._http.get(`${resource.prefix}/${lang}${resource.suffix}`, { responseType: 'text' }); + }); + return forkJoin(requests).pipe( + map(translationList => translationList.reduce((translationsAcc, currentTranslation) => translationsAcc + currentTranslation, '')), + map(contents => this.parse(contents)) + ); + } } +