@esfaenza/httpservice 15.2.19 → 15.2.20

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.
@@ -1,1014 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Optional, Inject, NgModule } from '@angular/core';
3
- import { __awaiter } from 'tslib';
4
- import * as i3 from '@angular/common/http';
5
- import { HttpEventType, HttpHeaders, HttpErrorResponse, HttpParams } from '@angular/common/http';
6
- import { first, concatMap, delay, finalize, map, catchError, scan } from 'rxjs/operators';
7
- import { Subject, forkJoin, from, of, throwError, Observable } from 'rxjs';
8
- import * as i2 from '@esfaenza/localizations';
9
- import * as i4 from '@esfaenza/preferences';
10
- import * as i5 from '@esfaenza/extensions';
11
- import { Title } from '@angular/platform-browser';
12
-
13
- /**
14
- * Dizionario di invalidazioni delle chiamate HTTP
15
- */
16
- const HTTP_INVALIDATION = new InjectionToken('HTTP_INVALIDATION');
17
- /**
18
- * Durata della cache lato libreria dopo il quale la cache verrà ripulita
19
- */
20
- const CLIENT_CACHE_DURATION_S = new InjectionToken('CLIENT_CACHE_DURATION_S');
21
- /**
22
- * Nome dell'APP utilizzato per creare le chiavi delle cache specifiche per l'applicazione corrente
23
- */
24
- const APP_NAME = new InjectionToken('APP_NAME');
25
- /**
26
- * Indica se utilizzare l'identificativo utente nella cache
27
- */
28
- const CACHE_BY_USER = new InjectionToken('CACHE_BY_USER');
29
- /**
30
- * Indica se fare log nella console ad ogni azione significativa
31
- */
32
- const HTTP_DEBUG_MODE = new InjectionToken('DEBUG_MODE');
33
-
34
- /**
35
- * Classe d'estensione che permette di modificare il comportamento della libreria negli hook definiti da interfaccia, in modo da poterla adattare
36
- * con un certo grado di customizzazione a qualsiasi struttura di frontend
37
- */
38
- class HttpServiceExtensions {
39
- /**
40
- * Hook per recuperare l'access token con cui effettuare le chiamate HTTP
41
- */
42
- retrieveAccessToken() {
43
- return "";
44
- }
45
- /**
46
- * Hook per recuperare l'Identity corrente in un oggetto generico con le informazioni di User e Tenant
47
- */
48
- retrieveIdentity() {
49
- return null;
50
- }
51
- /**
52
- * Hook per leggere dallo stato dell'applicazione se stiamo già venendo ridirezionati al login, in modo da non tentare di effettuare
53
- * N redirect contemporaneamente qualora molte API fallissero allo stesso tempo nell'autenticazione
54
- */
55
- readRedirectingToLogin() {
56
- return false;
57
- }
58
- /**
59
- * Hook per scrivere nello stato dell'applicazione se stiamo effettuando un redirect al login o meno
60
- */
61
- writeRedirectingToLogin(status) {
62
- }
63
- /**
64
- * Hook per effettuare il redirect al login
65
- */
66
- redirectToLogin() {
67
- }
68
- /**
69
- * Hook per leggere dallo stato dell'applicazione se stiamo già gestendo un errore, in modo da non tentare di gestire
70
- * N errori contemporaneamente qualora molte API fallissero allo stesso tempo
71
- */
72
- readHandlingErrorStatus() {
73
- return false;
74
- }
75
- /**
76
- * Hook per scrivere nello stato dell'applicazione se stiamo gestendo un errore o meno
77
- */
78
- writeHandlingErrorStatus(status) {
79
- }
80
- /**
81
- * Hook per leggere dallo stato dell'applicazione se stiamo già gestendo un redirect, in modo da non tentare di gestire
82
- * N redirect contemporaneamente qualora molte API lo richiedessero allo stesso tempo
83
- */
84
- readRedirectionStatus() {
85
- return false;
86
- }
87
- /**
88
- * Hook per scrivere nello stato dell'applicazione se stiamo gestendo un redirect o meno
89
- */
90
- writeRedirectionStatus(status) {
91
- }
92
- /**
93
- * Hook per indicare se l'applicazione può gestire eccezioni del tipo "NotConfigured" (444). Qualora l'applicazione che lo implementa dichiari di gestirle verrà chiamata
94
- * la funzione **handleBlockingException** per ognuno di questi errori
95
- */
96
- handleNotConfiguredException() {
97
- return false;
98
- }
99
- /**
100
- * Hook per la gestione di un qualsiasi errore bloccante per l'operazione attuale, ma non fatale (Generalmente gestibile da dialog di avviso)
101
- */
102
- handleBlockingException(status, text) {
103
- console.error("ESHttpError Blocking Exception " + status + " " + text);
104
- }
105
- /**
106
- * Hook per la gestione di un qualsiasi errore fatale (Generalmente gestibile tramite navigazione a una pagina di errore custom per l'applicativo)
107
- */
108
- handleException(status, text) {
109
- console.error("ESHttpError " + status + " " + text);
110
- }
111
- }
112
- HttpServiceExtensions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HttpServiceExtensions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
113
- HttpServiceExtensions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HttpServiceExtensions, providedIn: 'root' });
114
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HttpServiceExtensions, decorators: [{
115
- type: Injectable,
116
- args: [{ providedIn: 'root' }]
117
- }] });
118
-
119
- class CacheInfos {
120
- constructor(finalUrl, cache, cacheKey, cacheTime, cacheItem) {
121
- this.finalUrl = finalUrl;
122
- this.cache = cache;
123
- this.cacheKey = cacheKey;
124
- this.cacheTime = cacheTime;
125
- this.cacheItem = cacheItem;
126
- }
127
- }
128
-
129
- /**
130
- * Servizio utilizzato per effettuare qualsiasi tipo di chiamata HTTP dall'applicazione, gestisce errori e cache delle risposte nativamente e ne può essere
131
- * esteso/modificato il comportamento implementando la classe di "hook" **IHttpServiceExtensions** e registrandola nel provider della classe **HttpServiceExtensions**
132
- */
133
- class HTTPService {
134
- /**
135
- * @ignore
136
- */
137
- constructor(EXTENSION_CLASS, HTTP_INVALIDATION, APP_NAME, CLIENT_CACHE_DURATION_S, CACHE_BY_USER, HTTP_DEBUG_MODE, bc, http, localStorage, hash, utisExts) {
138
- this.EXTENSION_CLASS = EXTENSION_CLASS;
139
- this.HTTP_INVALIDATION = HTTP_INVALIDATION;
140
- this.APP_NAME = APP_NAME;
141
- this.CLIENT_CACHE_DURATION_S = CLIENT_CACHE_DURATION_S;
142
- this.CACHE_BY_USER = CACHE_BY_USER;
143
- this.HTTP_DEBUG_MODE = HTTP_DEBUG_MODE;
144
- this.bc = bc;
145
- this.http = http;
146
- this.localStorage = localStorage;
147
- this.hash = hash;
148
- this.utisExts = utisExts;
149
- /** Cache dello stato delle chiamate HTTP attualmente effettuate. Ogni chiamata è rappresentata da un GUID e lo status assume valore **false** solo sugli errori */
150
- this.callStatus = {};
151
- /** Nome della cache in cui vengono storicizzate le informazioni sulle risposte delle chiamate sotto forma di dictionary */
152
- this.localStorageHttpCacheKey = null;
153
- /** Nome della cache in cui vengono storicizzate le informazioni sulle risposte delle chiamate sotto forma di dictionary, solo per le chiamate con un tempo definito di caching */
154
- this.localStorageHttpTimedCacheKey = null;
155
- /** Nome della cache in cui vengono storicizzate le informazioni sullo scadere della cache stessa */
156
- this.localStorageHttpCacheExpireKey = null;
157
- /** Identità collegata al token di autenticazione da usare, richiesta al programma che utilizza la libreria attraverso l'hook **retrieveIdentity** della **HttpServiceExtensions** */
158
- this.me = null;
159
- /** Indica che la cache a tempo dev'essere persistita il prima possibile */
160
- this.PersistTimedCacheASAP = false;
161
- /** Indica che la cache senza limiti di tempo dev'essere persistita il prima possibile */
162
- this.PersistUntimedCacheASAP = false;
163
- /** Subject emesso quando il servizio http si stabilizza, cioè quando non c'è nessuna chiamata pending o in corso da qualche istante */
164
- this.Stabilized = new Subject();
165
- /** Lista delle ultime 3 chiamate completate con successo in ordine di completamento (in posizione 0 c'è l'ultima completata eccetera...) */
166
- this.LastThreeCompletedCalls = [];
167
- /*****************************************************************************************************************************************
168
- ***************************************************** TRANSACTION HELPERS ***************************************************************
169
- *****************************************************************************************************************************************/
170
- this.GET_Trans_BeginTrans = "/api/Trans/BeginTrans";
171
- this.GET_Trans_CheckExecution = "/api/Trans/CheckExecution";
172
- this.GET_Trans_EndTrans = "/api/Trans/EndTrans";
173
- this.ExtensionsImpl = this.EXTENSION_CLASS || new HttpServiceExtensions();
174
- this.localStorageHttpCacheKey = (this.APP_NAME).replace(/\s/g, '_') + "_HttpCache";
175
- this.localStorageHttpTimedCacheKey = (this.APP_NAME).replace(/\s/g, '_') + "_HttpTimedCache";
176
- this.localStorageHttpCacheExpireKey = this.localStorageHttpCacheKey + "_Expire";
177
- this.adjustOldStorageSystem();
178
- }
179
- /**
180
- * Se vedo che ci sono elementi salvati nel localStorage provo a toglierli e a risalvarli via preference.
181
- * Nel caso migliore li sposto dal localStorage al DB di preference, nel caso peggiore li tolgo e li risalvo nel localStorage
182
- */
183
- adjustOldStorageSystem() {
184
- return __awaiter(this, void 0, void 0, function* () {
185
- var lsTimed = localStorage.getItem(this.localStorageHttpTimedCacheKey);
186
- var lsUntimed = localStorage.getItem(this.localStorageHttpCacheKey);
187
- if (!lsTimed && !lsUntimed)
188
- return;
189
- localStorage.removeItem(this.localStorageHttpTimedCacheKey);
190
- localStorage.removeItem(this.localStorageHttpCacheKey);
191
- lsTimed = lsTimed ? JSON.parse(lsTimed) : {};
192
- lsUntimed = lsUntimed ? JSON.parse(lsUntimed) : {};
193
- yield forkJoin([
194
- this.localStorage.setItem(this.localStorageHttpTimedCacheKey, lsTimed),
195
- this.localStorage.setItem(this.localStorageHttpCacheKey, lsUntimed)
196
- ]).toPromise();
197
- this.log(this.loc("Converted old storage system to new one"));
198
- });
199
- }
200
- /**
201
- * Esecuzione di una GET HTTP con eventualmente la gestione della cache qualora la chiamata termini con la convenzione "#cache"
202
- *
203
- * @param {string} url URL su cui effettuare la chiamata
204
- * @param {HttpParams} params Parametri della chiamata
205
- * @param {string} transaction Codice transazione collegato a questa chiamata. Viene inserito nell'Header "X-TX-ID" e lato Backend dovrà essere gestito di conseguenza
206
- * @param {boolean} succesfulResultMandatory Indica che questa chiamata deve assolutamente andare bene. In caso contrario viene fisicamente fatto il throw che può essere
207
- * raccolto da chi usa la libreria nella pipe "onError" dell'Observable restituito ed essere gestito in maniera non standard
208
- * @param {Function} errorCallback Callback chiamato in caso di errore
209
- *
210
- * @returns {Observable<T>} Observable che contiene il risultato della chiamata
211
- */
212
- get(url, params = null, transaction = "", succesfulResultMandatory = true, errorCallback = null) {
213
- return forkJoin({
214
- myGuid: from([this.defaultStartCall(url)]),
215
- locale: this.bc.Locale.pipe(first())
216
- }).pipe(concatMap((ret) => {
217
- let cachedInfos = this.tryGetCacheInformations(url, params);
218
- if (cachedInfos.cache && cachedInfos.cacheItem) {
219
- this.log(this.loc("Result for") + " " + url + " " + this.loc("retrieved from cache"));
220
- return of(cachedInfos.cacheItem).pipe(delay(0), finalize(() => { this.tryFinalizeByGuid(ret.myGuid); }));
221
- }
222
- var httpCall = this.http.get(cachedInfos.finalUrl, { headers: this.getHeaders(ret.locale, transaction), params: params });
223
- return httpCall.pipe(map((res) => {
224
- let responseItem = res;
225
- if (cachedInfos.cache) {
226
- this.cacheResponse(this.utisExts.deepClone(responseItem), cachedInfos);
227
- this.log(this.loc("Cached result for") + " " + url);
228
- }
229
- return responseItem;
230
- }), catchError((err, caught) => {
231
- if (errorCallback)
232
- errorCallback();
233
- return !succesfulResultMandatory ? throwError(err) : this.registerErrorAndReturnEmptyObservable(err, ret.myGuid);
234
- }), finalize(() => { this.tryFinalizeByGuid(ret.myGuid, cachedInfos); }));
235
- }));
236
- }
237
- /**
238
- * Esecuzione di una GET HTTP con eventualmente la gestione della cache qualora la chiamata termini con la convenzione "#cache"
239
- *
240
- * Caso specifico di chiamata che deve restituire un Blob o un ArrayBuffer nativo da elaborare
241
- *
242
- * @param {string} url URL su cui effettuare la chiamata
243
- * @param {HttpParams} params Parametri della chiamata
244
- * @param {"arraybuffer"| "blob"} type Tipo di ritorno richiesto
245
- * @param {string} transaction Codice transazione collegato a questa chiamata. Viene inserito nell'Header "X-TX-ID" e lato Backend dovrà essere gestito di conseguenza
246
- * @param {boolean} succesfulResultMandatory Indica che questa chiamata deve assolutamente andare bene. In caso contrario viene fisicamente fatto il throw che può essere
247
- * raccolto da chi usa la libreria nella pipe "onError" dell'Observable restituito ed essere gestito in maniera non standard
248
- * @param {Function} errorCallback Callback chiamato in caso di errore
249
- *
250
- * @returns {Observable<Blob | ArrayBuffer>} Observable che contiene il risultato della chiamata
251
- */
252
- getRaw(url, params = null, type = "arraybuffer", transaction = "", succesfulResultMandatory = true, errorCallback = null) {
253
- return forkJoin({
254
- myGuid: from([this.defaultStartCall(url)]),
255
- locale: this.bc.Locale.pipe(first())
256
- }).pipe(concatMap((ret) => {
257
- let cachedInfos = this.tryGetCacheInformations(url, params);
258
- if (cachedInfos.cache && cachedInfos.cacheItem) {
259
- this.log(this.loc("Result for") + " " + url + " " + this.loc("retrieved from cache"));
260
- return of(cachedInfos.cacheItem).pipe(delay(0), finalize(() => { this.tryFinalizeByGuid(ret.myGuid); }));
261
- }
262
- var httpCall = this.http.get(cachedInfos.finalUrl, { responseType: type, headers: this.getHeaders(ret.locale, transaction), params: params });
263
- return httpCall.pipe(map((blob) => {
264
- if (cachedInfos.cache) {
265
- this.cacheResponse(blob, cachedInfos);
266
- this.log(this.loc("Cached result for") + " " + url);
267
- }
268
- return blob;
269
- }), catchError((err, caught) => {
270
- if (errorCallback)
271
- errorCallback();
272
- return !succesfulResultMandatory ? throwError(err) : this.registerErrorAndReturnEmptyObservable(err, ret.myGuid);
273
- }), finalize(() => { this.tryFinalizeByGuid(ret.myGuid, cachedInfos); }));
274
- }));
275
- }
276
- /**
277
- * Esecuzione di una POST HTTP
278
- *
279
- * @param {string} url URL su cui effettuare la chiamata
280
- * @param {any} bodyData DTO per la chiamata
281
- * @param {HttpParams} params Parametri della chiamata
282
- * @param {string} transaction Codice transazione collegato a questa chiamata. Viene inserito nell'Header "X-TX-ID" e lato Backend dovrà essere gestito di conseguenza
283
- * @param {boolean} succesfulResultMandatory Indica che questa chiamata deve assolutamente andare bene. In caso contrario viene fisicamente fatto il throw che può essere
284
- * raccolto da chi usa la libreria nella pipe "onError" dell'Observable restituito ed essere gestito in maniera non standard
285
- *
286
- * @returns {Observable<T>} Observable che contiene il risultato della chiamata
287
- */
288
- post(url, bodyData, params = null, transaction = "", succesfulResultMandatory = true) {
289
- return forkJoin({
290
- myGuid: from([this.defaultStartCall(url)]),
291
- locale: this.bc.Locale.pipe(first())
292
- }).pipe(concatMap((ret) => {
293
- // Se è una ricerca, shallow copy e rimuovo gli "items" per evitare di farli andare su e giù al backend
294
- if (!!(bodyData === null || bodyData === void 0 ? void 0 : bodyData.items) && !!(bodyData === null || bodyData === void 0 ? void 0 : bodyData.page)) {
295
- bodyData = Object.assign({}, bodyData);
296
- delete bodyData.items;
297
- }
298
- var httpCall = this.http.post(url, bodyData, { headers: this.getHeaders(ret.locale, transaction), params: params });
299
- return httpCall.pipe(catchError((err, _) => {
300
- return !succesfulResultMandatory ? throwError(err) : this.registerErrorAndReturnEmptyObservable(err, ret.myGuid);
301
- }), finalize(() => { this.tryFinalizeByGuid(ret.myGuid); }));
302
- }));
303
- }
304
- /**
305
- * Esecuzione di una DELETE HTTP
306
- *
307
- * @param {string} url URL su cui effettuare la chiamata
308
- * @param {HttpParams} params Parametri della chiamata
309
- * @param {string} transaction Codice transazione collegato a questa chiamata. Viene inserito nell'Header "X-TX-ID" e lato Backend dovrà essere gestito di conseguenza
310
- * @param {boolean} succesfulResultMandatory Indica che questa chiamata deve assolutamente andare bene. In caso contrario viene fisicamente fatto il throw che può essere
311
- * raccolto da chi usa la libreria nella pipe "onError" dell'Observable restituito ed essere gestito in maniera non standard
312
- *
313
- * @returns {Observable<T>} Observable che contiene il risultato della chiamata
314
- */
315
- delete(url, params = null, transaction = "", succesfulResultMandatory = true) {
316
- return forkJoin({
317
- myGuid: from([this.defaultStartCall(url)]),
318
- locale: this.bc.Locale.pipe(first())
319
- }).pipe(concatMap((ret) => {
320
- var httpCall = this.http.delete(url, { headers: this.getHeaders(ret.locale, transaction), params: params });
321
- return httpCall.pipe(catchError((err, caught) => {
322
- return !succesfulResultMandatory ? throwError(err) : this.registerErrorAndReturnEmptyObservable(err, ret.myGuid);
323
- }), finalize(() => { this.tryFinalizeByGuid(ret.myGuid); }));
324
- }));
325
- }
326
- /**
327
- * Esecuzione di una PUT HTTP
328
- *
329
- * @param {string} url URL su cui effettuare la chiamata
330
- * @param {any} bodyData DTO per la chiamata
331
- * @param {HttpParams} params Parametri della chiamata
332
- * @param {string} transaction Codice transazione collegato a questa chiamata. Viene inserito nell'Header "X-TX-ID" e lato Backend dovrà essere gestito di conseguenza
333
- * @param {boolean} succesfulResultMandatory Indica che questa chiamata deve assolutamente andare bene. In caso contrario viene fisicamente fatto il throw che può essere
334
- * raccolto da chi usa la libreria nella pipe "onError" dell'Observable restituito ed essere gestito in maniera non standard
335
- *
336
- * @returns {Observable<T>} Observable che contiene il risultato della chiamata
337
- */
338
- put(url, bodyData, params = null, transaction = "", succesfulResultMandatory = true) {
339
- return forkJoin({
340
- myGuid: from([this.defaultStartCall(url)]),
341
- locale: this.bc.Locale.pipe(first())
342
- }).pipe(concatMap((ret) => {
343
- var httpCall = this.http.put(url, bodyData, { headers: this.getHeaders(ret.locale, transaction), params: params });
344
- return httpCall.pipe(catchError((err, caught) => {
345
- return !succesfulResultMandatory ? throwError(err) : this.registerErrorAndReturnEmptyObservable(err, ret.myGuid);
346
- }), finalize(() => { this.tryFinalizeByGuid(ret.myGuid); }));
347
- }));
348
- }
349
- /**
350
- * Esecuzione di una POST HTTP
351
- *
352
- * Casistica particolare in cui bisogna anche inviare dei File
353
- *
354
- * @param {string} url URL su cui effettuare la chiamata
355
- * @param {any} bodyData DTO per la chiamata
356
- * @param {File[] | File} fileArrayOrFile Singolo file o lista di file da inviare. Il tipo **File** è quello nativo del Javascript
357
- *
358
- * @returns {Observable<T>} Observable che contiene il risultato della chiamata
359
- */
360
- postwithFiles(url, bodyData, fileArrayOrFile, params = null, succesfulResultMandatory = true, onError) {
361
- return forkJoin({
362
- myGuid: from([this.defaultStartCall(url)]),
363
- locale: this.bc.Locale.pipe(first())
364
- }).pipe(concatMap((ret) => {
365
- var formData = this.getFilesFormData(fileArrayOrFile);
366
- formData.append("body", JSON.stringify(bodyData));
367
- var httpCall = this.http.post(url, formData, { params: params, headers: this.getHeaders(ret.locale, null, true, null, null) });
368
- return httpCall.pipe(catchError((err, caught) => {
369
- onError === null || onError === void 0 ? void 0 : onError();
370
- return !succesfulResultMandatory ? throwError(err) : this.registerErrorAndReturnEmptyObservable(err, ret.myGuid);
371
- }), finalize(() => { this.tryFinalizeByGuid(ret.myGuid); }));
372
- }));
373
- }
374
- /**
375
- * Esecuzione di una POST HTTP
376
- *
377
- * Casistica particolare in cui viene restituito un file gestito come ObjectURL il cui URL si può gestire dal parametro di callback **getFileCallback**.
378
- * La chiamata non ha un tipo restituito in quanto il risultato dev'essere gestito attraverso la callback **getFileCallback**
379
- *
380
- * @param {string} url URL su cui effettuare la chiamata
381
- * @param {K} bodyData DTO per la chiamata
382
- * @param {string} filename Nome del file che si sta richiedendo, rimane lato Frontend e serve per assegnare arbitrariamente un nome al file restituito, se vuoto viene utilizzata la Content-Disposition della risposta
383
- * @param {Function} getFileCallback Callback a due parametri (url: string, filename: string) per gestire il risultato del file richiesto. **Utilizzare UtilityService.fileDownload** di @esfaenza/extensions
384
- * @param {Function} afterGetFile Callback da chiamare dopo aver gestito la risposta del **getFileCallback**, in caso **handleError** fosse **false** verrà richiamato anche in caso di errore
385
- * @param {boolean} handleError Indica se di default gli errori devono essere gestiti dalla libreria o se devono essere ignorati
386
- */
387
- postGetFile(url, bodyData, filename, getFileCallback, afterGetFile = null, handleError = true, pars) {
388
- return __awaiter(this, void 0, void 0, function* () {
389
- let myGuid = this.defaultStartCall(url);
390
- let locale = yield this.bc.Locale.pipe(first()).toPromise();
391
- this.http.post(url, bodyData, { params: pars, headers: this.getHeaders(locale), observe: 'response', responseType: "blob" }).pipe(catchError((err, caught) => {
392
- if (afterGetFile && !handleError)
393
- afterGetFile();
394
- return this.registerErrorAndReturnEmptyObservable(err, myGuid, handleError);
395
- }), finalize(() => { this.tryFinalizeByGuid(myGuid); })).subscribe((response) => {
396
- var _a, _b, _c, _d;
397
- let retUrl = window.URL.createObjectURL(response.body);
398
- let fn = (_d = (_c = (_b = (_a = response.headers.get('content-disposition')) === null || _a === void 0 ? void 0 : _a.split(';')[1]) === null || _b === void 0 ? void 0 : _b.split('filename')[1]) === null || _c === void 0 ? void 0 : _c.split('=')[1]) === null || _d === void 0 ? void 0 : _d.trim().replace(/\"/g, '');
399
- getFileCallback(retUrl, filename || fn);
400
- if (afterGetFile)
401
- afterGetFile();
402
- });
403
- });
404
- }
405
- /**
406
- * Esecuzione di una GET HTTP
407
- *
408
- * Casistica particolare in cui viene restituito un file gestito come ObjectURL il cui URL si può gestire dal parametro di callback **getFileCallback**.
409
- * La chiamata non ha un tipo restituito in quanto il risultato dev'essere gestito attraverso la callback **getFileCallback**
410
- *
411
- * @param {string} url URL su cui effettuare la chiamata
412
- * @param {HttpParams} params Parametri della chiamata
413
- * @param {string} filename Nome del file che si sta richiedendo, rimane lato Frontend e serve per assegnare arbitrariamente un nome al file restituito, se vuoto viene utilizzata la Content-Disposition della risposta
414
- * @param {Function} getFileCallback Callback a due parametri (url: string, filename: string) per gestire il risultato del file richiesto. **Utilizzare UtilityService.fileDownload** di @esfaenza/extensions
415
- * @param {Function} afterGetFile Callback da chiamare dopo aver gestito la risposta del **getFileCallback**, in caso **handleError** fosse **false** verrà richiamato anche in caso di errore
416
- * @param {boolean} handleError Indica se di default gli errori devono essere gestiti dalla libreria o se devono essere ignorati
417
- */
418
- getFile(url, params = null, filename, getFileCallback, afterGetFile = null, handleError = true) {
419
- return __awaiter(this, void 0, void 0, function* () {
420
- let myGuid = this.defaultStartCall(url);
421
- let locale = yield this.bc.Locale.pipe(first()).toPromise();
422
- this.http.get(url, { params: params, headers: this.getHeaders(locale), observe: 'response', responseType: "blob" }).pipe(catchError((err, caught) => {
423
- if (afterGetFile && !handleError)
424
- afterGetFile();
425
- return this.registerErrorAndReturnEmptyObservable(err, myGuid, handleError);
426
- }), finalize(() => { this.tryFinalizeByGuid(myGuid); })).subscribe((response) => {
427
- var _a, _b, _c, _d;
428
- let retUrl = window.URL.createObjectURL(response.body);
429
- let fn = (_d = (_c = (_b = (_a = response.headers.get('content-disposition')) === null || _a === void 0 ? void 0 : _a.split(';')[1]) === null || _b === void 0 ? void 0 : _b.split('filename')[1]) === null || _c === void 0 ? void 0 : _c.split('=')[1]) === null || _d === void 0 ? void 0 : _d.trim().replace(/\"/g, '');
430
- getFileCallback(retUrl, filename || fn);
431
- if (afterGetFile)
432
- afterGetFile();
433
- });
434
- });
435
- }
436
- /**
437
- * Download nativo di un file. Internamente utilizza il pattern **window.location.href = "..."**
438
- *
439
- * @param {string} url URL su cui effettuare la chiamata
440
- * @param {HttpParams} params Parametri della chiamata
441
- */
442
- getFileNative(url, params = null) {
443
- // Encodo tutti i parametri per evitare casi particolari
444
- // var encodedParams = new HttpParams();
445
- // let parKeys = params.keys();
446
- // for (let i = 0; i < parKeys.length; i++)
447
- // encodedParams = encodedParams.set(parKeys[i], encodeURIComponent(params.get(parKeys[i])));
448
- let finalUrl = url + (params ? "?" + params.toString().replace(/\+/g, '%2b') : "");
449
- window.location.href = finalUrl;
450
- }
451
- /**
452
- * Esecuzione di una GET di un file che emette i vari eventi di progresso di download.
453
- * Utilizzarla per overridare la dialog nativa di progress del browser e sostituirla con qualcosa tipo quello che fa MEGA.
454
- *
455
- * In caso si voglia ottenere il risultato nativo del browser del download utilizzare **getFileNative(url, pars)**
456
- *
457
- * @param {string} url URL su cui effettuare la chiamata
458
- * @param {HttpParams} params Parametri della chiamata
459
- * @param {Function} getFileCallback Callback a due parametri (url: string, filename: string) per gestire il risultato del file richiesto. **Utilizzare UtilityService.fileDownload** di @esfaenza/extensions
460
- *
461
- * @returns {Observable<Download>} Observable dei vari step di progresso del download
462
- */
463
- getFileWithProgress(url, params = null, getFileCallback) {
464
- return forkJoin({
465
- myGuid: from([this.defaultStartCall(url)]),
466
- locale: this.bc.Locale.pipe(first())
467
- }).pipe(concatMap((ret) => {
468
- return this.http.get(url, { responseType: 'blob', headers: this.getHeaders(ret.locale), params: params, observe: 'events', reportProgress: true })
469
- .pipe(scan((previous, event) => {
470
- if (this.isHttpProgressEvent(event)) {
471
- let progress = event.total ? (event.loaded > event.total ? 100 : Math.round((100 * event.loaded) / event.total)) : previous.progress;
472
- return { progress: progress, state: 'IN_PROGRESS', content: null };
473
- }
474
- if (this.isHttpResponse(event)) {
475
- if (event.body) {
476
- let cdisp = event.headers.get('content-disposition');
477
- let cdispFilename = cdisp.split(';')[1].split('filename')[1].split('=')[1].trim().replace(/\"/g, '');
478
- let retUrl = window.URL.createObjectURL(event.body);
479
- getFileCallback(retUrl, cdispFilename);
480
- }
481
- return { progress: 100, state: 'DONE', content: event.body };
482
- }
483
- return previous;
484
- }, { state: 'PENDING', progress: 0, content: null }), catchError((err, _) => { return this.registerErrorAndReturnEmptyObservable(err, ret.myGuid); }), finalize(() => { this.tryFinalizeByGuid(ret.myGuid); }));
485
- }));
486
- }
487
- /**
488
- * Riconosce se l'evento HTTP è di tipo **HttpResponse** e, se sì, lo casta al tipo corretto per essere utilizzato correttamente nel blocco di codice successivo
489
- */
490
- isHttpResponse(event) {
491
- return event.type === HttpEventType.Response;
492
- }
493
- /**
494
- * Riconosce se l'evento HTTP è di tipo **HttpProgressEvent** e, se sì, lo casta al tipo corretto per essere utilizzato correttamente nel blocco di codice successivo
495
- */
496
- isHttpProgressEvent(event) {
497
- return event.type === HttpEventType.DownloadProgress || event.type === HttpEventType.UploadProgress;
498
- }
499
- /**
500
- * Gestione dell'inizio di una chiamata ad un certo URL, viene generato un GUID da assegnarci, controllata la scadenza della cache,
501
- * e eventualmente loggato il fatto che sta per essere effettuata una chiamata HTTP
502
- *
503
- * @param {string} url Url a cui effettuare la chiamata
504
- * @returns {string} GUID assegnato alla chiamata
505
- */
506
- defaultStartCall(url) {
507
- let myGuid = this.getGUID();
508
- this.checkCacheInvalidation(url);
509
- this.callStatus[myGuid] = { url: url, success: true };
510
- this.log(this.loc("Starting call") + " " + myGuid + " " + this.loc("at URL") + ": " + url);
511
- return myGuid;
512
- }
513
- /**
514
- * Dato un url vengono controllate le informazioni su tutti gli url da invalidare collegati all'url chiamato e, se presenti in cache, invalidati
515
- *
516
- * @param {string} url URL per cui controllare se ci sono chiamate in cache da invalidare
517
- */
518
- checkCacheInvalidation(url) {
519
- let cache = this.localStorage.getLocalItem(this.localStorageHttpCacheKey);
520
- let tmp = /#cache(:?-(\d+))/gi.exec(url);
521
- let cacheTime = tmp ? tmp[2] : null;
522
- let normalizedUrl_tmp = url.replace("#cache" + (cacheTime ? "-" + cacheTime : ""), "");
523
- let normalizedUrl = normalizedUrl_tmp.substring(normalizedUrl_tmp.indexOf('/api'));
524
- if (!cache || !this.HTTP_INVALIDATION || !this.HTTP_INVALIDATION[normalizedUrl])
525
- return;
526
- let apisToInvalidate = this.HTTP_INVALIDATION[normalizedUrl];
527
- if (!apisToInvalidate || apisToInvalidate.length == 0)
528
- return;
529
- let keysToRemove = [];
530
- apisToInvalidate.forEach(api => {
531
- let cacheKey = this.makeCacheKey(api, null);
532
- for (let item in cache)
533
- if (item.indexOf(cacheKey) != -1)
534
- keysToRemove.push(item);
535
- });
536
- for (let i = 0; i < keysToRemove.length; i++) {
537
- let k = keysToRemove[i];
538
- this.log(this.loc("Invlalidating cache element") + " " + k);
539
- delete cache[k];
540
- }
541
- this.localStorage.setItem(this.localStorageHttpCacheKey, cache);
542
- }
543
- /**
544
- * Finalizzazione di una chiamata
545
- *
546
- * @param {string} guid GUID collegato alla chiamata appena terminata
547
- * @param {boolean} persistCacheIfIdle Effettua il persist della cache HTTP solo se non ci sono altre chiamate in corso, per evitare
548
- * che mi cambi sotto l'oggetto di cache mentre sto salvando le informazioni
549
- */
550
- tryFinalizeByGuid(guid, cacheInfos) {
551
- return __awaiter(this, void 0, void 0, function* () {
552
- this.log(this.loc("Finalizing call") + " " + guid + " " + this.loc("with status") + ": " + (!this.callStatus[guid] ? 'Unknown' : this.callStatus[guid].success ? this.loc('Success') : this.loc('Failure')));
553
- // TODO: Perdere 3-4 ore per capire perché ogni tanto arriva null in casi pesanti di Observable spammati a random
554
- if (this.callStatus[guid]) {
555
- // Alla prima chiamata buona, significa che almeno il login ce l'ho. Posso mettermi in modalità redirectInProgress false
556
- // e riiniziare a valutare errori di javashit
557
- if (this.callStatus[guid].success && this.ExtensionsImpl.readRedirectionStatus())
558
- this.ExtensionsImpl.writeRedirectionStatus(false);
559
- // Aggiungo la chiamata alla lista delle ultime 3 completate
560
- this.LastThreeCompletedCalls.unshift(this.callStatus[guid].url);
561
- if (this.LastThreeCompletedCalls.length > 3)
562
- this.LastThreeCompletedCalls.pop();
563
- // In ogni caso questa posso rimuoverla
564
- delete this.callStatus[guid];
565
- }
566
- // Se non ho nessun'altra chiamata in corso considero la situazione stabilizzatasi
567
- if (Object.keys(this.callStatus).length == 0)
568
- this.Stabilized.next(true);
569
- // Se vengo da una chiamata che ha aggiornato la cache a timer o globale marco il fatto che quella cache dev'essere aggiornata
570
- if (cacheInfos && cacheInfos.cache) {
571
- this.PersistTimedCacheASAP = this.PersistTimedCacheASAP || !!cacheInfos.cacheTime;
572
- this.PersistUntimedCacheASAP = this.PersistTimedCacheASAP || !cacheInfos.cacheTime;
573
- this.log(this.loc("Marking cache to be persisted as soon as possible"));
574
- }
575
- // Se una delle due cache devono essere aggiornate e non ho nessuna chiamata in corso effettuo l'aggiornamento in base a quale delle due va aggiornata
576
- // Alla fine di tutto marco come fatto
577
- if ((this.PersistTimedCacheASAP || this.PersistUntimedCacheASAP) && Object.keys(this.callStatus).length == 0) {
578
- var toCall = [];
579
- let tmpKey = "";
580
- if (this.PersistTimedCacheASAP) {
581
- tmpKey = this.localStorageHttpTimedCacheKey;
582
- toCall.push(this.localStorage.setItem(tmpKey, this.localStorage.getLocalItem(tmpKey)));
583
- }
584
- if (this.PersistUntimedCacheASAP) {
585
- tmpKey = this.localStorageHttpCacheKey;
586
- toCall.push(this.localStorage.setItem(tmpKey, this.localStorage.getLocalItem(tmpKey)));
587
- }
588
- this.log(this.loc("No more HTTP calls to be executed, entering idle state and persisting modified caches") + "...");
589
- var ret = yield forkJoin(toCall).toPromise();
590
- if (ret)
591
- this.log(this.loc("Caches succesfully persisted"));
592
- else
593
- this.log(this.loc("Errors persisting modified caches"));
594
- this.PersistTimedCacheASAP = false;
595
- this.PersistUntimedCacheASAP = false;
596
- }
597
- });
598
- }
599
- /**
600
- * Helper che dato un unico File o una lista di File crea un oggetto FormData che può essere inviato comodamente
601
- * ad un backend ASP.NET da cui si potrà accedere a Request.Form.Files
602
- *
603
- * @param {File | File[]} fileArrayOrFile Singolo File o lista di File. N.B: nella firma della funzione viene considerato **any** per fare test sulle proprietà
604
- * invece che fare test con l'**istanceof**
605
- *
606
- * @returns {FormData} FormData contenente tutti i file passati
607
- */
608
- getFilesFormData(fileArrayOrFile) {
609
- var formData = new FormData();
610
- if (fileArrayOrFile) {
611
- if (fileArrayOrFile.length)
612
- fileArrayOrFile.forEach(t => { formData.append("file", t, t.name); });
613
- else if (fileArrayOrFile.name)
614
- formData.append("files", fileArrayOrFile, fileArrayOrFile.name);
615
- }
616
- return formData;
617
- }
618
- /**
619
- * Helper che in base ai parametri disponibili genera gli Header HTTP per la chiamata da effettuare
620
- *
621
- * @param {string} contentType Indica se aggiungere agli header "Content-Type", valorizzato al valore del parametro
622
- * @param {string} accept Indica se aggiungere agli header "Accept", valorizzato al valore del parametro
623
- * @param {boolean} includeAuth Indica se aggiungere agli header "Authorization", valorizzato col token recuperato dall'hook **retrieveAccessToken** della classe di estensione
624
- * @param {string} transactionId Indica se aggiungere agli header "X-TX-ID", valorizzato al valore del parametro
625
- *
626
- * @returns {HttpHeaders} Header generati in base ai parametri
627
- */
628
- getHeaders(locale = 'it-IT', transactionId = "", includeAuth = true, contentType = "application/json", accept = "application/json") {
629
- var headers = new HttpHeaders();
630
- var authtoken = this.ExtensionsImpl.retrieveAccessToken();
631
- headers = headers.append("ngsw-bypass", "");
632
- if (contentType)
633
- headers = headers.append("Content-Type", contentType);
634
- if (transactionId)
635
- headers = headers.append("X-TX-ID", transactionId);
636
- if (authtoken && includeAuth)
637
- headers = headers.append("Authorization", "Bearer " + authtoken);
638
- if (accept)
639
- headers = headers.append("Accept", accept);
640
- headers = headers.append("Accept-Language", locale);
641
- return headers;
642
- }
643
- /**
644
- * Gestione di default degli errori
645
- *
646
- * @param {any} res Risultato della chiamata effettuata
647
- * @param {string} guid Identificativo GUID della chiamata effettuata
648
- */
649
- onError(res, guid) {
650
- return __awaiter(this, void 0, void 0, function* () {
651
- if (this.callStatus[guid])
652
- this.callStatus[guid].success = false;
653
- //Mi assicuro che tutti gli errori durante il redirect al login vengano ignorati
654
- if (this.ExtensionsImpl.readRedirectingToLogin()) {
655
- this.log(this.loc("Redirecting to Login, ignoring HTTP error on call") + " " + guid);
656
- return;
657
- }
658
- //Mi assicuro che venga gestito un solo errore per volta
659
- if (this.ExtensionsImpl.readHandlingErrorStatus()) {
660
- this.log(this.loc("Already Handling an error, ignoring HTTP error on call") + " " + guid);
661
- return;
662
- }
663
- else
664
- this.ExtensionsImpl.writeHandlingErrorStatus(true);
665
- let finalError = "";
666
- let finalStatus = "";
667
- if (this.isTypeError(res)) {
668
- finalError = res.message;
669
- finalStatus = "HTTP Service Internal Error";
670
- }
671
- else if (this.isHttpErrorResponse(res)) {
672
- finalError = yield this.getHttpErrorText(res.error);
673
- finalStatus = res.status.toString();
674
- switch (res.status) {
675
- // Unauthorized
676
- case 401:
677
- if (this.ExtensionsImpl.readRedirectionStatus()) {
678
- this.log(this.loc("Error 401 on call") + " " + guid + " " + this.loc("with redirect already in progress. Ignoring this event"));
679
- return;
680
- }
681
- this.log(this.loc("Error 401 on call") + " " + guid + " " + this.loc("redirecting to login."));
682
- this.ExtensionsImpl.writeRedirectionStatus(true);
683
- this.ExtensionsImpl.writeRedirectingToLogin(true);
684
- this.ExtensionsImpl.redirectToLogin();
685
- return;
686
- // Handled exception
687
- case 400:
688
- // No Permissions
689
- case 403:
690
- this.ExtensionsImpl.handleBlockingException(res.status, finalError);
691
- return;
692
- // Not found
693
- case 404:
694
- this.ExtensionsImpl.handleBlockingException(res.status, this.loc("Resource not found"));
695
- return;
696
- // NotConfiguredException
697
- case 444:
698
- if (this.ExtensionsImpl.readRedirectionStatus())
699
- this.log(this.loc("Error 444 on call") + " " + guid + " " + this.loc("with redirect already in progress. Ignoring this event"));
700
- else if (!this.ExtensionsImpl.handleNotConfiguredException())
701
- this.ExtensionsImpl.handleBlockingException(res.status, finalError);
702
- return;
703
- case 0:
704
- finalError = `Generic connection error while calling '[${guid}] - ${this.callStatus[guid].url}' at ${dayjs().format()}. Response: ${JSON.stringify(res)}`;
705
- }
706
- }
707
- this.ExtensionsImpl.handleException(finalStatus, finalError);
708
- });
709
- }
710
- /**
711
- * Dato un errore restituisce una promise con la stringa finale dell'errore in modo da poter fare un await
712
- *
713
- * @param {any} err Errore da controllare
714
- *
715
- * @returns {Promise<string>} Promise che risolve con la stringa finale dell'errore
716
- */
717
- getHttpErrorText(err) {
718
- // Se ho un Blob può essere o un CallResult o suppongo una semplice stringa,
719
- // altrimenti potrebbe essere direttamente un CallResult, oppure una semplice stringa
720
- return new Promise((resolve) => {
721
- if (err instanceof Blob) {
722
- let reader = new FileReader();
723
- reader.onload = (e) => {
724
- let errMsg = e.target.result;
725
- let jsonerrMsg;
726
- try {
727
- jsonerrMsg = JSON.parse(errMsg);
728
- }
729
- catch (e) { }
730
- return resolve(jsonerrMsg && this.isCallResult(jsonerrMsg) ? jsonerrMsg.error.message : errMsg);
731
- };
732
- reader.readAsText(err);
733
- }
734
- else if (this.isCallResult(err))
735
- return resolve(err.error.message);
736
- else
737
- return resolve(err === null || err === void 0 ? void 0 : err.toString());
738
- });
739
- }
740
- /**
741
- * Riconosce se l'oggetto è di tipo **CallResult** e, se sì, lo casta al tipo corretto per essere utilizzato correttamente nel blocco di codice successivo
742
- *
743
- * @param {any} err Errore da controllare
744
- */
745
- isCallResult(err) {
746
- var _a;
747
- return !!((_a = err === null || err === void 0 ? void 0 : err.error) === null || _a === void 0 ? void 0 : _a.message);
748
- }
749
- /**
750
- * Riconosce se l'errore è di tipo **HttpErrorResponse** e, se sì, lo casta al tipo corretto per essere utilizzato correttamente nel blocco di codice successivo
751
- *
752
- * @param {any} err Errore da controllare
753
- */
754
- isHttpErrorResponse(err) {
755
- return err instanceof HttpErrorResponse;
756
- }
757
- /**
758
- * Riconosce se l'errore è di tipo **TypeError** e, se sì, lo casta al tipo corretto per essere utilizzato correttamente nel blocco di codice successivo
759
- *
760
- * @param {any} err Errore da controllare
761
- */
762
- isTypeError(err) {
763
- return err.name == "TypeError";
764
- }
765
- /**
766
- * Come dice il nome, registra un errore e restituisce un Observable vuoto come risultato della chiamata
767
- *
768
- * @param {any} res Risultato della chiamata effettuata
769
- * @param {string} guid Identificativo GUID della chiamata effettuata
770
- * @param {boolean} handleError Indica se gestire l'errore via libreria o se limitarsi a restituire l'Observable vuoto
771
- *
772
- * @returns {Observable<any>} Observable vuoto
773
- */
774
- registerErrorAndReturnEmptyObservable(res, guid, handleError = true) {
775
- if (handleError)
776
- this.onError(res, guid);
777
- return new Observable(() => { });
778
- }
779
- /**
780
- * Dato un Url e dei parametri cerca di recuperare l'eventuale oggetto già salvato in cache con le informazioni base della cache stessa
781
- *
782
- * @param {string} url URL su cui effettuare la chiamata
783
- * @param {HttpParams} params Parametri della chiamata (nulli in caso di POST)
784
- *
785
- * @returns {CacheInfos} Oggetto contenente le informazioni sulla cache per l'oggetto specificato
786
- */
787
- tryGetCacheInformations(url, params) {
788
- let cachingKey = null, cacheTime = null, item = null;
789
- let useCaching = !!(/#cache/gi.exec(url));
790
- if (useCaching) {
791
- let tmp = /#cache(:?-(\d+))/gi.exec(url);
792
- cacheTime = tmp ? tmp[2] : null;
793
- url = url.replace("#cache" + (cacheTime ? "-" + cacheTime : ""), "");
794
- if (this.untimedCacheExpired() && !cacheTime)
795
- this.resetHttpUntimedCacheStorage();
796
- cachingKey = this.makeCacheKey(url, params);
797
- let cacheKey = cacheTime ? this.localStorageHttpTimedCacheKey : this.localStorageHttpCacheKey;
798
- let cacheLs = this.localStorage.getLocalItem(cacheKey);
799
- let cache = cacheLs ? cacheLs : {};
800
- if (cache && cache[cachingKey] && !this.timedCacheItemExpired(cache[cachingKey])) {
801
- // Se gestisco il tempo esatto della cache prima di restituire l'oggetto cachato lo ripulisco
802
- // dalle proprietà interne che gli ho aggiunto per controllarne la scadenza
803
- if (cacheTime)
804
- delete cache[cachingKey].__expire;
805
- item = cache[cachingKey];
806
- }
807
- }
808
- // Per assicurarmi che il rifeirmento degli oggetti sia diverso utilizzo il deepClone
809
- return new CacheInfos(url, useCaching, cachingKey, cacheTime, this.utisExts.deepClone(item));
810
- }
811
- /**
812
- * Inserisce un oggetto nella cache appropriata in base alle informazioni contenute nel parametro **cacheInfos**
813
- *
814
- * @param {T} item Oggetto da inserire nella cache
815
- * @param {CacheInfos} cacheInfos Informazioni sulla cache recuperate da una chiamata precedente a **tryGetCacheInformations**
816
- */
817
- cacheResponse(item, cacheInfos) {
818
- let cacheKey = cacheInfos.cacheTime ? this.localStorageHttpTimedCacheKey : this.localStorageHttpCacheKey;
819
- let cacheLs = this.localStorage.getLocalItem(cacheKey);
820
- let cache = cacheLs ? cacheLs : {};
821
- cache[cacheInfos.cacheKey] = item;
822
- if (cacheInfos.cacheTime)
823
- cache[cacheInfos.cacheKey].__expire = dayjs().add(cacheInfos.cacheTime, "seconds");
824
- this.localStorage.setLocalItem(cacheKey, cache);
825
- }
826
- /**
827
- * Controlla se la cache per le chiamate senza expire time è scaduta
828
- *
829
- * @returns {boolean} **true** se la cache è scaduta e dev'essere ripulita, **false** altrimenti
830
- */
831
- untimedCacheExpired() {
832
- let expire = JSON.parse(localStorage.getItem(this.localStorageHttpCacheExpireKey));
833
- return !expire || expire && dayjs(expire) < dayjs();
834
- }
835
- /**
836
- * Controlla se la cache per una chiamata che ha un tempo di vita ben definito è scaduta o meno
837
- *
838
- * @param {any} item Oggetto recuperato dalla cache a cui ho aggiunto la chiave interna __expire
839
- *
840
- * @returns {boolean} **true** se la cache è scaduta e dev'essere ripulita, **false** altrimenti
841
- */
842
- timedCacheItemExpired(item) {
843
- return dayjs(item.__expire) < dayjs();
844
- }
845
- /**
846
- * Ripulisce la cache e imposta la prossima scadenza ad adesso + **CLIENT_CACHE_DURATION_S** (token valorizzato in fase di configurazione dalla proprietà **clientCacheDurationS** della classe **HttpServiceModuleConfig**)
847
- */
848
- resetHttpUntimedCacheStorage() {
849
- return __awaiter(this, void 0, void 0, function* () {
850
- yield this.localStorage.setItem(this.localStorageHttpCacheKey, {}).toPromise();
851
- localStorage.setItem(this.localStorageHttpCacheExpireKey, JSON.stringify(dayjs().add(this.CLIENT_CACHE_DURATION_S, "second")));
852
- });
853
- }
854
- /**
855
- * Ripulisce la cache delle chiamate con un tempo di expire definito
856
- */
857
- resetHttpTimedCacheStorage() {
858
- return __awaiter(this, void 0, void 0, function* () {
859
- yield this.localStorage.setItem(this.localStorageHttpTimedCacheKey, {}).toPromise();
860
- });
861
- }
862
- /**
863
- * Genera una chiave per la cache delle chiamate in base ad URL e Parametri HTTP
864
- *
865
- * @param {string} url URL su cui effettuare la chiamata
866
- * @param {HttpParams} params Parametri della chiamata
867
- *
868
- * @returns {string} Chiave che rappresenta in maniera univoca la chiamata
869
- */
870
- makeCacheKey(url, params) {
871
- this.me = this.me || this.ExtensionsImpl.retrieveIdentity();
872
- let authKeyPart = (this.me ? this.me.Idtenant : "") + (this.me && this.CACHE_BY_USER ? this.me.IdUser : "");
873
- let paramsKeyPart = params && params.keys().length > 0 ? params.keys().reduce((prev, next) => prev + "," + next + '=' + params.get(next), "") : "";
874
- return authKeyPart + "_" + url.substring(url.indexOf("api") + 4) + "?" + paramsKeyPart;
875
- }
876
- /**
877
- * Generazione GUID
878
- *
879
- * @returns {string} Nuovo GUID generato in maniera casuale
880
- */
881
- getGUID() {
882
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
883
- var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
884
- return v.toString(16);
885
- });
886
- }
887
- /**
888
- * Metodo per scrivere log a console qualora **DEBUG_MODE** risultasse **true**
889
- *
890
- * @param {string} message Messaggio di log
891
- */
892
- log(message) {
893
- if (this.HTTP_DEBUG_MODE)
894
- console.log("@httpservice: " + message);
895
- }
896
- /**
897
- * Helper per la localizzazione dei messaggi
898
- *
899
- * @param {string} message Messaggio da localizzare
900
- *
901
- * @returns {string} Messaggio localizzato
902
- */
903
- loc(message) {
904
- // Togliamo velocemente ste localizzazioni inutili....
905
- return message;
906
- }
907
- /**
908
- * Helper per lanciare la selezione di tutto quello che è relativo a un api di ricerca con AppSearch (di cui non utilizzo il tipo vero per ridurre le dipendenze)
909
- */
910
- getAll(view, api, pars, transaction) {
911
- if (!view.selection.all)
912
- return of(view.selection.items);
913
- var jsonView = this.utisExts.deepClone(view);
914
- jsonView.page = 1;
915
- jsonView.itemsperpageoverride = 999999;
916
- return this.post(api, jsonView, pars, transaction).pipe(map(res => {
917
- var _a;
918
- let items = res.items;
919
- items.forEach(t => t.hash = this.hash.hashObject(t, null, false));
920
- if (((_a = res.selection.exclusions) === null || _a === void 0 ? void 0 : _a.length) > 0)
921
- items = items.filter((t) => !res.selection.exclusions.find((e) => this.hash.hashObject(e, null, false) == t.hash));
922
- return items;
923
- }));
924
- }
925
- beginTransaction(executionKey, secondsTimeout) {
926
- this.log("beginTransaction call received: " + executionKey);
927
- var pars = new HttpParams().set("executionKey", executionKey);
928
- if (secondsTimeout)
929
- pars = pars.set("secondsTimeout", secondsTimeout.toString());
930
- return this.get(this.GET_Trans_BeginTrans, pars);
931
- }
932
- checkTransaction(executionKey) {
933
- this.log("checkTransaction call received: " + executionKey);
934
- return this.get(this.GET_Trans_CheckExecution, new HttpParams().set("executionKey", executionKey));
935
- }
936
- endTransaction(transactionKey, transactionResult) {
937
- this.log("endTransaction call received: " + transactionKey + " Commit: " + transactionResult);
938
- let pars = new HttpParams().set("idtrans", transactionKey).set("success", transactionResult.toString());
939
- return this.get(this.GET_Trans_EndTrans, pars);
940
- }
941
- }
942
- HTTPService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HTTPService, deps: [{ token: HttpServiceExtensions }, { token: HTTP_INVALIDATION, optional: true }, { token: APP_NAME }, { token: CLIENT_CACHE_DURATION_S }, { token: CACHE_BY_USER }, { token: HTTP_DEBUG_MODE }, { token: i2.BaseLocalization }, { token: i3.HttpClient }, { token: i4.CacheService }, { token: i5.HashingService }, { token: i5.UtilityService }], target: i0.ɵɵFactoryTarget.Injectable });
943
- HTTPService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HTTPService, providedIn: 'root' });
944
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HTTPService, decorators: [{
945
- type: Injectable,
946
- args: [{ providedIn: 'root' }]
947
- }], ctorParameters: function () {
948
- return [{ type: HttpServiceExtensions }, { type: undefined, decorators: [{
949
- type: Optional
950
- }, {
951
- type: Inject,
952
- args: [HTTP_INVALIDATION]
953
- }] }, { type: undefined, decorators: [{
954
- type: Inject,
955
- args: [APP_NAME]
956
- }] }, { type: undefined, decorators: [{
957
- type: Inject,
958
- args: [CLIENT_CACHE_DURATION_S]
959
- }] }, { type: undefined, decorators: [{
960
- type: Inject,
961
- args: [CACHE_BY_USER]
962
- }] }, { type: undefined, decorators: [{
963
- type: Inject,
964
- args: [HTTP_DEBUG_MODE]
965
- }] }, { type: i2.BaseLocalization }, { type: i3.HttpClient }, { type: i4.CacheService }, { type: i5.HashingService }, { type: i5.UtilityService }];
966
- } });
967
-
968
- const titleOrGuid = (title) => {
969
- let ttl = title.getTitle();
970
- if (ttl)
971
- return ttl.substring(0, ttl.indexOf('>') > 0 ? ttl.indexOf('>') - 1 : ttl.length);
972
- else
973
- return Math.random().toString(36).replace('0.', '');
974
- };
975
- class HttpserviceModule {
976
- static forRoot(config) {
977
- return {
978
- ngModule: HttpserviceModule,
979
- providers: [
980
- { provide: HTTP_INVALIDATION, useValue: config === null || config === void 0 ? void 0 : config.httpInvalidation },
981
- { provide: CLIENT_CACHE_DURATION_S, useValue: (config === null || config === void 0 ? void 0 : config.clientCacheDurationS) || 3600 },
982
- { provide: APP_NAME, useFactory: titleOrGuid, deps: [Title] },
983
- { provide: CACHE_BY_USER, useValue: (config === null || config === void 0 ? void 0 : config.cacheByUser) || false },
984
- { provide: HTTP_DEBUG_MODE, useValue: (config === null || config === void 0 ? void 0 : config.debugMode) || false }
985
- ]
986
- };
987
- }
988
- }
989
- HttpserviceModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HttpserviceModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
990
- HttpserviceModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: HttpserviceModule });
991
- HttpserviceModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HttpserviceModule });
992
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HttpserviceModule, decorators: [{
993
- type: NgModule
994
- }] });
995
-
996
- /**
997
- * Classe di configurazione per il Modulo della libreria
998
- */
999
- class HttpServiceModuleConfig {
1000
- }
1001
-
1002
- class Download {
1003
- }
1004
-
1005
- /*
1006
- * Public API Surface of httpservice
1007
- */
1008
-
1009
- /**
1010
- * Generated bundle index. Do not edit.
1011
- */
1012
-
1013
- export { APP_NAME, CACHE_BY_USER, CLIENT_CACHE_DURATION_S, Download, HTTPService, HTTP_DEBUG_MODE, HTTP_INVALIDATION, HttpServiceExtensions, HttpServiceModuleConfig, HttpserviceModule };
1014
- //# sourceMappingURL=esfaenza-httpservice.mjs.map