n-translate-2
Version:
511 lines (506 loc) • 19 kB
JavaScript
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 };