UNPKG

n-translate-2

Version:
511 lines (506 loc) 19 kB
import { ErrorHandler, Injectable, NgModule, Optional, SkipSelf } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Headers } from '@angular/http'; import { NEndpoints, NHttp, NHttpConfig, NHttpModule } from 'n-http-2'; import { LocalStorageService, Ng2Webstorage } from 'ngx-webstorage'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/share'; import 'rxjs/add/observable/throw'; // This is to merge! var NTranslateConfigDefaults = { rootUrl: 'https://nstack.io/api', apiVersion: 'v1', platform: 'web', endpoints: { languages: 'languages', bestFit: 'languages/best_fit', keys: 'keys' }, apiKey: null, appId: null, storageIdentifier: null, persist: true, expires: Date.now() + (24 * 60 * 60 * 1000), fallbackFileEnabled: true, fallbackFileUrl: '/translate.json', debugEnabled: false }; /** * @param {?} config * @return {?} */ function nTranslateConfigFactory(config) { return new NTranslateConfig(config); } var NTranslateConfig = (function () { /** * @param {?} _config */ function NTranslateConfig(_config) { _config = _config || {}; if (!_config.hasOwnProperty('apiKey') || _config.apiKey === null) { throw new Error("NTranslate apiKey is missing"); } if (!_config.hasOwnProperty('appId') || _config.appId === null) { throw new Error("NTranslate appId is missing"); } if (!_config.hasOwnProperty('storageIdentifier') || _config.storageIdentifier === null) { throw new Error("NTranslate storageIdentifier is missing"); } this._config = Object.assign({}, NTranslateConfigDefaults, _config); } /** * @return {?} */ NTranslateConfig.prototype.getConfig = function () { return this._config; }; return NTranslateConfig; }()); var NTranslate = (function () { /** * @param {?} options * @param {?} http * @param {?} localStorage * @param {?} errorHandler */ function NTranslate(options, http, localStorage, errorHandler) { var _this = this; this.options = options; this.http = http; this.localStorage = localStorage; this.errorHandler = errorHandler; this.LANG = 'LANGUAGE'; this.ACTIVE_LANG = 'ACTIVE_LANGUAGE'; this.ALL = 'ALL'; this.subjectStore = {}; this.observableStore = {}; this.transmissionsStore = {}; this.config = options.getConfig(); if (this.config.fallbackFileEnabled && this.config.fallbackFileUrl) { if (this.config.debugEnabled) { console.info("nTranslate fallback file is enabled, starting internal checks"); } this.http.get(this.config.fallbackFileUrl).subscribe(function (response) { var fallbackData = response.json(); if (!fallbackData.hasOwnProperty('nTranslateCreatedAt')) { // The static JSON does not have a timestamp, we cannot pre-populate :( if (_this.config.debugEnabled) { console.info("nTranslate fallback json did not have a nTranslateCreatedAt property, no more to process"); } return; } if (_this.isExpired(fallbackData.nTranslateCreatedAt)) { // The fallback is older than what we have in store... if (_this.config.debugEnabled) { console.info("nTranslate fallback json is expired, no more to process"); } return; } // All is good if (_this.config.debugEnabled) { console.info("nTranslate fallback json is the newest data we have, populating stores - and fetching new translation data in the background"); } for (var key in fallbackData.data) { if (fallbackData.data.hasOwnProperty(key)) { if (!_this.getFromStorage(key)) { _this.persistInStorage(key, fallbackData.data[key]); } _this.setObservable(key, fallbackData.data[key]); } } var tempSubscription = _this.getAllSections(true).subscribe(function () { return tempSubscription.unsubscribe(); }); }); } } /** * @param {?=} forceFetch * @return {?} */ NTranslate.prototype.getAllSections = function (forceFetch) { if (!window.navigator.onLine) { return this.setObservable(this.ALL, this.getFromStorage(this.ALL)); } if (this.isExpired() || forceFetch) { if (this.config.debugEnabled) { console.info("nTranslate getAllSections \n - pulling from API - because " + (this.isExpired() ? 'isExpired' : 'forceFetch')); } return this.getKeysFromApi(); } if (this.observableStore.hasOwnProperty(this.ALL)) { if (this.config.debugEnabled) { console.info("nTranslate getSection getAllSections - pulling from In Memory"); } return this.getObservable(this.ALL); } if (this.getFromStorage(this.ALL)) { if (this.config.debugEnabled) { console.info("nTranslate getSection getAllSections - pulling from Local Storage"); } return this.setObservable(this.ALL, this.getFromStorage(this.ALL)); } if (this.config.debugEnabled) { console.info("nTranslate getSection getAllSections - pulling from API"); } return this.getKeysFromApi(); }; /** * @param {?} sectionName * @param {?=} forceFetch * @return {?} */ NTranslate.prototype.getSection = function (sectionName, forceFetch) { if (!window.navigator.onLine) { return this.setObservable(sectionName, this.getFromStorage(sectionName)); } if (this.isExpired() || forceFetch) { if (this.config.debugEnabled) { console.info("nTranslate getSection (" + sectionName + ") \n - pulling from API - because " + (this.isExpired() ? 'isExpired' : 'forceFetch')); } return this.getKeysFromApi(sectionName); } if (this.observableStore.hasOwnProperty(sectionName)) { if (this.config.debugEnabled) { console.info("nTranslate getSection (" + sectionName + ") - pulling from In Memory"); } return this.getObservable(sectionName); } if (this.getFromStorage(sectionName)) { if (this.config.debugEnabled) { console.info("nTranslate getSection (" + sectionName + ") - pulling from Local Storage"); } return this.setObservable(sectionName, this.getFromStorage(sectionName)); } if (this.config.debugEnabled) { console.info("nTranslate getSection (" + sectionName + ") - pulling from API"); } return this.getKeysFromApi(sectionName); }; /** * @param {?=} forceFetch * @return {?} */ NTranslate.prototype.getLanguages = function (forceFetch) { if (forceFetch) { if (this.config.debugEnabled) { console.info("nTranslate getLanguages \n - pulling from API - because " + (this.isExpired() ? 'isExpired' : 'forceFetch')); } return this.getLanguagesFromApi(true); } if (this.observableStore.hasOwnProperty('LANGUAGES')) { if (this.config.debugEnabled) { console.info("nTranslate getLanguages - pulling from In Memory"); } return this.getObservable('LANGUAGES'); } if (this.getFromStorage('LANGUAGES')) { if (this.config.debugEnabled) { console.info("nTranslate getLanguages - pulling from Local Storage"); } return this.setObservable('LANGUAGES', this.getFromStorage('LANGUAGES')); } if (this.config.debugEnabled) { console.info("nTranslate getLanguages - pulling from API"); } return this.getLanguagesFromApi(true); }; /** * @param {?=} forceFetch * @return {?} */ NTranslate.prototype.getBestFitLanguage = function (forceFetch) { if (forceFetch) { if (this.config.debugEnabled) { console.info("nTranslate getBestFitLanguage \n - pulling from API - because " + (this.isExpired() ? 'isExpired' : 'forceFetch')); } return this.getLanguagesFromApi(false); } if (this.observableStore.hasOwnProperty('BEST_FIT')) { if (this.config.debugEnabled) { console.info("nTranslate getBestFitLanguage - pulling from In Memory"); } return this.getObservable('BEST_FIT'); } if (this.getFromStorage('BEST_FIT')) { if (this.config.debugEnabled) { console.info("nTranslate getLanguages - pulling from Local Storage"); } return this.setObservable('BEST_FIT', this.getFromStorage('BEST_FIT')); } if (this.config.debugEnabled) { console.info("nTranslate getLanguages - pulling from API"); } return this.getLanguagesFromApi(false); }; /** * @return {?} */ NTranslate.prototype.getActiveLanguage = function () { if (this.observableStore.hasOwnProperty(this.ACTIVE_LANG)) { if (this.config.debugEnabled) { console.info("nTranslate getActiveLanguage - pulling from In Memory"); } return this.getObservable(this.ACTIVE_LANG); } return this.setObservable(this.ACTIVE_LANG, this.getFromStorage(this.ACTIVE_LANG)); }; /** * @return {?} */ NTranslate.prototype.getBrowserCultureLanguage = function () { if (typeof window === 'undefined' || typeof window.navigator === 'undefined') { return undefined; } var /** @type {?} */ browserCultureLang = window.navigator.languages ? window.navigator.languages[0] : null; browserCultureLang = browserCultureLang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage; return browserCultureLang; }; /** * @param {?} language * @return {?} */ NTranslate.prototype.setLanguage = function (language) { this.persistInStorage(this.ACTIVE_LANG, language); this.setObservable(this.ACTIVE_LANG, this.getFromStorage(this.ACTIVE_LANG)); }; /** * @param {?} sectionName * @return {?} */ NTranslate.prototype.getObservable = function (sectionName) { return this.observableStore[sectionName]; }; /** * @param {?} sectionName * @param {?} data * @return {?} */ NTranslate.prototype.setObservable = function (sectionName, data) { if (!this.observableStore.hasOwnProperty(sectionName)) { this.subjectStore[sectionName] = new BehaviorSubject(data); this.observableStore[sectionName] = this.subjectStore[sectionName].asObservable(); } else { this.subjectStore[sectionName].next(data); } return this.observableStore[sectionName]; }; /** * @param {?=} section * @return {?} */ NTranslate.prototype.getKeysFromApi = function (section) { var _this = this; var /** @type {?} */ sectionName = section ? section : this.ALL; if (this.transmissionsStore[sectionName]) { if (this.config.debugEnabled) { console.info("Already fetching via HTTP for section " + sectionName + " - returning existing transmission"); } return this.transmissionsStore[sectionName]; } this.transmissionsStore[sectionName] = this.requestHelper('keys', section) .flatMap(function (response) { var /** @type {?} */ body = response.json(); if (sectionName === _this.ALL) { for (var /** @type {?} */ key in body.data) { if (body.data.hasOwnProperty(key)) { _this.persistInStorage(key, body.data[key]); _this.setObservable(key, body.data[key]); } } _this.persistInStorage(_this.ALL, body.data); } else { _this.persistInStorage(sectionName, body.data); } _this.setExpiration(); delete _this.transmissionsStore[sectionName]; return _this.setObservable(sectionName, body.data); }) .share(); return this.transmissionsStore[sectionName]; }; /** * @param {?=} all * @return {?} */ NTranslate.prototype.getLanguagesFromApi = function (all) { var _this = this; var /** @type {?} */ identifier = all ? 'LANGUAGES' : 'BEST_FIT'; if (this.transmissionsStore[identifier]) { if (this.config.debugEnabled) { console.info("Already fetching via HTTP for languages - returning existing transmission"); } return this.transmissionsStore[identifier]; } this.transmissionsStore[identifier] = this.requestHelper(all ? 'languages' : 'bestFit') .flatMap(function (response) { var /** @type {?} */ body = response.json(); _this.persistInStorage(identifier, body.data); delete _this.transmissionsStore[identifier]; return _this.setObservable(identifier, body.data); }) .share(); return this.transmissionsStore[identifier]; }; /** * @param {?} key * @param {?} value * @return {?} */ NTranslate.prototype.persistInStorage = function (key, value) { var /** @type {?} */ k = this.config.storageIdentifier + '|' + key; this.localStorage.store(k, value); }; /** * @param {?} key * @return {?} */ NTranslate.prototype.getFromStorage = function (key) { var /** @type {?} */ k = this.config.storageIdentifier + '|' + key; return this.localStorage.retrieve(k); }; /** * @return {?} */ NTranslate.prototype.setExpiration = function () { var /** @type {?} */ expires = new Date().getTime() + this.config.expires; this.persistInStorage('EXPIRES', expires); }; /** * @param {?=} stamp * @return {?} */ NTranslate.prototype.isExpired = function (stamp) { var /** @type {?} */ now = new Date().getTime(); var /** @type {?} */ expires = stamp ? stamp : this.localStorage.retrieve(this.config.storageIdentifier + '|' + 'EXPIRES'); if (!expires) { if (this.config.debugEnabled) { console.info("nTranslate isExpired - no expires token found in storage"); } return true; } if (this.config.debugEnabled) { console.info("nTranslate isExpired evaluates to " + (now > expires)); } return now > expires; }; /** * @param {?} slug * @param {?=} section * @return {?} */ NTranslate.prototype.requestHelper = function (slug, section) { var /** @type {?} */ headers = new Headers({ 'X-Application-Id': this.config.appId, 'X-Rest-Api-Key': this.config.apiKey }); if (this.getFromStorage(this.ACTIVE_LANG)) { headers.append('X-Accept-Language', this.getFromStorage(this.ACTIVE_LANG).locale); } var /** @type {?} */ url = [ this.config.rootUrl, this.config.apiVersion, 'translate', this.config.platform ]; switch (slug) { case 'keys': url.push('keys'); if (section) { url.push(section); } break; case 'languages': url.push('languages'); break; case 'bestFit': url.push('languages/best_fit'); break; default: url.push('keys'); } return this.http.get(url.join('/'), { headers: headers }); }; return NTranslate; }()); NTranslate.decorators = [ { type: Injectable }, ]; /** * @nocollapse */ NTranslate.ctorParameters = function () { return [ { type: NTranslateConfig, }, { type: NHttp, }, { type: LocalStorageService, }, { type: ErrorHandler, }, ]; }; /** * @return {?} */ function createNHttpConfig() { return new NHttpConfig({}); } /** * @return {?} */ function createNEndpointsConfig() { return new NEndpoints({}); } var NTranslateModule = (function () { /** * @param {?} parentModule */ function NTranslateModule(parentModule) { if (parentModule) { throw new Error('NTranslateModule is already loaded. Import it in the AppModule only'); } } /** * @param {?=} providedConfig * @return {?} */ NTranslateModule.forRoot = function (providedConfig) { if (providedConfig === void 0) { providedConfig = { provide: NTranslateConfig, useFactory: nTranslateConfigFactory }; } return { ngModule: NTranslateModule, providers: [ providedConfig ] }; }; return NTranslateModule; }()); NTranslateModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule, Ng2Webstorage.forRoot({ prefix: 'nt2', caseSensitive: true }), NHttpModule.forRoot({ provide: NHttpConfig, useFactory: (createNHttpConfig) }, { provide: NEndpoints, useFactory: (createNEndpointsConfig) }) ], providers: [ NTranslate ] },] }, ]; /** * @nocollapse */ NTranslateModule.ctorParameters = function () { return [ { type: NTranslateModule, decorators: [{ type: Optional }, { type: SkipSelf },] }, ]; }; export { createNHttpConfig, createNEndpointsConfig, NTranslateModule, NTranslateConfigDefaults, nTranslateConfigFactory, NTranslateConfig, NTranslate };