ng-http-caching 1.0.13 → 13.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +228 -16
  2. package/esm2020/lib/ng-http-caching-interceptor.service.mjs +66 -0
  3. package/esm2020/lib/ng-http-caching.module.mjs +45 -0
  4. package/esm2020/lib/ng-http-caching.service.mjs +265 -0
  5. package/esm2020/lib/storage/ng-http-caching-memory-storage.mjs +28 -0
  6. package/esm2020/lib/storage/ng-http-caching-storage.interface.mjs +2 -0
  7. package/{esm2015/ng-http-caching.js → esm2020/ng-http-caching.mjs} +0 -0
  8. package/esm2020/public-api.mjs +9 -0
  9. package/fesm2015/ng-http-caching.mjs +410 -0
  10. package/fesm2015/ng-http-caching.mjs.map +1 -0
  11. package/{fesm2015/ng-http-caching.js → fesm2020/ng-http-caching.mjs} +104 -56
  12. package/fesm2020/ng-http-caching.mjs.map +1 -0
  13. package/lib/ng-http-caching-interceptor.service.d.ts +2 -2
  14. package/lib/ng-http-caching.module.d.ts +3 -2
  15. package/lib/ng-http-caching.service.d.ts +14 -5
  16. package/lib/storage/ng-http-caching-memory-storage.d.ts +12 -0
  17. package/lib/storage/ng-http-caching-storage.interface.d.ts +10 -0
  18. package/package.json +24 -14
  19. package/public-api.d.ts +2 -0
  20. package/bundles/ng-http-caching.umd.js +0 -385
  21. package/bundles/ng-http-caching.umd.js.map +0 -1
  22. package/bundles/ng-http-caching.umd.min.js +0 -2
  23. package/bundles/ng-http-caching.umd.min.js.map +0 -1
  24. package/esm2015/lib/ng-http-caching-interceptor.service.js +0 -65
  25. package/esm2015/lib/ng-http-caching.module.js +0 -44
  26. package/esm2015/lib/ng-http-caching.service.js +0 -247
  27. package/esm2015/public-api.js +0 -7
  28. package/fesm2015/ng-http-caching.js.map +0 -1
