UNPKG

ngx-api-manager

Version:
939 lines (929 loc) 40.9 kB
import { Inject, Injectable, InjectionToken, NgModule } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; import { BehaviorSubject as BehaviorSubject$1 } from 'rxjs/BehaviorSubject'; import { Subject as Subject$1 } from 'rxjs/Subject'; import { Observable as Observable$1 } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var TokenService = (function () { function TokenService() { var /** @type {?} */ token = null; this.get = function () { if (token === null) { token = localStorage.getItem('token') || null; } return token; }; this.set = function (val) { localStorage.setItem('token', val); return token = val; }; this.remove = function () { localStorage.removeItem('token'); token = null; }; } TokenService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ TokenService.ctorParameters = function () { return []; }; return TokenService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var LoadingStreamService = (function () { function LoadingStreamService() { this.loadingSource = new BehaviorSubject$1({ state: false, requestPoint: 'init' }); this.loadingStream$ = this.loadingSource.asObservable(); } /** * @param {?} action * @return {?} */ LoadingStreamService.prototype.emitLoading = /** * @param {?} action * @return {?} */ function (action) { this.loadingSource.next(action); }; LoadingStreamService.decorators = [ { type: Injectable }, ]; return LoadingStreamService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var enMsgs = { "0": "No Internet connection", "400": "Bad Request", "401": "Unauthorized", "402": "Payment Required", "403": "Forbidden", "404": "Not Found", "405": "Method Not Allowed", "406": "Not Acceptable", "407": "Proxy Authentication Required", "408": "Request Timeout", "409": "Conflict", "410": "Gone", "411": "Length Required", "412": "Precondition Failed", "413": "Request Entity Too Large", "414": "Request-URI Too Large", "415": "Unsupported Media Type", "416": "Requested Range Not Satisfiable", "417": "Expectation Failed", "422": "Unprocessable Entity", "423": "Locked", "424": "Failed Dependency", "425": "Unordered Collection", "426": "Upgrade Required", "428": "Precondition Required", "429": "Too Many Requests", "431": "Request Header Fields Too Large", "444": "Connection Closed Without Response", "449": "Retry With", "451": "Unavailable For Legal Reasons", "500": "Internal Server", "501": "Not Implemented", "502": "Bad Gateway", "503": "Service Unavailable", "504": "Gateway Timeout", "505": "HTTP Version Not Supported", "506": "Variant Also Negotiates", "507": "Insufficient Storage", "508": "Loop Detected", "509": "Bandwidth Limit Exceeded", "510": "UNot Extended", "511": "Network Authentication Required", "520": "Web server is returning an unknown error", "521": "Web server is down", "522": "Connection timed out", "523": "Origin is unreachable", "524": "A timeout occurred", "525": "SSL handshake failed", "526": "Invalid SSL certificate", "unusual": "Something went wrong!" }; var __extends = (undefined && undefined.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var ErrorsStreamService = (function () { function ErrorsStreamService() { this.errorSource = new Subject$1(); this.errorsStream$ = this.errorSource.asObservable(); } /** * @param {?} error * @param {?} errorPoint * @return {?} */ ErrorsStreamService.prototype.emitError = /** * @param {?} error * @param {?} errorPoint * @return {?} */ function (error, errorPoint) { this.errorSource.next({ error: error, errorPoint: errorPoint }); }; /** * @param {?} e * @param {?} errorPoint * @return {?} */ ErrorsStreamService.prototype.defaultProcessing = /** * @param {?} e * @param {?} errorPoint * @return {?} */ function (e, errorPoint) { switch (e.status) { case 0: return this.emitError(new DisconnectedError(enMsgs['0'], e), errorPoint); case 400: return this.emitError(new ClientError(enMsgs['400'], e), errorPoint); case 401: return this.emitError(new ClientError(enMsgs['401'], e), errorPoint); case 402: return this.emitError(new ClientError(enMsgs['402'], e), errorPoint); case 403: return this.emitError(new ClientError(enMsgs['403'], e), errorPoint); case 404: return this.emitError(new ClientError(enMsgs['404'], e), errorPoint); case 405: return this.emitError(new ClientError(enMsgs['405'], e), errorPoint); case 406: return this.emitError(new ClientError(enMsgs['406'], e), errorPoint); case 407: return this.emitError(new ClientError(enMsgs['407'], e), errorPoint); case 408: return this.emitError(new ClientError(enMsgs['408'], e), errorPoint); case 409: return this.emitError(new ClientError(enMsgs['409'], e), errorPoint); case 410: return this.emitError(new ClientError(enMsgs['410'], e), errorPoint); case 411: return this.emitError(new ClientError(enMsgs['411'], e), errorPoint); case 412: return this.emitError(new ClientError(enMsgs['412'], e), errorPoint); case 413: return this.emitError(new ClientError(enMsgs['413'], e), errorPoint); case 414: return this.emitError(new ClientError(enMsgs['414'], e), errorPoint); case 415: return this.emitError(new ClientError(enMsgs['415'], e), errorPoint); case 416: return this.emitError(new ClientError(enMsgs['416'], e), errorPoint); case 417: return this.emitError(new ClientError(enMsgs['417'], e), errorPoint); case 422: return this.emitError(new ClientError(enMsgs['422'], e), errorPoint); case 423: return this.emitError(new ClientError(enMsgs['423'], e), errorPoint); case 424: return this.emitError(new ClientError(enMsgs['424'], e), errorPoint); case 425: return this.emitError(new ClientError(enMsgs['425'], e), errorPoint); case 426: return this.emitError(new ClientError(enMsgs['426'], e), errorPoint); case 428: return this.emitError(new ClientError(enMsgs['428'], e), errorPoint); case 429: return this.emitError(new ClientError(enMsgs['429'], e), errorPoint); case 431: return this.emitError(new ClientError(enMsgs['431'], e), errorPoint); case 444: return this.emitError(new ClientError(enMsgs['444'], e), errorPoint); case 449: return this.emitError(new ClientError(enMsgs['449'], e), errorPoint); case 451: return this.emitError(new ClientError(enMsgs['451'], e), errorPoint); case 500: return this.emitError(new ServerError(enMsgs['500'], e), errorPoint); case 501: return this.emitError(new ServerError(enMsgs['501'], e), errorPoint); case 502: return this.emitError(new ServerError(enMsgs['502'], e), errorPoint); case 503: return this.emitError(new ServerError(enMsgs['503'], e), errorPoint); case 504: return this.emitError(new ServerError(enMsgs['504'], e), errorPoint); case 505: return this.emitError(new ServerError(enMsgs['505'], e), errorPoint); case 506: return this.emitError(new ServerError(enMsgs['506'], e), errorPoint); case 507: return this.emitError(new ServerError(enMsgs['507'], e), errorPoint); case 508: return this.emitError(new ServerError(enMsgs['508'], e), errorPoint); case 509: return this.emitError(new ServerError(enMsgs['509'], e), errorPoint); case 510: return this.emitError(new ServerError(enMsgs['510'], e), errorPoint); case 511: return this.emitError(new ServerError(enMsgs['511'], e), errorPoint); case 520: return this.emitError(new ServerError(enMsgs['520'], e), errorPoint); case 521: return this.emitError(new ServerError(enMsgs['521'], e), errorPoint); case 522: return this.emitError(new ServerError(enMsgs['522'], e), errorPoint); case 523: return this.emitError(new ServerError(enMsgs['523'], e), errorPoint); case 524: return this.emitError(new ServerError(enMsgs['524'], e), errorPoint); case 525: return this.emitError(new ServerError(enMsgs['525'], e), errorPoint); case 526: return this.emitError(new ServerError(enMsgs['526'], e), errorPoint); } return this.emitError(new UnusualError(enMsgs['unusual'], e), errorPoint); }; ErrorsStreamService.decorators = [ { type: Injectable }, ]; return ErrorsStreamService; }()); var TypeError$1 = (function () { function TypeError(type, message, cause) { this.message = message; this.cause = cause; this.name = type; this.stack = cause.stack; } return TypeError; }()); var AuthError = (function (_super) { __extends(AuthError, _super); function AuthError(message, cause) { return _super.call(this, 'AuthError', message, cause) || this; } return AuthError; }(TypeError$1)); var ClientError = (function (_super) { __extends(ClientError, _super); function ClientError(message, cause) { return _super.call(this, 'ClientError', message, cause) || this; } return ClientError; }(TypeError$1)); var ServerError = (function (_super) { __extends(ServerError, _super); function ServerError(message, cause) { return _super.call(this, 'ServerError', message, cause) || this; } return ServerError; }(TypeError$1)); var DisconnectedError = (function (_super) { __extends(DisconnectedError, _super); function DisconnectedError(message, cause) { return _super.call(this, 'DisconnectedError', message, cause) || this; } return DisconnectedError; }(TypeError$1)); var UnusualError = (function (_super) { __extends(UnusualError, _super); function UnusualError(message, cause) { return _super.call(this, 'UnusualError', message, cause) || this; } return UnusualError; }(TypeError$1)); var TimeoutError = (function (_super) { __extends(TimeoutError, _super); function TimeoutError(message, cause) { if (cause === void 0) { cause = {}; } var _this = _super.call(this, 'TimeoutError', message, cause) || this; _this.status = 408; return _this; } return TimeoutError; }(TypeError$1)); var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (undefined && undefined.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Мысли по поводу кеширования запросов: * * Что у нас есть? * Есть метод получающий ключ по которому можно проверить значение в хранилище. * * У нас есть запросы которые нужно кэшировать, а есть которые нет. т.е. методы. * GET запросы мы кэшируем. потому что мы получаем данные * POST, PUT, PATCH запросы мы кэшировать не можем так как они изменяют данные * итого кэшируются только GET запросы. * Нужно иметь глобальный флаг в конфигурации cache * а для каждого отдельно взятого запроса нужно иметь возможность * в конфиге опциях запроса нужно учесть флаг освежения запроса. если он true то в любом случае выполнить http запрос * * Нужно поработать с объектом типа storage. Создать ему еидный интерфей. продумать переключение между разными * хранилищами. * * У нас много хранилищь и конфигураций. При декларировании провайдера мы должны определить как именно будет создаваться * экземпляр класса ApiService и сделать это таким образом, чтоб эземпляру были переданы все нужные конфигурации путей * http и все возможные типы хранилищь из которых api.service сможет доставать данные. * Для обращения к хранилищу используем метод lookInStorage который посмотрит в конфигурации имя хранилища к которому * нужно обратиться за данными и выполнит обращение. Полученные данные вернет наружу. * * Если мы кэшируем какой лиюо get запрос то может возникнуть ситуация когда POST запросом или PATCH запросом данные * были изменены. В данной ситуации в кэше окажутся устаревшие данные. Нужно предусмотреть стратегию которая решит * данную проблему. * */ var API_CONFIG = new InjectionToken("ApiConfig"); var API_SERVICE = new InjectionToken("ApiService2"); var ApiService = (function () { function ApiService(http$$1, token, errors, loading, apiConfigs) { this.http = http$$1; this.token = token; this.errors = errors; this.loading = loading; this.apiConfigs = apiConfigs; this._defaultField = 'main'; } /** * @desc - получить конфигурацию по имени * * @template T * @param {?} name * @return {?} */ ApiService.prototype.getConfig = /** * @desc - получить конфигурацию по имени * * @template T * @param {?} name * @return {?} */ function (name) { var /** @type {?} */ config = this.apiConfigs.filter(function (config) { return config.name === name; }); return config.length != 0 ? config[0] : {}; }; /** * @desc - Задает конфигурацию которая будет использована для выполнения http запроса. Любой http запрос начинается с * этого метода. * * @template T * @param {?} name * @return {?} */ ApiService.prototype.useConfig = /** * @desc - Задает конфигурацию которая будет использована для выполнения http запроса. Любой http запрос начинается с * этого метода. * * @template T * @param {?} name * @return {?} */ function (name) { var _this = this; var /** @type {?} */ config = this.apiConfigs.filter(function (config) { return config.name === name; })[0]; return { /** * request обертка над request2 позволяющая контролировать тип используемой конфигурации. см. request2 * */ request: function (cb) { try { var /** @type {?} */ requestConfig = cb(config); requestConfig.useConfig = config.name; return _this.request2(requestConfig); } catch (/** @type {?} */ e) { console.error(e); } } }; }; /** * @desc - конфигурирует http запрос. устанавливает url, заголовки, токен параметры и т.д. * * @param {?} apiOptions * @return {?} */ ApiService.prototype.request2 = /** * @desc - конфигурирует http запрос. устанавливает url, заголовки, токен параметры и т.д. * * @param {?} apiOptions * @return {?} */ function (apiOptions) { // TODO предусмотреть переменную имяКонфига для экземпляра класса api (this.useConfig) var /** @type {?} */ token = this.token.get(), /** @type {?} */ config = this.getConfig(apiOptions.useConfig ? apiOptions.useConfig : this._defaultField); var method = apiOptions.method, subject = apiOptions.subject, just = apiOptions.just, param = apiOptions.param, _a = apiOptions.paramsArray, paramsArray = _a === void 0 ? [] : _a; var /** @type {?} */ httpParams = new HttpParams(), /** @type {?} */ headers = new HttpHeaders({}); apiOptions.url = apiOptions.url ? apiOptions.url : config[subject][just]; apiOptions.url = param ? apiOptions.url + "/" + param : apiOptions.url; apiOptions.timeout = apiOptions.timeout ? apiOptions.timeout : config.timeout; apiOptions.cache = apiOptions.cache !== undefined ? apiOptions.cache : config.cache; apiOptions.forcedRefresh = apiOptions.forcedRefresh !== undefined ? apiOptions.forcedRefresh : config.forcedRefresh; // метод get закодирует в encodeURI url включая правильную кодировку знаков "+" if (method.toLocaleLowerCase() === 'get') { apiOptions.url = this.encodeURL(apiOptions.url, paramsArray, config); } else { if (token) { httpParams = httpParams.set(config.tokenFieldName, token); } if (paramsArray) { paramsArray.forEach(function (item) { return httpParams = httpParams.set(item.key, String(item.val)); }); } } apiOptions.requestOptions = { headers: headers, withCredentials: config.withCredentials, params: httpParams }; return this.doRequest(apiOptions); }; /** * @desc - определяет какой метод (get, post и т.д.) нужно вызывать исходя из конфигурации * * @param {?} apiOptions * @return {?} */ ApiService.prototype.doRequest = /** * @desc - определяет какой метод (get, post и т.д.) нужно вызывать исходя из конфигурации * * @param {?} apiOptions * @return {?} */ function (apiOptions) { var url = apiOptions.url, method = apiOptions.method, requestOptions = apiOptions.requestOptions, body = apiOptions.body; switch (method.toLocaleLowerCase()) { case 'get': return this.getStartLoadingWrapper(this.http.get(url, requestOptions), apiOptions); // return this.http.get(url, options); case 'post': return this.getStartLoadingWrapper(this.http.post(url, body, requestOptions), apiOptions); // return this.http.post(url, body, options); case 'put': return this.getStartLoadingWrapper(this.http.put(url, body, requestOptions), apiOptions); // return this.http.put(url, body, options); case 'patch': return this.getStartLoadingWrapper(this.http.patch(url, body, requestOptions), apiOptions); // return this.http.patch(url, body, options); case 'delete': return this.getStartLoadingWrapper(this.http.delete(url, requestOptions), apiOptions); } }; /** * @desc - навешивает на http запрос функции общие для любого запроса. Генерация потока ошибок, потока загрузок * и таймаут запроса. Сюда можно добавить кэширование, повторные запросы при неудаче и др. * * @param {?} request * @param {?} apiOptions * @return {?} */ ApiService.prototype.getStartLoadingWrapper = /** * @desc - навешивает на http запрос функции общие для любого запроса. Генерация потока ошибок, потока загрузок * и таймаут запроса. Сюда можно добавить кэширование, повторные запросы при неудаче и др. * * @param {?} request * @param {?} apiOptions * @return {?} */ function (request, apiOptions) { var _this = this; var _a = apiOptions.requestPoint, requestPoint = _a === void 0 ? 'global' : _a, timeout = apiOptions.timeout, method = apiOptions.method, forcedRefresh = apiOptions.forcedRefresh; return { stream: function () { return request .do(function (d) { return _this.loading.emitLoading({ state: true, requestPoint: requestPoint }); }) .timeout(timeout) .catch(function (e) { _this.errors.defaultProcessing(e, requestPoint); if (e.name === "TimeoutError") throw new TimeoutError("timeout " + timeout + " expired", e); return Observable$1.of(e); }) .finally(function () { return _this.loading.emitLoading({ state: false, requestPoint: requestPoint }); }); }, promise: function () { return __awaiter(_this, void 0, void 0, function () { // let cache = this.checkConditionsAndGetCache(apiOptions); // if (cache !== null) return cache; var res, e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: this.loading.emitLoading({ state: true, requestPoint: requestPoint }); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, Promise.race([ request.toPromise(), new Promise(function (res, rej) { setTimeout(function () { return rej(new TimeoutError("timeout " + timeout + " expired")); }, timeout); }) ])]; case 2: res = _a.sent(); this.loading.emitLoading({ state: false, requestPoint: requestPoint }); // тут возвращаемое значение может быть закэшировоно return [2 /*return*/, res]; case 3: e_1 = _a.sent(); this.loading.emitLoading({ state: false, requestPoint: requestPoint }); this.errors.defaultProcessing(e_1, requestPoint); throw e_1; case 4: return [2 /*return*/]; } }); }); } }; }; /** * @desc - закодирует параметры get запроса. !!знак '+' нужно кодировать отдельно иначе возникнет ошибка!! * * @param {?} url * @param {?} paramsArray * @param {?} config * @return {?} */ ApiService.prototype.encodeURL = /** * @desc - закодирует параметры get запроса. !!знак '+' нужно кодировать отдельно иначе возникнет ошибка!! * * @param {?} url * @param {?} paramsArray * @param {?} config * @return {?} */ function (url, paramsArray, config) { var /** @type {?} */ token = this.token.get(); url = url + "?" + config.tokenFieldName + "=" + token; for (var _i = 0, paramsArray_1 = paramsArray; _i < paramsArray_1.length; _i++) { var item = paramsArray_1[_i]; var /** @type {?} */ param = encodeURI(item.key + "=" + item.val); url = url + "&" + param; } url = url.replace(/\+/g, '%2B'); return url; }; /** * @desc - проверяет уловия при которых можно отдавать закэшированное значение и если уловия верны возвращает кэш. * * @param {?} apiOptions * @return {?} */ ApiService.prototype.checkConditionsAndGetCache = /** * @desc - проверяет уловия при которых можно отдавать закэшированное значение и если уловия верны возвращает кэш. * * @param {?} apiOptions * @return {?} */ function (apiOptions) { var /** @type {?} */ config = this.configs[apiOptions.useConfig ? apiOptions.useConfig : this._defaultField]; var url = apiOptions.url, requestOptions = apiOptions.requestOptions, method = apiOptions.method, forcedRefresh = apiOptions.forcedRefresh; if (forcedRefresh === false) { var /** @type {?} */ cacheValue = this.lookInStorage(this.getKey(url, requestOptions.params, [config.tokenFieldName])); if (method === 'get' && cacheValue) return cacheValue; } return null; }; /** * @desc - Для обращения к хранилищу используем метод lookInStorage который посмотрит в конфигурации имя хранилища * к которому нужно обратиться за данными и выполнит обращение. Полученные данные вернет наружу. * * @param {?} key * @param {?=} storage * @return {?} */ ApiService.prototype.lookInStorage = /** * @desc - Для обращения к хранилищу используем метод lookInStorage который посмотрит в конфигурации имя хранилища * к которому нужно обратиться за данными и выполнит обращение. Полученные данные вернет наружу. * * @param {?} key * @param {?=} storage * @return {?} */ function (key, storage) { if (storage === void 0) { storage = this._defaultField; } return this.storages[storage].get(key); }; /** * @desc - Используя базовый url и набор GET параметров запроса формирует имя ключа для сохранения и получения * закэшированных данных для данного url. * * @template T * @param {?} baseURL * @param {?} params * @param {?=} exclude * @return {?} */ ApiService.prototype.getKey = /** * @desc - Используя базовый url и набор GET параметров запроса формирует имя ключа для сохранения и получения * закэшированных данных для данного url. * * @template T * @param {?} baseURL * @param {?} params * @param {?=} exclude * @return {?} */ function (baseURL, params, exclude) { if (exclude === void 0) { exclude = []; } var /** @type {?} */ cloneParams = null, /** @type {?} */ finallyParams; for (var _i = 0, exclude_1 = exclude; _i < exclude_1.length; _i++) { var param = exclude_1[_i]; cloneParams = params["delete"](param); } finallyParams = cloneParams ? cloneParams.toString() : params.toString(); return "" + baseURL + (finallyParams ? "?" + finallyParams : ""); }; ApiService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ApiService.ctorParameters = function () { return [ { type: HttpClient, }, { type: TokenService, }, { type: ErrorsStreamService, }, { type: LoadingStreamService, }, { type: undefined, decorators: [{ type: Inject, args: [API_CONFIG,] },] }, ]; }; return ApiService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var MemoryStorage = (function () { function MemoryStorage() { } /** * @param {?} key * @return {?} */ MemoryStorage.prototype.get = /** * @param {?} key * @return {?} */ function (key) { var /** @type {?} */ rawData = this[key]; if (!rawData) return null; var /** @type {?} */ data = MemoryStorage.isFresh(rawData.lastUpdate, rawData.howLongIsItFresh) ? rawData : null; // если данные устарели удалим их из хранилища if (data === null) this[key] = undefined; return data; }; /** * @param {?} key * @param {?} data * @return {?} */ MemoryStorage.prototype.set = /** * @param {?} key * @param {?} data * @return {?} */ function (key, data) { var /** @type {?} */ value = MemoryStorage.isFresh(data.lastUpdate, data.howLongIsItFresh) ? data : null; if (value === null) return null; this[key] = value; return data; }; /** * @param {?} lastUpdate * @param {?} howLongIsItFresh * @return {?} */ MemoryStorage.isFresh = /** * @param {?} lastUpdate * @param {?} howLongIsItFresh * @return {?} */ function (lastUpdate, howLongIsItFresh) { var /** @type {?} */ now = Number(+(new Date())); var /** @type {?} */ timeAfterLastUpdate = now - lastUpdate; return timeAfterLastUpdate < howLongIsItFresh; }; MemoryStorage.decorators = [ { type: Injectable }, ]; return MemoryStorage; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var LocalStorage = (function () { function LocalStorage() { } /** * @param {?} key * @return {?} */ LocalStorage.prototype.get = /** * @param {?} key * @return {?} */ function (key) { var /** @type {?} */ rawData = localStorage.getItem(key); if (!rawData) return null; var /** @type {?} */ data = this._parseDataWithExpirationDate(rawData); // если данные устарели удалим их из хранилища if (data === null) localStorage.removeItem(key); return data; }; /** * @param {?} key * @param {?} data * @return {?} */ LocalStorage.prototype.set = /** * @param {?} key * @param {?} data * @return {?} */ function (key, data) { var /** @type {?} */ value = this._stringifyDataWithExpirationDate(data); if (value === null) return null; localStorage.setItem(key, value); return data; }; /** * @param {?} lastUpdate * @param {?} howLongIsItFresh * @return {?} */ LocalStorage.isFresh = /** * @param {?} lastUpdate * @param {?} howLongIsItFresh * @return {?} */ function (lastUpdate, howLongIsItFresh) { var /** @type {?} */ now = Number(+(new Date())); var /** @type {?} */ timeAfterLastUpdate = now - lastUpdate; return timeAfterLastUpdate < howLongIsItFresh; }; /** * @param {?} data * @return {?} */ LocalStorage.prototype._parseDataWithExpirationDate = /** * @param {?} data * @return {?} */ function (data) { if (!data) return null; var /** @type {?} */ res = JSON.parse(data); if (!LocalStorage.isFresh(res.lastUpdate, res.howLongIsItFresh)) { return null; } return res; }; /** * @param {?} data * @return {?} */ LocalStorage.prototype._stringifyDataWithExpirationDate = /** * @param {?} data * @return {?} */ function (data) { if (!data) return null; if (!LocalStorage.isFresh(data.lastUpdate, data.howLongIsItFresh)) { return null; } return JSON.stringify(data); }; LocalStorage.decorators = [ { type: Injectable }, ]; return LocalStorage; }()); var __assign = (undefined && undefined.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var NgxApiManager = (function () { function NgxApiManager() { } /** * @param {?=} options * @return {?} */ NgxApiManager.forRoot = /** * @param {?=} options * @return {?} */ function (options) { if (options === void 0) { options = {}; } return { ngModule: NgxApiManager, providers: options.configs.map(function (config) { return { provide: API_CONFIG, useValue: config, multi: true }; }).concat([ { provide: API_SERVICE, // не забывайте при передаче в deps сервиса класс является маркером. deps: [ HttpClient, TokenService, ErrorsStreamService, LoadingStreamService, API_CONFIG, MemoryStorage, LocalStorage ], useFactory: function (httpClient, tokenService, errorsService, loadingService, apiConfigs, memoryStorage, localStorage) { var /** @type {?} */ api = new ApiService(httpClient, tokenService, errorsService, loadingService, apiConfigs); // пока тестируются функции кэширования используется данное решение. // когда storages будут внедрены то подключаться они будут как apiConfigs api.storages = __assign({}, options.storages, { main: memoryStorage, localStorage: localStorage }); return api; } } ]) }; }; NgxApiManager.decorators = [ { type: NgModule, args: [{ providers: [ HttpClient, ApiService, TokenService, MemoryStorage, LocalStorage, ErrorsStreamService, LoadingStreamService ], exports: [] },] }, ]; return NgxApiManager; }()); export { NgxApiManager, API_CONFIG, API_SERVICE, ApiService, TokenService, ErrorsStreamService, TypeError$1 as TypeError, AuthError, ClientError, ServerError, DisconnectedError, UnusualError, TimeoutError, LoadingStreamService };