@@ -1,385 +0,0 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/common/http'), require('@angular/core'), require('rxjs'), require('rxjs/operators')) :
3
- typeof define === 'function' && define.amd ? define('ng-http-caching', ['exports', '@angular/common/http', '@angular/core', 'rxjs', 'rxjs/operators'], factory) :
4
- (global = global || self, factory(global['ng-http-caching'] = {}, global.ng.common.http, global.ng.core, global.rxjs, global.rxjs.operators));
5
- }(this, (function (exports, http, i0, rxjs, operators) { 'use strict';
6
-
7
- var NG_HTTP_CACHING_CONFIG = new i0.InjectionToken('ng-http-caching.config');
8
- (function (NgHttpCachingStrategy) {
9
- NgHttpCachingStrategy["ALLOW_ALL"] = "ALLOW_ALL";
10
- NgHttpCachingStrategy["DISALLOW_ALL"] = "DISALLOW_ALL";
11
- })(exports.NgHttpCachingStrategy || (exports.NgHttpCachingStrategy = {}));
12
- (function (NgHttpCachingHeaders) {
13
- NgHttpCachingHeaders["ALLOW_CACHE"] = "X-NG-HTTP-CACHING-ALLOW-CACHE";
14
- NgHttpCachingHeaders["DISALLOW_CACHE"] = "X-NG-HTTP-CACHING-DISALLOW-CACHE";
15
- NgHttpCachingHeaders["LIFETIME"] = "X-NG-HTTP-CACHING-LIFETIME";
16
- NgHttpCachingHeaders["TAG"] = "X-NG-HTTP-CACHING-TAG";
17
- })(exports.NgHttpCachingHeaders || (exports.NgHttpCachingHeaders = {}));
18
- var NgHttpCachingConfig = /** @class */ (function () {
19
- function NgHttpCachingConfig() {
20
- }
21
- return NgHttpCachingConfig;
22
- }());
23
- var NgHttpCachingConfigDefault = {
24
- lifetime: 60 * 60 * 100,
25
- allowedMethod: ['GET'],
26
- cacheStrategy: exports.NgHttpCachingStrategy.ALLOW_ALL,
27
- };
28
- var NgHttpCachingService = /** @class */ (function () {
29
- function NgHttpCachingService(config) {
30
- this.store = new Map();
31
- this.queue = new Map();
32
- if (config) {
33
- this.config = Object.assign(Object.assign({}, NgHttpCachingConfigDefault), config);
34
- }
35
- else {
36
- this.config = NgHttpCachingConfigDefault;
37
- }
38
- }
39
- /**
40
- * Return the config
41
- */
42
- NgHttpCachingService.prototype.getConfig = function () {
43
- return this.config;
44
- };
45
- /**
46
- * Return response from cache
47
- */
48
- NgHttpCachingService.prototype.getFromCache = function (req) {
49
- var key = this.getKey(req);
50
- var cached = this.store.get(key);
51
- if (!cached) {
52
- return undefined;
53
- }
54
- if (this.isExpired(cached)) {
55
- this.clearCacheByKey(key);
56
- return undefined;
57
- }
58
- return cached.response;
59
- };
60
- /**
61
- * Add response to cache
62
- */
63
- NgHttpCachingService.prototype.addToCache = function (req, res) {
64
- var key = this.getKey(req);
65
- var entry = {
66
- url: req.urlWithParams,
67
- response: res,
68
- request: req,
69
- addedTime: Date.now(),
70
- };
71
- if (this.isValid(entry)) {
72
- this.store.set(key, entry);
73
- return true;
74
- }
75
- return false;
76
- };
77
- /**
78
- * Delete response from cache
79
- */
80
- NgHttpCachingService.prototype.deleteFromCache = function (req) {
81
- var key = this.getKey(req);
82
- return this.clearCacheByKey(key);
83
- };
84
- /**
85
- * Clear the cache
86
- */
87
- NgHttpCachingService.prototype.clearCache = function () {
88
- this.store.clear();
89
- };
90
- /**
91
- * Clear the cache by key
92
- */
93
- NgHttpCachingService.prototype.clearCacheByKey = function (key) {
94
- return this.store.delete(key);
95
- };
96
- /**
97
- * Clear the cache by regex
98
- */
99
- NgHttpCachingService.prototype.clearCacheByRegex = function (regex) {
100
- var _this = this;
101
- this.store.forEach(function (entry, key) {
102
- if (regex.test(key)) {
103
- _this.clearCacheByKey(key);
104
- }
105
- });
106
- };
107
- /**
108
- * Clear the cache by TAG
109
- */
110
- NgHttpCachingService.prototype.clearCacheByTag = function (tag) {
111
- var _this = this;
112
- this.store.forEach(function (entry, key) {
113
- var tagHeader = entry.request.headers.get(exports.NgHttpCachingHeaders.TAG);
114
- if (tagHeader && tagHeader.split(',').includes(tag)) {
115
- _this.clearCacheByKey(key);
116
- }
117
- });
118
- };
119
- /**
120
- * Run garbage collector (delete expired cache entry)
121
- */
122
- NgHttpCachingService.prototype.runGc = function () {
123
- var _this = this;
124
- this.store.forEach(function (entry, key) {
125
- if (_this.isExpired(entry)) {
126
- _this.clearCacheByKey(key);
127
- }
128
- });
129
- };
130
- /**
131
- * Return true if cache entry is expired
132
- */
133
- NgHttpCachingService.prototype.isExpired = function (entry) {
134
- // if user provide custom method, use it
135
- if (typeof this.config.isExpired === 'function') {
136
- var result = this.config.isExpired(entry);
137
- // if result is undefined, normal behaviour is provided
138
- if (typeof result !== 'undefined') {
139
- return result;
140
- }
141
- }
142
- // config/default lifetime
143
- var lifetime = this.config.lifetime;
144
- // request has own lifetime
145
- if (entry.request.headers.has(exports.NgHttpCachingHeaders.LIFETIME)) {
146
- lifetime = +entry.request.headers.get(exports.NgHttpCachingHeaders.LIFETIME);
147
- }
148
- // never expire if 0
149
- if (lifetime === 0) {
150
- return false;
151
- }
152
- // wrong lifetime
153
- if (lifetime < 0) {
154
- throw new Error('lifetime must be greater than or equal 0');
155
- }
156
- return entry.addedTime + lifetime < Date.now();
157
- };
158
- /**
159
- * Return true if cache entry is valid for store in the cache
160
- */
161
- NgHttpCachingService.prototype.isValid = function (entry) {
162
- // if user provide custom method, use it
163
- if (typeof this.config.isValid === 'function') {
164
- var result = this.config.isValid(entry);
165
- // if result is undefined, normal behaviour is provided
166
- if (typeof result !== 'undefined') {
167
- return result;
168
- }
169
- }
170
- return true;
171
- };
172
- /**
173
- * Return true if the request is cacheable
174
- */
175
- NgHttpCachingService.prototype.isCacheable = function (req) {
176
- // if user provide custom method, use it
177
- if (typeof this.config.isCacheable === 'function') {
178
- var result = this.config.isCacheable(req);
179
- // if result is undefined, normal behaviour is provided
180
- if (typeof result !== 'undefined') {
181
- return result;
182
- }
183
- }
184
- // request has disallow cache header
185
- if (req.headers.has(exports.NgHttpCachingHeaders.DISALLOW_CACHE)) {
186
- return false;
187
- }
188
- // strategy is disallow all...
189
- if (this.config.cacheStrategy === exports.NgHttpCachingStrategy.DISALLOW_ALL) {
190
- // request isn't allowed if come without allow header
191
- if (!req.headers.has(exports.NgHttpCachingHeaders.ALLOW_CACHE)) {
192
- return false;
193
- }
194
- }
195
- // if allowed method is only ALL, allow all http methos
196
- if (this.config.allowedMethod.length === 1) {
197
- if (this.config.allowedMethod[0] === 'ALL') {
198
- return true;
199
- }
200
- }
201
- // request is allowed if method is in allowedMethod
202
- return this.config.allowedMethod.indexOf(req.method) !== -1;
203
- };
204
- /**
205
- * Return the cache key
206
- */
207
- NgHttpCachingService.prototype.getKey = function (req) {
208
- // if user provide custom method, use it
209
- if (typeof this.config.getKey === 'function') {
210
- var result = this.config.getKey(req);
211
- // if result is undefined, normal behaviour is provided
212
- if (typeof result !== 'undefined') {
213
- return result;
214
- }
215
- }
216
- // default key id is url with query parameters
217
- return req.urlWithParams;
218
- };
219
- /**
220
- * Return observable from cache
221
- */
222
- NgHttpCachingService.prototype.getFromQueue = function (req) {
223
- var key = this.getKey(req);
224
- var cached = this.queue.get(key);
225
- if (!cached) {
226
- return undefined;
227
- }
228
- return cached;
229
- };
230
- /**
231
- * Add observable to cache
232
- */
233
- NgHttpCachingService.prototype.addToQueue = function (req, obs) {
234
- var key = this.getKey(req);
235
- this.queue.set(key, obs);
236
- };
237
- /**
238
- * Delete observable from cache
239
- */
240
- NgHttpCachingService.prototype.deleteFromQueue = function (req) {
241
- var key = this.getKey(req);
242
- return this.queue.delete(key);
243
- };
244
- return NgHttpCachingService;
245
- }());
246
- NgHttpCachingService.ɵfac = function NgHttpCachingService_Factory(t) { return new (t || NgHttpCachingService)(i0.ɵɵinject(NG_HTTP_CACHING_CONFIG, 8)); };
247
- NgHttpCachingService.ɵprov = i0.ɵɵdefineInjectable({ token: NgHttpCachingService, factory: NgHttpCachingService.ɵfac });
248
- /*@__PURE__*/ (function () {
249
- i0.ɵsetClassMetadata(NgHttpCachingService, [{
250
- type: i0.Injectable
251
- }], function () {
252
- return [{ type: NgHttpCachingConfig, decorators: [{
253
- type: i0.Inject,
254
- args: [NG_HTTP_CACHING_CONFIG]
255
- }, {
256
- type: i0.Optional
257
- }] }];
258
- }, null);
259
- })();
260
-
261
- var NgHttpCachingInterceptorService = /** @class */ (function () {
262
- function NgHttpCachingInterceptorService(cacheService) {
263
- this.cacheService = cacheService;
264
- }
265
- NgHttpCachingInterceptorService.prototype.intercept = function (req, next) {
266
- var _this = this;
267
- // run garbage collector
268
- this.cacheService.runGc();
269
- // Don't cache if it's not cacheable
270
- if (!this.cacheService.isCacheable(req)) {
271
- return this.sendRequest(req, next);
272
- }
273
- // Checked if there is pending response for this request
274
- var cachedObservable = this.cacheService.getFromQueue(req);
275
- if (cachedObservable) {
276
- // console.log('cachedObservable', req);
277
- return cachedObservable;
278
- }
279
- // Checked if there is cached response for this request
280
- var cachedResponse = this.cacheService.getFromCache(req);
281
- if (cachedResponse) {
282
- // console.log('cachedResponse', req);
283
- return rxjs.of(cachedResponse.clone());
284
- }
285
- // If the request of going through for first time
286
- // then let the request proceed and cache the response
287
- // console.log('sendRequest', req);
288
- var shared = this.sendRequest(req, next).pipe(operators.tap(function (event) {
289
- if (event instanceof http.HttpResponse) {
290
- _this.cacheService.addToCache(req, event.clone());
291
- }
292
- }), operators.finalize(function () {
293
- // delete pending request
294
- _this.cacheService.deleteFromQueue(req);
295
- }), operators.share());
296
- // add pending request to queue for cache parallell request
297
- this.cacheService.addToQueue(req, shared);
298
- return shared;
299
- };
300
- /**
301
- * Send http request (next handler)
302
- */
303
- NgHttpCachingInterceptorService.prototype.sendRequest = function (req, next) {
304
- var cloned = req.clone();
305
- // trim custom headers before send request
306
- Object.values(exports.NgHttpCachingHeaders).forEach(function (ngHttpCachingHeaders) {
307
- if (cloned.headers.has(ngHttpCachingHeaders)) {
308
- cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });
309
- }
310
- });
311
- return next.handle(cloned);
312
- };
313
- return NgHttpCachingInterceptorService;
314
- }());
315
- NgHttpCachingInterceptorService.ɵfac = function NgHttpCachingInterceptorService_Factory(t) { return new (t || NgHttpCachingInterceptorService)(i0.ɵɵinject(NgHttpCachingService)); };
316
- NgHttpCachingInterceptorService.ɵprov = i0.ɵɵdefineInjectable({ token: NgHttpCachingInterceptorService, factory: NgHttpCachingInterceptorService.ɵfac });
317
- /*@__PURE__*/ (function () {
318
- i0.ɵsetClassMetadata(NgHttpCachingInterceptorService, [{
319
- type: i0.Injectable
320
- }], function () { return [{ type: NgHttpCachingService }]; }, null);
321
- })();
322
-
323
- var NgHttpCachingModule = /** @class */ (function () {
324
- function NgHttpCachingModule() {
325
- }
326
- NgHttpCachingModule.forRoot = function (ngHttpCachingConfig) {
327
- return {
328
- ngModule: NgHttpCachingModule,
329
- providers: [
330
- {
331
- provide: NG_HTTP_CACHING_CONFIG,
332
- useValue: ngHttpCachingConfig,
333
- },
334
- ],
335
- };
336
- };
337
- return NgHttpCachingModule;
338
- }());
339
- NgHttpCachingModule.ɵmod = i0.ɵɵdefineNgModule({ type: NgHttpCachingModule });
340
- NgHttpCachingModule.ɵinj = i0.ɵɵdefineInjector({ factory: function NgHttpCachingModule_Factory(t) { return new (t || NgHttpCachingModule)(); }, providers: [
341
- NgHttpCachingService,
342
- {
343
- provide: http.HTTP_INTERCEPTORS,
344
- useClass: NgHttpCachingInterceptorService,
345
- multi: true,
346
- },
347
- ], imports: [[]] });
348
- /*@__PURE__*/ (function () {
349
- i0.ɵsetClassMetadata(NgHttpCachingModule, [{
350
- type: i0.NgModule,
351
- args: [{
352
- declarations: [],
353
- imports: [],
354
- providers: [
355
- NgHttpCachingService,
356
- {
357
- provide: http.HTTP_INTERCEPTORS,
358
- useClass: NgHttpCachingInterceptorService,
359
- multi: true,
360
- },
361
- ],
362
- exports: [],
363
- }]
364
- }], null, null);
365
- })();
366
-
367
- /*
368
- * Public API Surface of ng-http-caching
369
- */
370
-
371
- /**
372
- * Generated bundle index. Do not edit.
373
- */
374
-
375
- exports.NG_HTTP_CACHING_CONFIG = NG_HTTP_CACHING_CONFIG;
376
- exports.NgHttpCachingConfig = NgHttpCachingConfig;
377
- exports.NgHttpCachingConfigDefault = NgHttpCachingConfigDefault;
378
- exports.NgHttpCachingInterceptorService = NgHttpCachingInterceptorService;
379
- exports.NgHttpCachingModule = NgHttpCachingModule;
380
- exports.NgHttpCachingService = NgHttpCachingService;
381
-
382
- Object.defineProperty(exports, '__esModule', { value: true });
383
-
384
- })));
385
- //# sourceMappingURL=ng-http-caching.umd.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ng-http-caching.umd.js","sources":["../../../projects/ng-http-caching/src/lib/ng-http-caching.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching-interceptor.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.module.ts","../../../projects/ng-http-caching/src/public-api.ts","../../../projects/ng-http-caching/src/ng-http-caching.ts"],"sourcesContent":["import { Injectable, InjectionToken, Inject, Optional } from '@angular/core';\nimport { HttpRequest, HttpResponse, HttpEvent } from '@angular/common/http';\nimport { Observable } from 'rxjs/internal/Observable';\n\nexport interface NgHttpCachingEntry {\n url: string;\n response: HttpResponse<any>;\n request: HttpRequest<any>;\n addedTime: number;\n}\n\nexport const NG_HTTP_CACHING_CONFIG = new InjectionToken<NgHttpCachingConfig>(\n 'ng-http-caching.config'\n);\n\nexport enum NgHttpCachingStrategy {\n ALLOW_ALL = 'ALLOW_ALL',\n DISALLOW_ALL = 'DISALLOW_ALL',\n}\n\nexport enum NgHttpCachingHeaders {\n ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',\n DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',\n LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',\n TAG = 'X-NG-HTTP-CACHING-TAG',\n}\nexport class NgHttpCachingConfig {\n lifetime?: number;\n allowedMethod?: string[];\n cacheStrategy?: NgHttpCachingStrategy;\n isExpired?: (entry: NgHttpCachingEntry) => boolean | undefined;\n isCacheable?: (req: HttpRequest<any>) => boolean | undefined;\n getKey?: (req: HttpRequest<any>) => string | undefined;\n isValid?: (entry: NgHttpCachingEntry) => boolean | undefined;\n}\n\nexport const NgHttpCachingConfigDefault: NgHttpCachingConfig = {\n lifetime: 60 * 60 * 100,\n allowedMethod: ['GET'],\n cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,\n};\n\n@Injectable()\nexport class NgHttpCachingService {\n\n public readonly store = new Map<string, NgHttpCachingEntry>();\n\n public readonly queue = new Map<string, Observable<HttpEvent<any>>>();\n\n private config: NgHttpCachingConfig;\n\n constructor(\n @Inject(NG_HTTP_CACHING_CONFIG) @Optional() config: NgHttpCachingConfig\n ) {\n if (config) {\n this.config = { ...NgHttpCachingConfigDefault, ...config };\n } else {\n this.config = NgHttpCachingConfigDefault;\n }\n }\n\n /**\n * Return the config\n */\n getConfig(): NgHttpCachingConfig {\n return this.config;\n }\n\n /**\n * Return response from cache\n */\n getFromCache(req: HttpRequest<any>): HttpResponse<any> | undefined {\n const key: string = this.getKey(req);\n const cached: NgHttpCachingEntry = this.store.get(key);\n\n if (!cached) {\n return undefined;\n }\n\n if (this.isExpired(cached)) {\n this.clearCacheByKey(key);\n return undefined;\n }\n\n return cached.response;\n }\n\n /**\n * Add response to cache\n */\n addToCache(req: HttpRequest<any>, res: HttpResponse<any>): boolean {\n const key: string = this.getKey(req);\n const entry: NgHttpCachingEntry = {\n url: req.urlWithParams,\n response: res,\n request: req,\n addedTime: Date.now(),\n };\n if ( this.isValid(entry) ) {\n this.store.set(key, entry);\n return true;\n }\n return false;\n }\n\n /**\n * Delete response from cache\n */\n deleteFromCache(req: HttpRequest<any>): boolean {\n const key: string = this.getKey(req);\n return this.clearCacheByKey(key);\n }\n\n /**\n * Clear the cache\n */\n clearCache(): void {\n this.store.clear();\n }\n\n /**\n * Clear the cache by key\n */\n clearCacheByKey(key: string): boolean {\n return this.store.delete(key);\n }\n\n /**\n * Clear the cache by regex\n */\n clearCacheByRegex(regex: RegExp): void {\n this.store.forEach((entry: NgHttpCachingEntry, key: string) => {\n if ( regex.test(key) ){\n this.clearCacheByKey(key);\n }\n });\n }\n\n /**\n * Clear the cache by TAG\n */\n clearCacheByTag(tag: string): void {\n this.store.forEach((entry: NgHttpCachingEntry, key: string) => {\n const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);\n if ( tagHeader && tagHeader.split(',').includes(tag) ){\n this.clearCacheByKey(key);\n }\n });\n }\n\n /**\n * Run garbage collector (delete expired cache entry)\n */\n runGc(): void {\n this.store.forEach((entry: NgHttpCachingEntry, key: string) => {\n if ( this.isExpired(entry) ){\n this.clearCacheByKey(key);\n }\n });\n }\n\n /**\n * Return true if cache entry is expired\n */\n isExpired(entry: NgHttpCachingEntry): boolean {\n // if user provide custom method, use it\n if (typeof this.config.isExpired === 'function') {\n const result = this.config.isExpired(entry);\n // if result is undefined, normal behaviour is provided\n if (typeof result !== 'undefined') {\n return result;\n }\n }\n // config/default lifetime\n let lifetime = this.config.lifetime;\n // request has own lifetime\n if (entry.request.headers.has(NgHttpCachingHeaders.LIFETIME)) {\n lifetime = +entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);\n }\n // never expire if 0\n if (lifetime === 0) {\n return false;\n }\n // wrong lifetime\n if (lifetime < 0) {\n throw new Error('lifetime must be greater than or equal 0');\n }\n return entry.addedTime + lifetime < Date.now();\n }\n\n /**\n * Return true if cache entry is valid for store in the cache\n */\n isValid(entry: NgHttpCachingEntry): boolean {\n // if user provide custom method, use it\n if (typeof this.config.isValid === 'function') {\n const result = this.config.isValid(entry);\n // if result is undefined, normal behaviour is provided\n if (typeof result !== 'undefined') {\n return result;\n }\n }\n return true;\n }\n\n /**\n * Return true if the request is cacheable\n */\n isCacheable(req: HttpRequest<any>): boolean {\n // if user provide custom method, use it\n if (typeof this.config.isCacheable === 'function') {\n const result = this.config.isCacheable(req);\n // if result is undefined, normal behaviour is provided\n if (typeof result !== 'undefined') {\n return result;\n }\n }\n // request has disallow cache header\n if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {\n return false;\n }\n // strategy is disallow all...\n if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {\n // request isn't allowed if come without allow header\n if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {\n return false;\n }\n }\n // if allowed method is only ALL, allow all http methos\n if ( this.config.allowedMethod.length === 1) {\n if (this.config.allowedMethod[0] === 'ALL'){\n return true;\n }\n }\n // request is allowed if method is in allowedMethod\n return this.config.allowedMethod.indexOf(req.method) !== -1;\n }\n\n /**\n * Return the cache key\n */\n getKey(req: HttpRequest<any>): string {\n // if user provide custom method, use it\n if (typeof this.config.getKey === 'function') {\n const result = this.config.getKey(req);\n // if result is undefined, normal behaviour is provided\n if (typeof result !== 'undefined') {\n return result;\n }\n }\n // default key id is url with query parameters\n return req.urlWithParams;\n }\n\n /**\n * Return observable from cache\n */\n getFromQueue(req: HttpRequest<any>): Observable<HttpEvent<any>> | undefined {\n const key: string = this.getKey(req);\n const cached: Observable<HttpEvent<any>> = this.queue.get(key);\n\n if (!cached) {\n return undefined;\n }\n\n return cached;\n }\n\n /**\n * Add observable to cache\n */\n addToQueue(req: HttpRequest<any>, obs: Observable<HttpEvent<any>>): void {\n const key: string = this.getKey(req);\n this.queue.set(key, obs);\n }\n\n /**\n * Delete observable from cache\n */\n deleteFromQueue(req: HttpRequest<any>): boolean {\n const key: string = this.getKey(req);\n return this.queue.delete(key);\n }\n}\n","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { tap, finalize, share } from 'rxjs/operators';\nimport { NgHttpCachingService, NgHttpCachingHeaders } from './ng-http-caching.service';\n\n\n@Injectable()\nexport class NgHttpCachingInterceptorService implements HttpInterceptor {\n\n constructor(private readonly cacheService: NgHttpCachingService) {}\n\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n // run garbage collector\n this.cacheService.runGc();\n\n // Don't cache if it's not cacheable\n if ( !this.cacheService.isCacheable(req) ) {\n return this.sendRequest(req, next);\n }\n\n // Checked if there is pending response for this request\n const cachedObservable: Observable<HttpEvent<any>> = this.cacheService.getFromQueue(req);\n if ( cachedObservable ) {\n // console.log('cachedObservable', req);\n return cachedObservable;\n }\n\n // Checked if there is cached response for this request\n const cachedResponse: HttpResponse<any> = this.cacheService.getFromCache(req);\n if (cachedResponse) {\n // console.log('cachedResponse', req);\n return of(cachedResponse.clone());\n }\n\n // If the request of going through for first time\n // then let the request proceed and cache the response\n // console.log('sendRequest', req);\n const shared = this.sendRequest(req, next).pipe(\n tap(event => {\n if (event instanceof HttpResponse) {\n this.cacheService.addToCache(req, event.clone());\n }\n }),\n finalize(() => {\n // delete pending request\n this.cacheService.deleteFromQueue(req);\n }),\n share()\n );\n\n // add pending request to queue for cache parallell request\n this.cacheService.addToQueue(req, shared);\n\n return shared;\n }\n\n /**\n * Send http request (next handler)\n */\n sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n let cloned: HttpRequest<any> = req.clone();\n // trim custom headers before send request\n Object.values(NgHttpCachingHeaders).forEach(ngHttpCachingHeaders => {\n if ( cloned.headers.has(ngHttpCachingHeaders) ) {\n cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });\n }\n });\n return next.handle(cloned);\n }\n}\n","import { NgModule, ModuleWithProviders } from '@angular/core';\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\nimport {\n NG_HTTP_CACHING_CONFIG,\n NgHttpCachingConfig,\n NgHttpCachingService,\n} from './ng-http-caching.service';\nimport { NgHttpCachingInterceptorService } from './ng-http-caching-interceptor.service';\n\n@NgModule({\n declarations: [],\n imports: [],\n providers: [\n NgHttpCachingService,\n {\n provide: HTTP_INTERCEPTORS,\n useClass: NgHttpCachingInterceptorService,\n multi: true,\n },\n ],\n exports: [],\n})\nexport class NgHttpCachingModule {\n static forRoot(\n ngHttpCachingConfig?: NgHttpCachingConfig\n ): ModuleWithProviders<NgHttpCachingModule> {\n return {\n ngModule: NgHttpCachingModule,\n providers: [\n {\n provide: NG_HTTP_CACHING_CONFIG,\n useValue: ngHttpCachingConfig,\n },\n ],\n };\n }\n}\n","/*\n * Public API Surface of ng-http-caching\n */\n\nexport * from './lib/ng-http-caching-interceptor.service';\nexport * from './lib/ng-http-caching.service';\nexport * from './lib/ng-http-caching.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["InjectionToken","NgHttpCachingStrategy","NgHttpCachingHeaders","Injectable","Inject","Optional","of","tap","HttpResponse","finalize","share","HTTP_INTERCEPTORS","NgModule"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/common/http"),require("@angular/core"),require("rxjs"),require("rxjs/operators")):"function"==typeof define&&define.amd?define("ng-http-caching",["exports","@angular/common/http","@angular/core","rxjs","rxjs/operators"],t):t((e=e||self)["ng-http-caching"]={},e.ng.common.http,e.ng.core,e.rxjs,e.rxjs.operators)}(this,(function(e,t,r,i,n){"use strict";var o,c,a=new r.InjectionToken("ng-http-caching.config");(o=e.NgHttpCachingStrategy||(e.NgHttpCachingStrategy={})).ALLOW_ALL="ALLOW_ALL",o.DISALLOW_ALL="DISALLOW_ALL",(c=e.NgHttpCachingHeaders||(e.NgHttpCachingHeaders={})).ALLOW_CACHE="X-NG-HTTP-CACHING-ALLOW-CACHE",c.DISALLOW_CACHE="X-NG-HTTP-CACHING-DISALLOW-CACHE",c.LIFETIME="X-NG-HTTP-CACHING-LIFETIME",c.TAG="X-NG-HTTP-CACHING-TAG";var s=function(){},h={lifetime:36e4,allowedMethod:["GET"],cacheStrategy:e.NgHttpCachingStrategy.ALLOW_ALL},u=function(){function t(e){this.store=new Map,this.queue=new Map,this.config=e?Object.assign(Object.assign({},h),e):h}return t.prototype.getConfig=function(){return this.config},t.prototype.getFromCache=function(e){var t=this.getKey(e),r=this.store.get(t);if(r){if(!this.isExpired(r))return r.response;this.clearCacheByKey(t)}},t.prototype.addToCache=function(e,t){var r=this.getKey(e),i={url:e.urlWithParams,response:t,request:e,addedTime:Date.now()};return!!this.isValid(i)&&(this.store.set(r,i),!0)},t.prototype.deleteFromCache=function(e){var t=this.getKey(e);return this.clearCacheByKey(t)},t.prototype.clearCache=function(){this.store.clear()},t.prototype.clearCacheByKey=function(e){return this.store.delete(e)},t.prototype.clearCacheByRegex=function(e){var t=this;this.store.forEach((function(r,i){e.test(i)&&t.clearCacheByKey(i)}))},t.prototype.clearCacheByTag=function(t){var r=this;this.store.forEach((function(i,n){var o=i.request.headers.get(e.NgHttpCachingHeaders.TAG);o&&o.split(",").includes(t)&&r.clearCacheByKey(n)}))},t.prototype.runGc=function(){var e=this;this.store.forEach((function(t,r){e.isExpired(t)&&e.clearCacheByKey(r)}))},t.prototype.isExpired=function(t){if("function"==typeof this.config.isExpired){var r=this.config.isExpired(t);if(void 0!==r)return r}var i=this.config.lifetime;if(t.request.headers.has(e.NgHttpCachingHeaders.LIFETIME)&&(i=+t.request.headers.get(e.NgHttpCachingHeaders.LIFETIME)),0===i)return!1;if(i<0)throw new Error("lifetime must be greater than or equal 0");return t.addedTime+i<Date.now()},t.prototype.isValid=function(e){if("function"==typeof this.config.isValid){var t=this.config.isValid(e);if(void 0!==t)return t}return!0},t.prototype.isCacheable=function(t){if("function"==typeof this.config.isCacheable){var r=this.config.isCacheable(t);if(void 0!==r)return r}return!t.headers.has(e.NgHttpCachingHeaders.DISALLOW_CACHE)&&(!(this.config.cacheStrategy===e.NgHttpCachingStrategy.DISALLOW_ALL&&!t.headers.has(e.NgHttpCachingHeaders.ALLOW_CACHE))&&(1===this.config.allowedMethod.length&&"ALL"===this.config.allowedMethod[0]||-1!==this.config.allowedMethod.indexOf(t.method)))},t.prototype.getKey=function(e){if("function"==typeof this.config.getKey){var t=this.config.getKey(e);if(void 0!==t)return t}return e.urlWithParams},t.prototype.getFromQueue=function(e){var t=this.getKey(e),r=this.queue.get(t);if(r)return r},t.prototype.addToQueue=function(e,t){var r=this.getKey(e);this.queue.set(r,t)},t.prototype.deleteFromQueue=function(e){var t=this.getKey(e);return this.queue.delete(t)},t}();u.ɵfac=function(e){return new(e||u)(r.ɵɵinject(a,8))},u.ɵprov=r.ɵɵdefineInjectable({token:u,factory:u.ɵfac});var f=function(){function r(e){this.cacheService=e}return r.prototype.intercept=function(e,r){var o=this;if(this.cacheService.runGc(),!this.cacheService.isCacheable(e))return this.sendRequest(e,r);var c=this.cacheService.getFromQueue(e);if(c)return c;var a=this.cacheService.getFromCache(e);if(a)return i.of(a.clone());var s=this.sendRequest(e,r).pipe(n.tap((function(r){r instanceof t.HttpResponse&&o.cacheService.addToCache(e,r.clone())})),n.finalize((function(){o.cacheService.deleteFromQueue(e)})),n.share());return this.cacheService.addToQueue(e,s),s},r.prototype.sendRequest=function(t,r){var i=t.clone();return Object.values(e.NgHttpCachingHeaders).forEach((function(e){i.headers.has(e)&&(i=i.clone({headers:i.headers.delete(e)}))})),r.handle(i)},r}();f.ɵfac=function(e){return new(e||f)(r.ɵɵinject(u))},f.ɵprov=r.ɵɵdefineInjectable({token:f,factory:f.ɵfac});var p=function(){function e(){}return e.forRoot=function(t){return{ngModule:e,providers:[{provide:a,useValue:t}]}},e}();p.ɵmod=r.ɵɵdefineNgModule({type:p}),p.ɵinj=r.ɵɵdefineInjector({factory:function(e){return new(e||p)},providers:[u,{provide:t.HTTP_INTERCEPTORS,useClass:f,multi:!0}],imports:[[]]}),e.NG_HTTP_CACHING_CONFIG=a,e.NgHttpCachingConfig=s,e.NgHttpCachingConfigDefault=h,e.NgHttpCachingInterceptorService=f,e.NgHttpCachingModule=p,e.NgHttpCachingService=u,Object.defineProperty(e,"__esModule",{value:!0})}));
2
- //# sourceMappingURL=ng-http-caching.umd.min.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../projects/ng-http-caching/src/lib/ng-http-caching.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching-interceptor.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.module.ts"],"names":["NgHttpCachingStrategy","NgHttpCachingHeaders","NG_HTTP_CACHING_CONFIG","InjectionToken","NgHttpCachingConfigDefault","lifetime","allowedMethod","cacheStrategy","ALLOW_ALL","NgHttpCachingService","config","this","store","Map","queue","Object","assign","prototype","getConfig","getFromCache","req","key","getKey","cached","get","isExpired","response","clearCacheByKey","addToCache","res","entry","url","urlWithParams","request","addedTime","Date","now","isValid","set","deleteFromCache","clearCache","clear","delete","clearCacheByRegex","regex","_this","forEach","test","clearCacheByTag","tag","tagHeader","headers","TAG","split","includes","runGc","result","has","LIFETIME","Error","isCacheable","DISALLOW_CACHE","DISALLOW_ALL","ALLOW_CACHE","length","indexOf","method","getFromQueue","addToQueue","obs","deleteFromQueue","i0","ɵɵinject","factory","ɵfac","NgHttpCachingInterceptorService","cacheService","intercept","next","sendRequest","cachedObservable","cachedResponse","of","clone","shared","pipe","tap","event","HttpResponse","finalize","share","cloned","values","ngHttpCachingHeaders","handle","NgHttpCachingModule","forRoot","ngHttpCachingConfig","ngModule","providers","provide","useValue","HTTP_INTERCEPTORS","useClass","multi","imports"],"mappings":"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","sourcesContent":["import { Injectable, InjectionToken, Inject, Optional } from '@angular/core';\nimport { HttpRequest, HttpResponse, HttpEvent } from '@angular/common/http';\nimport { Observable } from 'rxjs/internal/Observable';\n\nexport interface NgHttpCachingEntry {\n url: string;\n response: HttpResponse<any>;\n request: HttpRequest<any>;\n addedTime: number;\n}\n\nexport const NG_HTTP_CACHING_CONFIG = new InjectionToken<NgHttpCachingConfig>(\n 'ng-http-caching.config'\n);\n\nexport enum NgHttpCachingStrategy {\n ALLOW_ALL = 'ALLOW_ALL',\n DISALLOW_ALL = 'DISALLOW_ALL',\n}\n\nexport enum NgHttpCachingHeaders {\n ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',\n DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',\n LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',\n TAG = 'X-NG-HTTP-CACHING-TAG',\n}\nexport class NgHttpCachingConfig {\n lifetime?: number;\n allowedMethod?: string[];\n cacheStrategy?: NgHttpCachingStrategy;\n isExpired?: (entry: NgHttpCachingEntry) => boolean | undefined;\n isCacheable?: (req: HttpRequest<any>) => boolean | undefined;\n getKey?: (req: HttpRequest<any>) => string | undefined;\n isValid?: (entry: NgHttpCachingEntry) => boolean | undefined;\n}\n\nexport const NgHttpCachingConfigDefault: NgHttpCachingConfig = {\n lifetime: 60 * 60 * 100,\n allowedMethod: ['GET'],\n cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,\n};\n\n@Injectable()\nexport class NgHttpCachingService {\n\n public readonly store = new Map<string, NgHttpCachingEntry>();\n\n public readonly queue = new Map<string, Observable<HttpEvent<any>>>();\n\n private config: NgHttpCachingConfig;\n\n constructor(\n @Inject(NG_HTTP_CACHING_CONFIG) @Optional() config: NgHttpCachingConfig\n ) {\n if (config) {\n this.config = { ...NgHttpCachingConfigDefault, ...config };\n } else {\n this.config = NgHttpCachingConfigDefault;\n }\n }\n\n /**\n * Return the config\n */\n getConfig(): NgHttpCachingConfig {\n return this.config;\n }\n\n /**\n * Return response from cache\n */\n getFromCache(req: HttpRequest<any>): HttpResponse<any> | undefined {\n const key: string = this.getKey(req);\n const cached: NgHttpCachingEntry = this.store.get(key);\n\n if (!cached) {\n return undefined;\n }\n\n if (this.isExpired(cached)) {\n this.clearCacheByKey(key);\n return undefined;\n }\n\n return cached.response;\n }\n\n /**\n * Add response to cache\n */\n addToCache(req: HttpRequest<any>, res: HttpResponse<any>): boolean {\n const key: string = this.getKey(req);\n const entry: NgHttpCachingEntry = {\n url: req.urlWithParams,\n response: res,\n request: req,\n addedTime: Date.now(),\n };\n if ( this.isValid(entry) ) {\n this.store.set(key, entry);\n return true;\n }\n return false;\n }\n\n /**\n * Delete response from cache\n */\n deleteFromCache(req: HttpRequest<any>): boolean {\n const key: string = this.getKey(req);\n return this.clearCacheByKey(key);\n }\n\n /**\n * Clear the cache\n */\n clearCache(): void {\n this.store.clear();\n }\n\n /**\n * Clear the cache by key\n */\n clearCacheByKey(key: string): boolean {\n return this.store.delete(key);\n }\n\n /**\n * Clear the cache by regex\n */\n clearCacheByRegex(regex: RegExp): void {\n this.store.forEach((entry: NgHttpCachingEntry, key: string) => {\n if ( regex.test(key) ){\n this.clearCacheByKey(key);\n }\n });\n }\n\n /**\n * Clear the cache by TAG\n */\n clearCacheByTag(tag: string): void {\n this.store.forEach((entry: NgHttpCachingEntry, key: string) => {\n const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);\n if ( tagHeader && tagHeader.split(',').includes(tag) ){\n this.clearCacheByKey(key);\n }\n });\n }\n\n /**\n * Run garbage collector (delete expired cache entry)\n */\n runGc(): void {\n this.store.forEach((entry: NgHttpCachingEntry, key: string) => {\n if ( this.isExpired(entry) ){\n this.clearCacheByKey(key);\n }\n });\n }\n\n /**\n * Return true if cache entry is expired\n */\n isExpired(entry: NgHttpCachingEntry): boolean {\n // if user provide custom method, use it\n if (typeof this.config.isExpired === 'function') {\n const result = this.config.isExpired(entry);\n // if result is undefined, normal behaviour is provided\n if (typeof result !== 'undefined') {\n return result;\n }\n }\n // config/default lifetime\n let lifetime = this.config.lifetime;\n // request has own lifetime\n if (entry.request.headers.has(NgHttpCachingHeaders.LIFETIME)) {\n lifetime = +entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);\n }\n // never expire if 0\n if (lifetime === 0) {\n return false;\n }\n // wrong lifetime\n if (lifetime < 0) {\n throw new Error('lifetime must be greater than or equal 0');\n }\n return entry.addedTime + lifetime < Date.now();\n }\n\n /**\n * Return true if cache entry is valid for store in the cache\n */\n isValid(entry: NgHttpCachingEntry): boolean {\n // if user provide custom method, use it\n if (typeof this.config.isValid === 'function') {\n const result = this.config.isValid(entry);\n // if result is undefined, normal behaviour is provided\n if (typeof result !== 'undefined') {\n return result;\n }\n }\n return true;\n }\n\n /**\n * Return true if the request is cacheable\n */\n isCacheable(req: HttpRequest<any>): boolean {\n // if user provide custom method, use it\n if (typeof this.config.isCacheable === 'function') {\n const result = this.config.isCacheable(req);\n // if result is undefined, normal behaviour is provided\n if (typeof result !== 'undefined') {\n return result;\n }\n }\n // request has disallow cache header\n if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {\n return false;\n }\n // strategy is disallow all...\n if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {\n // request isn't allowed if come without allow header\n if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {\n return false;\n }\n }\n // if allowed method is only ALL, allow all http methos\n if ( this.config.allowedMethod.length === 1) {\n if (this.config.allowedMethod[0] === 'ALL'){\n return true;\n }\n }\n // request is allowed if method is in allowedMethod\n return this.config.allowedMethod.indexOf(req.method) !== -1;\n }\n\n /**\n * Return the cache key\n */\n getKey(req: HttpRequest<any>): string {\n // if user provide custom method, use it\n if (typeof this.config.getKey === 'function') {\n const result = this.config.getKey(req);\n // if result is undefined, normal behaviour is provided\n if (typeof result !== 'undefined') {\n return result;\n }\n }\n // default key id is url with query parameters\n return req.urlWithParams;\n }\n\n /**\n * Return observable from cache\n */\n getFromQueue(req: HttpRequest<any>): Observable<HttpEvent<any>> | undefined {\n const key: string = this.getKey(req);\n const cached: Observable<HttpEvent<any>> = this.queue.get(key);\n\n if (!cached) {\n return undefined;\n }\n\n return cached;\n }\n\n /**\n * Add observable to cache\n */\n addToQueue(req: HttpRequest<any>, obs: Observable<HttpEvent<any>>): void {\n const key: string = this.getKey(req);\n this.queue.set(key, obs);\n }\n\n /**\n * Delete observable from cache\n */\n deleteFromQueue(req: HttpRequest<any>): boolean {\n const key: string = this.getKey(req);\n return this.queue.delete(key);\n }\n}\n","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { tap, finalize, share } from 'rxjs/operators';\nimport { NgHttpCachingService, NgHttpCachingHeaders } from './ng-http-caching.service';\n\n\n@Injectable()\nexport class NgHttpCachingInterceptorService implements HttpInterceptor {\n\n constructor(private readonly cacheService: NgHttpCachingService) {}\n\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n // run garbage collector\n this.cacheService.runGc();\n\n // Don't cache if it's not cacheable\n if ( !this.cacheService.isCacheable(req) ) {\n return this.sendRequest(req, next);\n }\n\n // Checked if there is pending response for this request\n const cachedObservable: Observable<HttpEvent<any>> = this.cacheService.getFromQueue(req);\n if ( cachedObservable ) {\n // console.log('cachedObservable', req);\n return cachedObservable;\n }\n\n // Checked if there is cached response for this request\n const cachedResponse: HttpResponse<any> = this.cacheService.getFromCache(req);\n if (cachedResponse) {\n // console.log('cachedResponse', req);\n return of(cachedResponse.clone());\n }\n\n // If the request of going through for first time\n // then let the request proceed and cache the response\n // console.log('sendRequest', req);\n const shared = this.sendRequest(req, next).pipe(\n tap(event => {\n if (event instanceof HttpResponse) {\n this.cacheService.addToCache(req, event.clone());\n }\n }),\n finalize(() => {\n // delete pending request\n this.cacheService.deleteFromQueue(req);\n }),\n share()\n );\n\n // add pending request to queue for cache parallell request\n this.cacheService.addToQueue(req, shared);\n\n return shared;\n }\n\n /**\n * Send http request (next handler)\n */\n sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n let cloned: HttpRequest<any> = req.clone();\n // trim custom headers before send request\n Object.values(NgHttpCachingHeaders).forEach(ngHttpCachingHeaders => {\n if ( cloned.headers.has(ngHttpCachingHeaders) ) {\n cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });\n }\n });\n return next.handle(cloned);\n }\n}\n","import { NgModule, ModuleWithProviders } from '@angular/core';\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\nimport {\n NG_HTTP_CACHING_CONFIG,\n NgHttpCachingConfig,\n NgHttpCachingService,\n} from './ng-http-caching.service';\nimport { NgHttpCachingInterceptorService } from './ng-http-caching-interceptor.service';\n\n@NgModule({\n declarations: [],\n imports: [],\n providers: [\n NgHttpCachingService,\n {\n provide: HTTP_INTERCEPTORS,\n useClass: NgHttpCachingInterceptorService,\n multi: true,\n },\n ],\n exports: [],\n})\nexport class NgHttpCachingModule {\n static forRoot(\n ngHttpCachingConfig?: NgHttpCachingConfig\n ): ModuleWithProviders<NgHttpCachingModule> {\n return {\n ngModule: NgHttpCachingModule,\n providers: [\n {\n provide: NG_HTTP_CACHING_CONFIG,\n useValue: ngHttpCachingConfig,\n },\n ],\n };\n }\n}\n"]}
@@ -1,65 +0,0 @@
1
- import { HttpResponse } from '@angular/common/http';
2
- import { Injectable } from '@angular/core';
3
- import { of } from 'rxjs';
4
- import { tap, finalize, share } from 'rxjs/operators';
5
- import { NgHttpCachingHeaders } from './ng-http-caching.service';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "./ng-http-caching.service";
8
- export class NgHttpCachingInterceptorService {
9
- constructor(cacheService) {
10
- this.cacheService = cacheService;
11
- }
12
- intercept(req, next) {
13
- // run garbage collector
14
- this.cacheService.runGc();
15
- // Don't cache if it's not cacheable
16
- if (!this.cacheService.isCacheable(req)) {
17
- return this.sendRequest(req, next);
18
- }
19
- // Checked if there is pending response for this request
20
- const cachedObservable = this.cacheService.getFromQueue(req);
21
- if (cachedObservable) {
22
- // console.log('cachedObservable', req);
23
- return cachedObservable;
24
- }
25
- // Checked if there is cached response for this request
26
- const cachedResponse = this.cacheService.getFromCache(req);
27
- if (cachedResponse) {
28
- // console.log('cachedResponse', req);
29
- return of(cachedResponse.clone());
30
- }
31
- // If the request of going through for first time
32
- // then let the request proceed and cache the response
33
- // console.log('sendRequest', req);
34
- const shared = this.sendRequest(req, next).pipe(tap(event => {
35
- if (event instanceof HttpResponse) {
36
- this.cacheService.addToCache(req, event.clone());
37
- }
38
- }), finalize(() => {
39
- // delete pending request
40
- this.cacheService.deleteFromQueue(req);
41
- }), share());
42
- // add pending request to queue for cache parallell request
43
- this.cacheService.addToQueue(req, shared);
44
- return shared;
45
- }
46
- /**
47
- * Send http request (next handler)
48
- */
49
- sendRequest(req, next) {
50
- let cloned = req.clone();
51
- // trim custom headers before send request
52
- Object.values(NgHttpCachingHeaders).forEach(ngHttpCachingHeaders => {
53
- if (cloned.headers.has(ngHttpCachingHeaders)) {
54
- cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });
55
- }
56
- });
57
- return next.handle(cloned);
58
- }
59
- }
60
- NgHttpCachingInterceptorService.ɵfac = function NgHttpCachingInterceptorService_Factory(t) { return new (t || NgHttpCachingInterceptorService)(i0.ɵɵinject(i1.NgHttpCachingService)); };
61
- NgHttpCachingInterceptorService.ɵprov = i0.ɵɵdefineInjectable({ token: NgHttpCachingInterceptorService, factory: NgHttpCachingInterceptorService.ɵfac });
62
- /*@__PURE__*/ (function () { i0.ɵsetClassMetadata(NgHttpCachingInterceptorService, [{
63
- type: Injectable
64
- }], function () { return [{ type: i1.NgHttpCachingService }]; }, null); })();
65
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLWludGVyY2VwdG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1odHRwLWNhY2hpbmcvc3JjL2xpYi9uZy1odHRwLWNhY2hpbmctaW50ZXJjZXB0b3Iuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXdELFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzFHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RCxPQUFPLEVBQXdCLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7OztBQUl2RixNQUFNLE9BQU8sK0JBQStCO0lBRTFDLFlBQTZCLFlBQWtDO1FBQWxDLGlCQUFZLEdBQVosWUFBWSxDQUFzQjtJQUFHLENBQUM7SUFFbkUsU0FBUyxDQUFDLEdBQXFCLEVBQUUsSUFBaUI7UUFDaEQsd0JBQXdCO1FBQ3hCLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFMUIsb0NBQW9DO1FBQ3BDLElBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRztZQUN6QyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQ3BDO1FBRUQsd0RBQXdEO1FBQ3hELE1BQU0sZ0JBQWdCLEdBQStCLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pGLElBQUssZ0JBQWdCLEVBQUc7WUFDdEIsd0NBQXdDO1lBQ3hDLE9BQU8sZ0JBQWdCLENBQUM7U0FDekI7UUFFRCx1REFBdUQ7UUFDdkQsTUFBTSxjQUFjLEdBQXNCLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlFLElBQUksY0FBYyxFQUFFO1lBQ2xCLHNDQUFzQztZQUN0QyxPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztTQUNuQztRQUVELGlEQUFpRDtRQUNqRCxzREFBc0Q7UUFDdEQsbUNBQW1DO1FBQ25DLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FDN0MsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ1YsSUFBSSxLQUFLLFlBQVksWUFBWSxFQUFFO2dCQUNqQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7YUFDbEQ7UUFDSCxDQUFDLENBQUMsRUFDRixRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ1oseUJBQXlCO1lBQ3pCLElBQUksQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxFQUNGLEtBQUssRUFBRSxDQUNSLENBQUM7UUFFRiwyREFBMkQ7UUFDM0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTFDLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVcsQ0FBQyxHQUFxQixFQUFFLElBQWlCO1FBQ2xELElBQUksTUFBTSxHQUFxQixHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDM0MsMENBQTBDO1FBQzFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsRUFBRTtZQUNqRSxJQUFLLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLEVBQUc7Z0JBQzlDLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ2pGO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDN0IsQ0FBQzs7OEdBN0RVLCtCQUErQjt1RUFBL0IsK0JBQStCLFdBQS9CLCtCQUErQjtrREFBL0IsK0JBQStCO2NBRDNDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwRXZlbnQsIEh0dHBIYW5kbGVyLCBIdHRwSW50ZXJjZXB0b3IsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwLCBmaW5hbGl6ZSwgc2hhcmUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBOZ0h0dHBDYWNoaW5nU2VydmljZSwgTmdIdHRwQ2FjaGluZ0hlYWRlcnMgfSBmcm9tICcuL25nLWh0dHAtY2FjaGluZy5zZXJ2aWNlJztcblxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmdIdHRwQ2FjaGluZ0ludGVyY2VwdG9yU2VydmljZSBpbXBsZW1lbnRzIEh0dHBJbnRlcmNlcHRvciB7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjYWNoZVNlcnZpY2U6IE5nSHR0cENhY2hpbmdTZXJ2aWNlKSB7fVxuXG4gIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PGFueT4sIG5leHQ6IEh0dHBIYW5kbGVyKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xuICAgIC8vIHJ1biBnYXJiYWdlIGNvbGxlY3RvclxuICAgIHRoaXMuY2FjaGVTZXJ2aWNlLnJ1bkdjKCk7XG5cbiAgICAvLyBEb24ndCBjYWNoZSBpZiBpdCdzIG5vdCBjYWNoZWFibGVcbiAgICBpZiAoICF0aGlzLmNhY2hlU2VydmljZS5pc0NhY2hlYWJsZShyZXEpICkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VuZFJlcXVlc3QocmVxLCBuZXh0KTtcbiAgICB9XG5cbiAgICAvLyBDaGVja2VkIGlmIHRoZXJlIGlzIHBlbmRpbmcgcmVzcG9uc2UgZm9yIHRoaXMgcmVxdWVzdFxuICAgIGNvbnN0IGNhY2hlZE9ic2VydmFibGU6IE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+ID0gdGhpcy5jYWNoZVNlcnZpY2UuZ2V0RnJvbVF1ZXVlKHJlcSk7XG4gICAgaWYgKCBjYWNoZWRPYnNlcnZhYmxlICkge1xuICAgICAgLy8gY29uc29sZS5sb2coJ2NhY2hlZE9ic2VydmFibGUnLCByZXEpO1xuICAgICAgcmV0dXJuIGNhY2hlZE9ic2VydmFibGU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2tlZCBpZiB0aGVyZSBpcyBjYWNoZWQgcmVzcG9uc2UgZm9yIHRoaXMgcmVxdWVzdFxuICAgIGNvbnN0IGNhY2hlZFJlc3BvbnNlOiBIdHRwUmVzcG9uc2U8YW55PiA9IHRoaXMuY2FjaGVTZXJ2aWNlLmdldEZyb21DYWNoZShyZXEpO1xuICAgIGlmIChjYWNoZWRSZXNwb25zZSkge1xuICAgICAgLy8gY29uc29sZS5sb2coJ2NhY2hlZFJlc3BvbnNlJywgcmVxKTtcbiAgICAgIHJldHVybiBvZihjYWNoZWRSZXNwb25zZS5jbG9uZSgpKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgcmVxdWVzdCBvZiBnb2luZyB0aHJvdWdoIGZvciBmaXJzdCB0aW1lXG4gICAgLy8gdGhlbiBsZXQgdGhlIHJlcXVlc3QgcHJvY2VlZCBhbmQgY2FjaGUgdGhlIHJlc3BvbnNlXG4gICAgLy8gY29uc29sZS5sb2coJ3NlbmRSZXF1ZXN0JywgcmVxKTtcbiAgICBjb25zdCBzaGFyZWQgPSB0aGlzLnNlbmRSZXF1ZXN0KHJlcSwgbmV4dCkucGlwZShcbiAgICAgIHRhcChldmVudCA9PiB7XG4gICAgICAgIGlmIChldmVudCBpbnN0YW5jZW9mIEh0dHBSZXNwb25zZSkge1xuICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlLmFkZFRvQ2FjaGUocmVxLCBldmVudC5jbG9uZSgpKTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgIC8vIGRlbGV0ZSBwZW5kaW5nIHJlcXVlc3RcbiAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2UuZGVsZXRlRnJvbVF1ZXVlKHJlcSk7XG4gICAgICB9KSxcbiAgICAgIHNoYXJlKClcbiAgICApO1xuXG4gICAgLy8gYWRkIHBlbmRpbmcgcmVxdWVzdCB0byBxdWV1ZSBmb3IgY2FjaGUgcGFyYWxsZWxsIHJlcXVlc3RcbiAgICB0aGlzLmNhY2hlU2VydmljZS5hZGRUb1F1ZXVlKHJlcSwgc2hhcmVkKTtcblxuICAgIHJldHVybiBzaGFyZWQ7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBodHRwIHJlcXVlc3QgKG5leHQgaGFuZGxlcilcbiAgICovXG4gIHNlbmRSZXF1ZXN0KHJlcTogSHR0cFJlcXVlc3Q8YW55PiwgbmV4dDogSHR0cEhhbmRsZXIpOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+PiB7XG4gICAgbGV0IGNsb25lZDogSHR0cFJlcXVlc3Q8YW55PiA9IHJlcS5jbG9uZSgpO1xuICAgIC8vIHRyaW0gY3VzdG9tIGhlYWRlcnMgYmVmb3JlIHNlbmQgcmVxdWVzdFxuICAgIE9iamVjdC52YWx1ZXMoTmdIdHRwQ2FjaGluZ0hlYWRlcnMpLmZvckVhY2gobmdIdHRwQ2FjaGluZ0hlYWRlcnMgPT4ge1xuICAgICAgaWYgKCBjbG9uZWQuaGVhZGVycy5oYXMobmdIdHRwQ2FjaGluZ0hlYWRlcnMpICkge1xuICAgICAgICBjbG9uZWQgPSBjbG9uZWQuY2xvbmUoeyBoZWFkZXJzOiBjbG9uZWQuaGVhZGVycy5kZWxldGUobmdIdHRwQ2FjaGluZ0hlYWRlcnMpIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBuZXh0LmhhbmRsZShjbG9uZWQpO1xuICB9XG59XG4iXX0=
@@ -1,44 +0,0 @@
1
- import { NgModule } from '@angular/core';
2
- import { HTTP_INTERCEPTORS } from '@angular/common/http';
3
- import { NG_HTTP_CACHING_CONFIG, NgHttpCachingService, } from './ng-http-caching.service';
4
- import { NgHttpCachingInterceptorService } from './ng-http-caching-interceptor.service';
5
- import * as i0 from "@angular/core";
6
- export class NgHttpCachingModule {
7
- static forRoot(ngHttpCachingConfig) {
8
- return {
9
- ngModule: NgHttpCachingModule,
10
- providers: [
11
- {
12
- provide: NG_HTTP_CACHING_CONFIG,
13
- useValue: ngHttpCachingConfig,
14
- },
15
- ],
16
- };
17
- }
18
- }
19
- NgHttpCachingModule.ɵmod = i0.ɵɵdefineNgModule({ type: NgHttpCachingModule });
20
- NgHttpCachingModule.ɵinj = i0.ɵɵdefineInjector({ factory: function NgHttpCachingModule_Factory(t) { return new (t || NgHttpCachingModule)(); }, providers: [
21
- NgHttpCachingService,
22
- {
23
- provide: HTTP_INTERCEPTORS,
24
- useClass: NgHttpCachingInterceptorService,
25
- multi: true,
26
- },
27
- ], imports: [[]] });
28
- /*@__PURE__*/ (function () { i0.ɵsetClassMetadata(NgHttpCachingModule, [{
29
- type: NgModule,
30
- args: [{
31
- declarations: [],
32
- imports: [],
33
- providers: [
34
- NgHttpCachingService,
35
- {
36
- provide: HTTP_INTERCEPTORS,
37
- useClass: NgHttpCachingInterceptorService,
38
- multi: true,
39
- },
40
- ],
41
- exports: [],
42
- }]
43
- }], null, null); })();
44
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWh0dHAtY2FjaGluZy9zcmMvbGliL25nLWh0dHAtY2FjaGluZy5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBdUIsTUFBTSxlQUFlLENBQUM7QUFDOUQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUNMLHNCQUFzQixFQUV0QixvQkFBb0IsR0FDckIsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQzs7QUFleEYsTUFBTSxPQUFPLG1CQUFtQjtJQUM5QixNQUFNLENBQUMsT0FBTyxDQUNaLG1CQUF5QztRQUV6QyxPQUFPO1lBQ0wsUUFBUSxFQUFFLG1CQUFtQjtZQUM3QixTQUFTLEVBQUU7Z0JBQ1Q7b0JBQ0UsT0FBTyxFQUFFLHNCQUFzQjtvQkFDL0IsUUFBUSxFQUFFLG1CQUFtQjtpQkFDOUI7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDOzt1REFiVSxtQkFBbUI7cUhBQW5CLG1CQUFtQixtQkFWbkI7UUFDVCxvQkFBb0I7UUFDcEI7WUFDRSxPQUFPLEVBQUUsaUJBQWlCO1lBQzFCLFFBQVEsRUFBRSwrQkFBK0I7WUFDekMsS0FBSyxFQUFFLElBQUk7U0FDWjtLQUNGLFlBUlEsRUFBRTtrREFXQSxtQkFBbUI7Y0FiL0IsUUFBUTtlQUFDO2dCQUNSLFlBQVksRUFBRSxFQUFFO2dCQUNoQixPQUFPLEVBQUUsRUFBRTtnQkFDWCxTQUFTLEVBQUU7b0JBQ1Qsb0JBQW9CO29CQUNwQjt3QkFDRSxPQUFPLEVBQUUsaUJBQWlCO3dCQUMxQixRQUFRLEVBQUUsK0JBQStCO3dCQUN6QyxLQUFLLEVBQUUsSUFBSTtxQkFDWjtpQkFDRjtnQkFDRCxPQUFPLEVBQUUsRUFBRTthQUNaIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUsIE1vZHVsZVdpdGhQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEhUVFBfSU5URVJDRVBUT1JTIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHtcbiAgTkdfSFRUUF9DQUNISU5HX0NPTkZJRyxcbiAgTmdIdHRwQ2FjaGluZ0NvbmZpZyxcbiAgTmdIdHRwQ2FjaGluZ1NlcnZpY2UsXG59IGZyb20gJy4vbmctaHR0cC1jYWNoaW5nLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmdIdHRwQ2FjaGluZ0ludGVyY2VwdG9yU2VydmljZSB9IGZyb20gJy4vbmctaHR0cC1jYWNoaW5nLWludGVyY2VwdG9yLnNlcnZpY2UnO1xuXG5ATmdNb2R1bGUoe1xuICBkZWNsYXJhdGlvbnM6IFtdLFxuICBpbXBvcnRzOiBbXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAgTmdIdHRwQ2FjaGluZ1NlcnZpY2UsXG4gICAge1xuICAgICAgcHJvdmlkZTogSFRUUF9JTlRFUkNFUFRPUlMsXG4gICAgICB1c2VDbGFzczogTmdIdHRwQ2FjaGluZ0ludGVyY2VwdG9yU2VydmljZSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gIF0sXG4gIGV4cG9ydHM6IFtdLFxufSlcbmV4cG9ydCBjbGFzcyBOZ0h0dHBDYWNoaW5nTW9kdWxlIHtcbiAgc3RhdGljIGZvclJvb3QoXG4gICAgbmdIdHRwQ2FjaGluZ0NvbmZpZz86IE5nSHR0cENhY2hpbmdDb25maWdcbiAgKTogTW9kdWxlV2l0aFByb3ZpZGVyczxOZ0h0dHBDYWNoaW5nTW9kdWxlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5nTW9kdWxlOiBOZ0h0dHBDYWNoaW5nTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBwcm92aWRlOiBOR19IVFRQX0NBQ0hJTkdfQ09ORklHLFxuICAgICAgICAgIHVzZVZhbHVlOiBuZ0h0dHBDYWNoaW5nQ29uZmlnLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9XG59XG4iXX0=