uni-manager 0.1.16 → 0.1.18
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.
|
@@ -3,7 +3,7 @@ import { UniToastManager } from 'uni-manager/toast';
|
|
|
3
3
|
import isEqual from 'lodash-es/isEqual';
|
|
4
4
|
import { UniErrorManager } from 'uni-manager/error';
|
|
5
5
|
import { MapOperator, PollingErrorMode, EmitValueMode } from 'uni-model-type/enum';
|
|
6
|
-
import { UniHttpError,
|
|
6
|
+
import { UniHttpError, isErrorResponse } from 'uni-error/http';
|
|
7
7
|
import { UniTypeDateManager } from 'uni-manager/type';
|
|
8
8
|
|
|
9
9
|
function operatorHandler(operator) {
|
|
@@ -235,9 +235,12 @@ function updateHasError(id, hasError) {
|
|
|
235
235
|
* Esegue una richiesta HTTP nativa gestendo l'imbuto dei 4 casi d'errore.
|
|
236
236
|
*/
|
|
237
237
|
async function execute(url, init) {
|
|
238
|
+
const startTime = performance.now();
|
|
238
239
|
try {
|
|
239
240
|
/* Esecuzione della richiesta HTTP nativa */
|
|
240
241
|
const res = await fetch(url, init);
|
|
242
|
+
/* Calcolo durata */
|
|
243
|
+
const durationMs = Math.round(performance.now() - startTime);
|
|
241
244
|
/* Gestione dello stato 204: chiamata andata a buon fine ma senza dati di ritorno */
|
|
242
245
|
if (res.status === 204) {
|
|
243
246
|
return undefined;
|
|
@@ -247,7 +250,7 @@ async function execute(url, init) {
|
|
|
247
250
|
return res;
|
|
248
251
|
}
|
|
249
252
|
/* Gestione Errore HTTP: la chiamata è arrivata al server ma ha restituito uno stato 4xx o 5xx */
|
|
250
|
-
let
|
|
253
|
+
let httpError;
|
|
251
254
|
try {
|
|
252
255
|
/* Clonazione della risposta per l'ispezione del payload senza consumare lo stream originale */
|
|
253
256
|
const resClone = res.clone();
|
|
@@ -255,17 +258,27 @@ async function execute(url, init) {
|
|
|
255
258
|
const contentType = res.headers.get('content-type') ?? '';
|
|
256
259
|
const isJson = contentType.startsWith('application/json');
|
|
257
260
|
/* Estrazione del corpo dell'errore in base al formato rilevato */
|
|
258
|
-
|
|
261
|
+
httpError = isJson ? await resClone.json() : await resClone.text();
|
|
259
262
|
}
|
|
260
263
|
catch {
|
|
261
264
|
/* Fallback in caso di fallimento della clonazione o del parsing del testo */
|
|
262
|
-
|
|
265
|
+
httpError = `Failed to parse error response body (Status: ${res.status})`;
|
|
263
266
|
}
|
|
264
267
|
// ERRORE CON STATUS, CASO A: errore applicativo backend ('be')
|
|
265
268
|
// Se il payload estratto supera il controllo 'isHttpException', significa che la richiesta è stata elaborata dal codice C#, ha intercettato il GlobalExceptionHandler ed è ritornata come JSON strutturato.
|
|
266
269
|
// Questo scenario si applica a qualsiasi codice (400, 404, 500, ecc.) purché sia formattato dal backend.
|
|
267
|
-
if (
|
|
268
|
-
|
|
270
|
+
if (isErrorResponse(httpError)) {
|
|
271
|
+
const errorResponse = httpError;
|
|
272
|
+
throw new UniHttpError({
|
|
273
|
+
type: 'be',
|
|
274
|
+
url,
|
|
275
|
+
httpStatus: res.status,
|
|
276
|
+
durationMs,
|
|
277
|
+
userAgent: navigator.userAgent,
|
|
278
|
+
queryParams: url.searchParams,
|
|
279
|
+
init,
|
|
280
|
+
error: errorResponse,
|
|
281
|
+
});
|
|
269
282
|
}
|
|
270
283
|
// ERRORE CON STATUS, CASO B: errore infrastrutturale del server ('server')
|
|
271
284
|
// Se l'esecuzione raggiunge questo punto, il server ha risposto con un errore (es. 404, 405, 502, 504) ma non ha restituito il JSON customizzato.
|
|
@@ -273,15 +286,27 @@ async function execute(url, init) {
|
|
|
273
286
|
// Di conseguenza, il flag 'isBe' deve essere impostato a false poiché non deriva dalla logica applicativa.
|
|
274
287
|
const defaultMessage = `HTTP Error ${res.status}${res.statusText ? ` (${res.statusText})` : ''}`;
|
|
275
288
|
const errorTracker = new Error(defaultMessage);
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
289
|
+
const errorResponse = {
|
|
290
|
+
exception: {
|
|
291
|
+
isBe: false,
|
|
292
|
+
type: 'ServerError',
|
|
293
|
+
message: typeof httpError === 'string' && httpError.trim()
|
|
294
|
+
? httpError // Se è presente l'HTML o del testo reale del server, viene utilizzato questo
|
|
295
|
+
: defaultMessage, // Se il corpo della risposta è vuoto, viene usato il messaggio di sicurezza
|
|
296
|
+
stackTrace: errorTracker.stack ?? '',
|
|
297
|
+
},
|
|
298
|
+
innerException: null,
|
|
283
299
|
};
|
|
284
|
-
throw new UniHttpError(
|
|
300
|
+
throw new UniHttpError({
|
|
301
|
+
type: 'server',
|
|
302
|
+
url,
|
|
303
|
+
httpStatus: res.status,
|
|
304
|
+
durationMs,
|
|
305
|
+
userAgent: navigator.userAgent,
|
|
306
|
+
queryParams: url.searchParams,
|
|
307
|
+
init,
|
|
308
|
+
error: errorResponse,
|
|
309
|
+
});
|
|
285
310
|
}
|
|
286
311
|
catch (error) {
|
|
287
312
|
// ERRORE CON/SENZA STATUS: già gestito, rilancio diretto.
|
|
@@ -295,12 +320,24 @@ async function execute(url, init) {
|
|
|
295
320
|
// Il browser solleva un 'TypeError' (es. "Failed to fetch").
|
|
296
321
|
if (error instanceof TypeError) {
|
|
297
322
|
const fallbackException = {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
323
|
+
exception: {
|
|
324
|
+
isBe: false,
|
|
325
|
+
type: error.name || 'NetworkError',
|
|
326
|
+
message: error.message,
|
|
327
|
+
stackTrace: error.stack ?? '',
|
|
328
|
+
},
|
|
329
|
+
innerException: null,
|
|
302
330
|
};
|
|
303
|
-
throw new UniHttpError(
|
|
331
|
+
throw new UniHttpError({
|
|
332
|
+
type: 'network',
|
|
333
|
+
url,
|
|
334
|
+
httpStatus: 0,
|
|
335
|
+
durationMs: 0,
|
|
336
|
+
userAgent: navigator.userAgent,
|
|
337
|
+
queryParams: url.searchParams,
|
|
338
|
+
init,
|
|
339
|
+
error: fallbackException,
|
|
340
|
+
});
|
|
304
341
|
}
|
|
305
342
|
// ERRORE SENZA STATUS, CASO B: errore frontend ('fe')
|
|
306
343
|
// Qualsiasi altro errore imprevisto che non derivi da un fallimento della fetch o della risposta.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uni-manager-http.mjs","sources":["../../../projects/uni-manager/http/handler.ts","../../../projects/uni-manager/http/core.ts","../../../projects/uni-manager/http/execute.ts","../../../projects/uni-manager/http/util.ts","../../../projects/uni-manager/http/manager.ts","../../../projects/uni-manager/http/uni-manager-http.ts"],"sourcesContent":["import {\r\n EMPTY,\r\n Observable,\r\n OperatorFunction,\r\n concatMap,\r\n exhaustMap,\r\n mergeMap,\r\n of,\r\n switchMap,\r\n throwError,\r\n} from 'rxjs';\r\nimport { UniHttpError } from 'uni-error/http';\r\nimport { UniErrorManager } from 'uni-manager/error';\r\nimport { MapOperator, PollingErrorMode } from 'uni-model-type/enum';\r\n\r\nexport function operatorHandler<T>(\r\n operator: MapOperator,\r\n): (\r\n project: (value: number) => Observable<T | undefined>,\r\n) => OperatorFunction<number, T | undefined> {\r\n // Gestione della concorrenza in base al parametro\r\n switch (operator) {\r\n case MapOperator.EXHAUST_MAP: {\r\n return (project) => exhaustMap(project);\r\n }\r\n case MapOperator.CONCAT_MAP: {\r\n return (project) => concatMap(project);\r\n }\r\n case MapOperator.MERGE_MAP: {\r\n return (project) => mergeMap(project);\r\n }\r\n case MapOperator.SWITCH_MAP: {\r\n return (project) => switchMap(project);\r\n }\r\n }\r\n}\r\n\r\nexport function errorHandler(\r\n ref: string,\r\n err: unknown,\r\n errorMode: PollingErrorMode,\r\n): Observable<never> {\r\n // Controllo: sia effettivamente un errore di tipo 'UniHttpError'\r\n if (err instanceof UniHttpError) {\r\n switch (errorMode) {\r\n case PollingErrorMode.IGNORE: {\r\n return of();\r\n }\r\n case PollingErrorMode.SKIP: {\r\n return EMPTY;\r\n }\r\n case PollingErrorMode.IGNORE_WITH_ERROR: {\r\n UniErrorManager.add(ref, err);\r\n return of();\r\n }\r\n case PollingErrorMode.STOP: {\r\n UniErrorManager.add(ref, err);\r\n return throwError(() => err);\r\n }\r\n }\r\n } else {\r\n return throwError(() => err);\r\n }\r\n}\r\n","import isEqual from 'lodash-es/isEqual';\r\nimport {\r\n Observable,\r\n catchError,\r\n defer,\r\n distinctUntilChanged,\r\n finalize,\r\n from,\r\n tap,\r\n timer,\r\n} from 'rxjs';\r\nimport { UniErrorManager } from 'uni-manager/error';\r\nimport { UniToastManager } from 'uni-manager/toast';\r\nimport { EmitValueMode, MapOperator, PollingErrorMode } from 'uni-model-type/enum';\r\nimport type { HttpConfig, HttpConfigPolling, HttpRef } from 'uni-model-type/type';\r\n\r\nimport { errorHandler, operatorHandler } from './handler';\r\nimport { UniHttpManager } from './manager';\r\n\r\n/* ------------------------------------------------------------------------------- */\r\n/* -------------------------------- Funzioni Core RxJS -------------------------- */\r\n/* ------------------------------------------------------------------------------- */\r\n/**\r\n * Gestisce l'esecuzione e il ciclo di vita di una singola richiesta HTTP.\r\n * Si occupa della registrazione della reference, della gestione dei loader, dei toast di successo e dell'intercettazione degli errori.\r\n */\r\nexport function http$<T>(\r\n url: URL,\r\n refType: HttpRef['type'],\r\n config: HttpConfig<T>,\r\n promiseFactory: () => Promise<T | undefined>,\r\n): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const { ref, toast, hasLoader } = config;\r\n\r\n return defer(() => {\r\n const http$ = from(promiseFactory());\r\n return http$.pipe(\r\n tap({\r\n subscribe: () => {\r\n /* Creazione reference */\r\n add(ref, url, refType);\r\n\r\n /* Incrementa per il loader */\r\n if (hasLoader !== false) {\r\n updateIsLoading(ref, 1);\r\n }\r\n },\r\n unsubscribe: () => {\r\n /* Rimozione reference */\r\n remove(ref);\r\n },\r\n next: (res) => {\r\n /* Mostra toast (se presente) */\r\n if (toast) {\r\n UniToastManager.showHttp(toast, res);\r\n }\r\n },\r\n }),\r\n catchError((err) => {\r\n // Aggiorna la ref nella map\r\n updateHasError(ref, true);\r\n\r\n /* Gestione errore */\r\n return errorHandler(ref, err, PollingErrorMode.STOP);\r\n }),\r\n finalize(() => {\r\n /* Decrementa per il loader */\r\n if (hasLoader !== false) {\r\n updateIsLoading(ref, -1);\r\n }\r\n }),\r\n );\r\n });\r\n}\r\n\r\n/**\r\n * Avvia e coordina un ciclo di polling a intervalli regolari.\r\n * Gestisce la concorrenza tramite operatori RxJS configurabili, la rimozione dei popup, di errore nelle iterazioni successive e i comportamenti custom al primo avvio.\r\n */\r\nexport function httpPolling$<T>(\r\n url: URL,\r\n config: HttpConfigPolling<T>,\r\n promiseFactory: () => Promise<T | undefined>,\r\n): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const {\r\n interval,\r\n ref,\r\n operator = MapOperator.SWITCH_MAP,\r\n errorMode = PollingErrorMode.STOP,\r\n emitValueMode = EmitValueMode.ON_NEW_DATA,\r\n firstIteration,\r\n } = config;\r\n\r\n const timer$ = timer(0, interval);\r\n const source$ = timer$.pipe(\r\n tap({\r\n subscribe: () => {\r\n /* Creazione reference */\r\n add(ref, url, 'polling');\r\n },\r\n unsubscribe: () => {\r\n /* Rimozione reference */\r\n remove(ref);\r\n },\r\n }),\r\n operatorHandler<T>(operator)((index) => {\r\n /* Incrementa per il loader */\r\n if (index === 0 && firstIteration?.hasLoader !== false) {\r\n updateIsLoading(ref, 1);\r\n }\r\n\r\n return defer(() => {\r\n const http$ = from(promiseFactory());\r\n return http$.pipe(\r\n tap((res) => {\r\n /* Meccanismo di ripristino automatico: se il polling torna in salute, cancella l'errore dallo store e nasconde i relativi messaggi a schermo */\r\n if (errorMode === PollingErrorMode.IGNORE_WITH_ERROR) {\r\n updateHasError(ref, false);\r\n UniErrorManager.remove(ref);\r\n }\r\n\r\n /* Prima risposta */\r\n if (index === 0 && firstIteration?.toast) {\r\n UniToastManager.showHttp(firstIteration.toast, res);\r\n }\r\n }),\r\n catchError((err) => {\r\n // Aggiorna la ref nella map\r\n updateHasError(ref, true);\r\n\r\n /* Gestione errore */\r\n return errorHandler(ref, err, errorMode);\r\n }),\r\n finalize(() => {\r\n /* Decrementa per il loader */\r\n if (index === 0 && firstIteration?.hasLoader !== false) {\r\n updateIsLoading(ref, -1);\r\n }\r\n }),\r\n );\r\n });\r\n }),\r\n );\r\n\r\n return emitValueMode === EmitValueMode.ON_NEW_DATA\r\n ? source$.pipe(distinctUntilChanged((prev, cur) => isEqual(prev, cur)))\r\n : source$;\r\n}\r\n\r\n/* ------------------------------------------------------------------------------- */\r\n/* ------------------------------------ Utils ------------------------------------ */\r\n/* ------------------------------------------------------------------------------- */\r\n/**\r\n * Aggiunge una nuova ref nello store solo se non è già presente.\r\n * Se l'ID esiste già, l'operazione viene interrotta per preservare il dato originale.\r\n */\r\nfunction add(id: string, url: URL, type: HttpRef['type']): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentValue;\r\n\r\n // Controllo: se è presente l'item allora termina\r\n if (oldMap.get(id)) return;\r\n\r\n // Crea il nuovo oggetto\r\n const newItemMap: HttpRef = {\r\n type,\r\n lineId: undefined,\r\n url,\r\n hasError: false,\r\n pendingCount: 0,\r\n };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Rimuove un http ref tramite ID\r\n */\r\nfunction remove(id: string): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentValue;\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n if (!oldMap.has(id)) return;\r\n\r\n // Aggiorna store\r\n const newMap = new Map(oldMap);\r\n newMap.delete(id);\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Aggiorna il contatore delle chiamate pendenti per una specifica ref.\r\n * Incrementa o decrementa 'pendingCount' garantendo che non scenda mai sotto lo zero.\r\n * Se la ref non esiste, l'operazione viene ignorata.\r\n */\r\nfunction updateIsLoading(id: string, delta: -1 | 1): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentValue;\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n const oldItem = oldMap.get(id);\r\n if (!oldItem) return;\r\n\r\n // Aggiorna l'oggetto\r\n const newItemMap: HttpRef = {\r\n ...oldItem,\r\n pendingCount: Math.max(0, oldItem.pendingCount + delta),\r\n };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Aggiorna lo stato di errore per una specifica ref.\r\n * Se il valore di 'hasError' è identico a quello attuale o se la ref non esiste,\r\n * l'operazione viene interrotta per evitare aggiornamenti inutili.\r\n */\r\nfunction updateHasError(id: string, hasError: boolean): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentValue;\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n const oldItem = oldMap.get(id);\r\n if (!oldItem) return;\r\n\r\n // Controllo: se con lo stesso valore, salta\r\n if (oldItem.hasError === hasError) return;\r\n\r\n // Aggiorna l'oggetto\r\n const newItemMap: HttpRef = { ...oldItem, hasError };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n","import { isHttpException, UniHttpError } from 'uni-error/http';\r\nimport type { ExceptionHttp, FileDatasource } from 'uni-model-type/type';\r\n\r\n/**\r\n * Esegue una richiesta HTTP nativa gestendo l'imbuto dei 4 casi d'errore.\r\n */\r\nasync function execute(url: URL, init?: RequestInit): Promise<Response | undefined> {\r\n try {\r\n /* Esecuzione della richiesta HTTP nativa */\r\n const res = await fetch(url, init);\r\n\r\n /* Gestione dello stato 204: chiamata andata a buon fine ma senza dati di ritorno */\r\n if (res.status === 204) {\r\n return undefined;\r\n }\r\n\r\n /* Gestione ok HTTP: chiamata andata a buon fine. Viene restituita la risposta al chiamante. */\r\n if (res.ok) {\r\n return res;\r\n }\r\n\r\n /* Gestione Errore HTTP: la chiamata è arrivata al server ma ha restituito uno stato 4xx o 5xx */\r\n let httpErrorPayload: unknown;\r\n\r\n try {\r\n /* Clonazione della risposta per l'ispezione del payload senza consumare lo stream originale */\r\n const resClone = res.clone();\r\n\r\n /* Verifica se il formato è un JSON */\r\n const contentType = res.headers.get('content-type') ?? '';\r\n const isJson = contentType.startsWith('application/json');\r\n\r\n /* Estrazione del corpo dell'errore in base al formato rilevato */\r\n httpErrorPayload = isJson ? await resClone.json() : await resClone.text();\r\n } catch {\r\n /* Fallback in caso di fallimento della clonazione o del parsing del testo */\r\n httpErrorPayload = `Failed to parse error response body (Status: ${res.status})`;\r\n }\r\n\r\n // ERRORE CON STATUS, CASO A: errore applicativo backend ('be')\r\n // Se il payload estratto supera il controllo 'isHttpException', significa che la richiesta è stata elaborata dal codice C#, ha intercettato il GlobalExceptionHandler ed è ritornata come JSON strutturato.\r\n // Questo scenario si applica a qualsiasi codice (400, 404, 500, ecc.) purché sia formattato dal backend.\r\n if (isHttpException(httpErrorPayload)) {\r\n throw new UniHttpError('be', res.status, url, httpErrorPayload);\r\n }\r\n\r\n // ERRORE CON STATUS, CASO B: errore infrastrutturale del server ('server')\r\n // Se l'esecuzione raggiunge questo punto, il server ha risposto con un errore (es. 404, 405, 502, 504) ma non ha restituito il JSON customizzato.\r\n // Rappresenta il blocco da parte del server web (IIS, Nginx, Proxy) che ha rifiutato la chiamata o ha risposto con una pagina HTML/Testo standard.\r\n // Di conseguenza, il flag 'isBe' deve essere impostato a false poiché non deriva dalla logica applicativa.\r\n const defaultMessage = `HTTP Error ${res.status}${res.statusText ? ` (${res.statusText})` : ''}`;\r\n const errorTracker = new Error(defaultMessage);\r\n const fallbackException: ExceptionHttp = {\r\n isBe: false,\r\n type: 'ServerError',\r\n message:\r\n typeof httpErrorPayload === 'string' && httpErrorPayload.trim()\r\n ? httpErrorPayload // Se è presente l'HTML o del testo reale del server, viene utilizzato questo\r\n : defaultMessage, // Se il corpo della risposta è vuoto, viene usato il messaggio di sicurezza\r\n stackTrace: errorTracker.stack ?? '',\r\n };\r\n throw new UniHttpError('server', res.status, url, fallbackException);\r\n } catch (error: unknown) {\r\n // ERRORE CON/SENZA STATUS: già gestito, rilancio diretto.\r\n // Se l'errore è un'istanza di UniHttpError (lanciata nei blocchi superiori per 'be' o 'server'), significa che è già stata catalogata correttamente.\r\n // Viene eseguito il rilancio diretto.\r\n if (error instanceof UniHttpError) {\r\n throw error;\r\n }\r\n\r\n // ERRORE SENZA STATUS, CASO A: errore di rete locale ('network')\r\n // Si verifica solo se la fetch() fallisce prima di stabilire un contatto con il server.\r\n // Il browser solleva un 'TypeError' (es. \"Failed to fetch\").\r\n if (error instanceof TypeError) {\r\n const fallbackException: ExceptionHttp = {\r\n isBe: false,\r\n type: error.name || 'NetworkError',\r\n message: error.message,\r\n stackTrace: error.stack ?? '',\r\n };\r\n throw new UniHttpError('network', 0, url, fallbackException);\r\n }\r\n\r\n // ERRORE SENZA STATUS, CASO B: errore frontend ('fe')\r\n // Qualsiasi altro errore imprevisto che non derivi da un fallimento della fetch o della risposta.\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function executeHttp<T>(url: URL, init?: RequestInit): Promise<T | undefined> {\r\n /* Esegue la chiamata HTTP e restituisce il corpo decodificato come JSON */\r\n const res = await execute(url, init);\r\n if (!res) return undefined;\r\n\r\n /* Estrae il contenuto come testo */\r\n const text = await res.text();\r\n\r\n /* Controllo: se il testo è vuoto (''), ritorna undefined */\r\n if (!text || text.trim().length === 0) {\r\n return undefined;\r\n }\r\n\r\n /* Parsa manualmente il testo, dato che lo stream è stato già letto */\r\n return JSON.parse(text) as T;\r\n}\r\n\r\nexport async function executeBlob(\r\n url: URL,\r\n init?: RequestInit,\r\n): Promise<FileDatasource | undefined> {\r\n /* Esegue la chiamata HTTP */\r\n const res = await execute(url, init);\r\n if (!res) return undefined;\r\n\r\n /* Estrae il contenuto come Blob direttamente */\r\n const blob = await res.blob();\r\n\r\n /* Controllo: se il blob è vuoto (0 byte), ritorna undefined */\r\n if (blob.size === 0) {\r\n return undefined;\r\n }\r\n\r\n /* Estrae il nome del file dall'header */\r\n const disposition = res.headers.get('Content-Disposition');\r\n let fileName = 'download.pdf'; // Fallback di default\r\n if (disposition) {\r\n const matches = /filename[^;=\\n]*=((['\"]).*?\\2|[^;\\n]*)/.exec(disposition);\r\n if (!!matches && matches[1]) {\r\n fileName = matches[1].replaceAll(/['\"]/g, '');\r\n }\r\n }\r\n\r\n /* Genera l'URL temporaneo dal blob */\r\n const fileUrl = URL.createObjectURL(blob);\r\n\r\n return { url: fileUrl, name: fileName };\r\n}\r\n","import { UniTypeDateManager } from 'uni-manager/type';\r\nimport type { HttpBody, HttpConfig } from 'uni-model-type/type';\r\n\r\n/**\r\n * Costruisce un URL completo per l'API partendo dai parametri di configurazione.\r\n */\r\nexport function getUrl<T>(hostname: string, port: number, config: HttpConfig<T>): URL {\r\n const { pathParams, path, hasApiPrefix } = config;\r\n\r\n // Costruzione url\r\n const cleanPath = path.replaceAll(/^\\/+|\\/+$/g, '');\r\n const segments = [hasApiPrefix === false ? '' : 'api', cleanPath].filter(Boolean);\r\n const pathFixed = '/' + segments.join('/');\r\n const url = new URL(pathFixed, `http://${hostname}:${port}`);\r\n\r\n if (pathParams) {\r\n // Regex per intercettare stringhe in formato ISO string\r\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})?)?$/;\r\n\r\n for (const [key, rawValue] of Object.entries(pathParams)) {\r\n if (rawValue === undefined || rawValue === null) {\r\n continue;\r\n }\r\n\r\n // Conversione in array per usare un solo ciclo\r\n const valuesArray = Array.isArray(rawValue) ? rawValue : [rawValue];\r\n\r\n for (const item of valuesArray) {\r\n if (item === undefined || item === null) {\r\n continue;\r\n }\r\n\r\n let formattedValue: string;\r\n\r\n // Caso: Date nativo\r\n if (item instanceof Date) {\r\n formattedValue = UniTypeDateManager.toYYYYMMDD(item);\r\n }\r\n // Caso: Date formato ISO string\r\n else if (typeof item === 'string' && isoDateRegex.test(item)) {\r\n const parsedDate = new Date(item);\r\n formattedValue = Number.isNaN(parsedDate.getTime())\r\n ? item\r\n : UniTypeDateManager.toYYYYMMDD(parsedDate);\r\n }\r\n // Default\r\n else {\r\n formattedValue = String(item);\r\n }\r\n\r\n url.searchParams.append(key, formattedValue);\r\n }\r\n }\r\n }\r\n\r\n return url;\r\n}\r\n\r\n/**\r\n * Normalizza i valori del body cosi da sistemare le incongruenze tra ui e db\r\n */\r\nexport function normalizeHttpBody<T extends HttpBody>(body: T, isRoot = true): T {\r\n // PRIMITIVI GENERICI\r\n // Tipi gestiti: null, undefined, number, boolean, symbol, bigint, string\r\n if (body === null || typeof body !== 'object') {\r\n // Sotto-gestione specifica per il tipo: string\r\n if (typeof body === 'string') {\r\n return body.trim() as T;\r\n }\r\n return body;\r\n }\r\n\r\n // DATE\r\n // Tipi gestiti: Date\r\n // Formattazione esplicita manuale in YYYY-MM-DD\r\n if (body instanceof Date) {\r\n const year = body.getFullYear();\r\n const month = String(body.getMonth() + 1).padStart(2, '0');\r\n const day = String(body.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${day}` as unknown as T;\r\n }\r\n\r\n // STRUTTURE DATI ITERABILI\r\n // Tipi gestiti: Array (qualsiasi array, es. string[], number[], Object[])\r\n // Se è un array, viene mappato ricorsivamente ogni singolo elemento al suo interno (passando isRoot = false perché gli elementi dell'array non sono l'oggetto root principale)\r\n if (Array.isArray(body)) {\r\n return body.map((item) => normalizeHttpBody(item, false)) as unknown as T;\r\n }\r\n\r\n // OGGETTI\r\n // Tipi gestiti: Record<string, any>, generici oggetti JavaScript ({ })\r\n // Rimuove chiave 'id' al primo livello e prosegue ricorsivamente\r\n const entries = Object.entries(body)\r\n .filter(([key]) => !(isRoot && key.toLowerCase() === 'id'))\r\n .map(([key, value]) => [key, normalizeHttpBody(value, false)]);\r\n\r\n // Ricostruisce l'oggetto normalizzato\r\n return Object.fromEntries(entries) as T;\r\n}\r\n","import { BehaviorSubject, Observable, distinctUntilChanged, map, tap } from 'rxjs';\r\nimport { UniToastManager } from 'uni-manager/toast';\r\nimport type {\r\n FileDatasource,\r\n HttpBody,\r\n HttpConfig,\r\n HttpConfigPolling,\r\n HttpRef,\r\n ToastConfig,\r\n} from 'uni-model-type/type';\r\n\r\nimport { http$, httpPolling$ } from './core';\r\nimport { executeBlob, executeHttp } from './execute';\r\nimport { getUrl, normalizeHttpBody } from './util';\r\n\r\nconst CONFIG_TOAST_DEFAULT: ToastConfig = {\r\n type: 'success',\r\n label: 'OperationCompleted',\r\n};\r\n\r\nexport class UniHttpManager {\r\n /* ------------------------------------------------------------------------------- */\r\n /* ----------------------------------- Config ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Hostname del server (es. 'api.example.com' o 'localhost') */\r\n private static hostname: string;\r\n\r\n /** Porta del server su cui effettuare le chiamate (es. 80, 443 o 3000) */\r\n private static port: number;\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* --------------------------------- Metodi: get --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Restituisce se lo store ha chiamate in attesa di risposta o meno */\r\n public static get hasWaitingRequests$(): Observable<boolean> {\r\n return this.store$.pipe(\r\n map((requestMap) => {\r\n for (const request of requestMap.values()) {\r\n if (request.pendingCount > 0) return true;\r\n }\r\n return false;\r\n }),\r\n distinctUntilChanged(),\r\n );\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ------------------------------------ Store ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Store privato (Subject) */\r\n public static store = new BehaviorSubject<Map<string, HttpRef>>(new Map());\r\n\r\n /** Store pubblico (Observable) */\r\n public static store$: Observable<Map<string, HttpRef>> = this.store.asObservable();\r\n\r\n /** Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable */\r\n public static get currentValue(): Map<string, HttpRef> {\r\n return this.store.getValue();\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: setup -------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Inizializza la configurazione di rete del manager.\r\n * Deve essere chiamato prima di effettuare qualsiasi richiesta HTTP.\r\n */\r\n public static setup(hostname: string, port: number): void {\r\n this.hostname = hostname;\r\n this.port = port;\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: CRUD --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /*\r\n * Esegue una singola richiesta HTTP GET.\r\n * Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.\r\n */\r\n public static read$<T>(config: HttpConfig<T>): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'GET',\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'one', config, () => executeHttp<T>(url, initCustom)).pipe(\r\n tap((res) => {\r\n if (Array.isArray(res) && config.toast === undefined) {\r\n UniToastManager.show({\r\n label: 'ItemsFound',\r\n params: { count: res.length },\r\n });\r\n }\r\n }),\r\n );\r\n }\r\n\r\n /**\r\n * Esegue una richiesta HTTP POST inviando un payload JSON nel corpo della richiesta.\r\n * Imposta automaticamente l'header 'Content-Type' come 'application/json'.\r\n */\r\n public static create$<T>(config: HttpConfig<T>, body: HttpBody): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...config.init?.headers,\r\n },\r\n body: JSON.stringify(normalizeHttpBody(body)),\r\n };\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<T> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'one', configCustom, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Esegue una singola richiesta HTTP PUT per aggiornare una risorsa esistente.\r\n */\r\n public static update$<T>(config: HttpConfig<T>, body?: HttpBody): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = { ...config.init, method: 'PUT' };\r\n if (body !== undefined) {\r\n initCustom.headers = {\r\n 'Content-Type': 'application/json',\r\n ...config.init?.headers,\r\n };\r\n initCustom.body = JSON.stringify(normalizeHttpBody(body));\r\n }\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<T> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'one', configCustom, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Esegue una richiesta HTTP DELETE per rimuovere una risorsa.\r\n * Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.\r\n */\r\n public static delete$<T>(config: HttpConfig<T>): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'DELETE',\r\n };\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<T> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'one', configCustom, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------- Metodi: CRUD file/image ---------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Recupera un'immagine tramite una richiesta GET e la trasforma in un formato gestibile (es. Blob o Base64).\r\n * Delega la logica di conversione alla funzione executeImage.\r\n */\r\n public static readImage$(\r\n config: HttpConfig<FileDatasource>,\r\n ): Observable<FileDatasource | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'GET',\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'image', config, () => executeBlob(url, initCustom));\r\n }\r\n\r\n /**\r\n * Recupera un file (es. PDF) tramite una richiesta GET e restituisce un Object URL temporaneo.\r\n * Delega la logica di conversione alla funzione executeFile.\r\n */\r\n public static readFile$(\r\n config: HttpConfig<FileDatasource>,\r\n ): Observable<FileDatasource | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'GET',\r\n };\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<FileDatasource> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'file', configCustom, () => executeBlob(url, initCustom));\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ---------------------------- Metodi: CRUD polling ----------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Avvia un ciclo di polling basato su richieste GET.\r\n * Continua a emettere valori in base alla configurazione di intervallo definita in HttpConfigPolling.\r\n */\r\n public static readPolling$<T>(config: HttpConfigPolling<T>): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'GET',\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return httpPolling$(url, config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Avvia un ciclo di polling basato su richieste POST.\r\n * Invia il body specificato a ogni iterazione del ciclo.\r\n */\r\n public static createPolling$<T>(\r\n config: HttpConfigPolling<T>,\r\n body: HttpBody,\r\n ): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return httpPolling$(url, config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Avvia un ciclo di polling basato su richieste PUT.\r\n */\r\n public static updatePolling$<T>(\r\n config: HttpConfigPolling<T>,\r\n body?: HttpBody,\r\n ): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'PUT',\r\n };\r\n if (body !== undefined) {\r\n initCustom.headers = {\r\n ...initCustom.headers,\r\n 'Content-Type': 'application/json',\r\n };\r\n initCustom.body = JSON.stringify(body);\r\n }\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return httpPolling$(url, config, () => executeHttp<T>(url, initCustom));\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uni-manager-http.mjs","sources":["../../../projects/uni-manager/http/handler.ts","../../../projects/uni-manager/http/core.ts","../../../projects/uni-manager/http/execute.ts","../../../projects/uni-manager/http/util.ts","../../../projects/uni-manager/http/manager.ts","../../../projects/uni-manager/http/uni-manager-http.ts"],"sourcesContent":["import {\r\n EMPTY,\r\n Observable,\r\n OperatorFunction,\r\n concatMap,\r\n exhaustMap,\r\n mergeMap,\r\n of,\r\n switchMap,\r\n throwError,\r\n} from 'rxjs';\r\nimport { UniHttpError } from 'uni-error/http';\r\nimport { UniErrorManager } from 'uni-manager/error';\r\nimport { MapOperator, PollingErrorMode } from 'uni-model-type/enum';\r\n\r\nexport function operatorHandler<T>(\r\n operator: MapOperator,\r\n): (\r\n project: (value: number) => Observable<T | undefined>,\r\n) => OperatorFunction<number, T | undefined> {\r\n // Gestione della concorrenza in base al parametro\r\n switch (operator) {\r\n case MapOperator.EXHAUST_MAP: {\r\n return (project) => exhaustMap(project);\r\n }\r\n case MapOperator.CONCAT_MAP: {\r\n return (project) => concatMap(project);\r\n }\r\n case MapOperator.MERGE_MAP: {\r\n return (project) => mergeMap(project);\r\n }\r\n case MapOperator.SWITCH_MAP: {\r\n return (project) => switchMap(project);\r\n }\r\n }\r\n}\r\n\r\nexport function errorHandler(\r\n ref: string,\r\n err: unknown,\r\n errorMode: PollingErrorMode,\r\n): Observable<never> {\r\n // Controllo: sia effettivamente un errore di tipo 'UniHttpError'\r\n if (err instanceof UniHttpError) {\r\n switch (errorMode) {\r\n case PollingErrorMode.IGNORE: {\r\n return of();\r\n }\r\n case PollingErrorMode.SKIP: {\r\n return EMPTY;\r\n }\r\n case PollingErrorMode.IGNORE_WITH_ERROR: {\r\n UniErrorManager.add(ref, err);\r\n return of();\r\n }\r\n case PollingErrorMode.STOP: {\r\n UniErrorManager.add(ref, err);\r\n return throwError(() => err);\r\n }\r\n }\r\n } else {\r\n return throwError(() => err);\r\n }\r\n}\r\n","import isEqual from 'lodash-es/isEqual';\r\nimport {\r\n Observable,\r\n catchError,\r\n defer,\r\n distinctUntilChanged,\r\n finalize,\r\n from,\r\n tap,\r\n timer,\r\n} from 'rxjs';\r\nimport { UniErrorManager } from 'uni-manager/error';\r\nimport { UniToastManager } from 'uni-manager/toast';\r\nimport { EmitValueMode, MapOperator, PollingErrorMode } from 'uni-model-type/enum';\r\nimport type { HttpConfig, HttpConfigPolling, HttpRef } from 'uni-model-type/type';\r\n\r\nimport { errorHandler, operatorHandler } from './handler';\r\nimport { UniHttpManager } from './manager';\r\n\r\n/* ------------------------------------------------------------------------------- */\r\n/* -------------------------------- Funzioni Core RxJS -------------------------- */\r\n/* ------------------------------------------------------------------------------- */\r\n/**\r\n * Gestisce l'esecuzione e il ciclo di vita di una singola richiesta HTTP.\r\n * Si occupa della registrazione della reference, della gestione dei loader, dei toast di successo e dell'intercettazione degli errori.\r\n */\r\nexport function http$<T>(\r\n url: URL,\r\n refType: HttpRef['type'],\r\n config: HttpConfig<T>,\r\n promiseFactory: () => Promise<T | undefined>,\r\n): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const { ref, toast, hasLoader } = config;\r\n\r\n return defer(() => {\r\n const http$ = from(promiseFactory());\r\n return http$.pipe(\r\n tap({\r\n subscribe: () => {\r\n /* Creazione reference */\r\n add(ref, url, refType);\r\n\r\n /* Incrementa per il loader */\r\n if (hasLoader !== false) {\r\n updateIsLoading(ref, 1);\r\n }\r\n },\r\n unsubscribe: () => {\r\n /* Rimozione reference */\r\n remove(ref);\r\n },\r\n next: (res) => {\r\n /* Mostra toast (se presente) */\r\n if (toast) {\r\n UniToastManager.showHttp(toast, res);\r\n }\r\n },\r\n }),\r\n catchError((err) => {\r\n // Aggiorna la ref nella map\r\n updateHasError(ref, true);\r\n\r\n /* Gestione errore */\r\n return errorHandler(ref, err, PollingErrorMode.STOP);\r\n }),\r\n finalize(() => {\r\n /* Decrementa per il loader */\r\n if (hasLoader !== false) {\r\n updateIsLoading(ref, -1);\r\n }\r\n }),\r\n );\r\n });\r\n}\r\n\r\n/**\r\n * Avvia e coordina un ciclo di polling a intervalli regolari.\r\n * Gestisce la concorrenza tramite operatori RxJS configurabili, la rimozione dei popup, di errore nelle iterazioni successive e i comportamenti custom al primo avvio.\r\n */\r\nexport function httpPolling$<T>(\r\n url: URL,\r\n config: HttpConfigPolling<T>,\r\n promiseFactory: () => Promise<T | undefined>,\r\n): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const {\r\n interval,\r\n ref,\r\n operator = MapOperator.SWITCH_MAP,\r\n errorMode = PollingErrorMode.STOP,\r\n emitValueMode = EmitValueMode.ON_NEW_DATA,\r\n firstIteration,\r\n } = config;\r\n\r\n const timer$ = timer(0, interval);\r\n const source$ = timer$.pipe(\r\n tap({\r\n subscribe: () => {\r\n /* Creazione reference */\r\n add(ref, url, 'polling');\r\n },\r\n unsubscribe: () => {\r\n /* Rimozione reference */\r\n remove(ref);\r\n },\r\n }),\r\n operatorHandler<T>(operator)((index) => {\r\n /* Incrementa per il loader */\r\n if (index === 0 && firstIteration?.hasLoader !== false) {\r\n updateIsLoading(ref, 1);\r\n }\r\n\r\n return defer(() => {\r\n const http$ = from(promiseFactory());\r\n return http$.pipe(\r\n tap((res) => {\r\n /* Meccanismo di ripristino automatico: se il polling torna in salute, cancella l'errore dallo store e nasconde i relativi messaggi a schermo */\r\n if (errorMode === PollingErrorMode.IGNORE_WITH_ERROR) {\r\n updateHasError(ref, false);\r\n UniErrorManager.remove(ref);\r\n }\r\n\r\n /* Prima risposta */\r\n if (index === 0 && firstIteration?.toast) {\r\n UniToastManager.showHttp(firstIteration.toast, res);\r\n }\r\n }),\r\n catchError((err) => {\r\n // Aggiorna la ref nella map\r\n updateHasError(ref, true);\r\n\r\n /* Gestione errore */\r\n return errorHandler(ref, err, errorMode);\r\n }),\r\n finalize(() => {\r\n /* Decrementa per il loader */\r\n if (index === 0 && firstIteration?.hasLoader !== false) {\r\n updateIsLoading(ref, -1);\r\n }\r\n }),\r\n );\r\n });\r\n }),\r\n );\r\n\r\n return emitValueMode === EmitValueMode.ON_NEW_DATA\r\n ? source$.pipe(distinctUntilChanged((prev, cur) => isEqual(prev, cur)))\r\n : source$;\r\n}\r\n\r\n/* ------------------------------------------------------------------------------- */\r\n/* ------------------------------------ Utils ------------------------------------ */\r\n/* ------------------------------------------------------------------------------- */\r\n/**\r\n * Aggiunge una nuova ref nello store solo se non è già presente.\r\n * Se l'ID esiste già, l'operazione viene interrotta per preservare il dato originale.\r\n */\r\nfunction add(id: string, url: URL, type: HttpRef['type']): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentValue;\r\n\r\n // Controllo: se è presente l'item allora termina\r\n if (oldMap.get(id)) return;\r\n\r\n // Crea il nuovo oggetto\r\n const newItemMap: HttpRef = {\r\n type,\r\n lineId: undefined,\r\n url,\r\n hasError: false,\r\n pendingCount: 0,\r\n };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Rimuove un http ref tramite ID\r\n */\r\nfunction remove(id: string): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentValue;\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n if (!oldMap.has(id)) return;\r\n\r\n // Aggiorna store\r\n const newMap = new Map(oldMap);\r\n newMap.delete(id);\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Aggiorna il contatore delle chiamate pendenti per una specifica ref.\r\n * Incrementa o decrementa 'pendingCount' garantendo che non scenda mai sotto lo zero.\r\n * Se la ref non esiste, l'operazione viene ignorata.\r\n */\r\nfunction updateIsLoading(id: string, delta: -1 | 1): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentValue;\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n const oldItem = oldMap.get(id);\r\n if (!oldItem) return;\r\n\r\n // Aggiorna l'oggetto\r\n const newItemMap: HttpRef = {\r\n ...oldItem,\r\n pendingCount: Math.max(0, oldItem.pendingCount + delta),\r\n };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Aggiorna lo stato di errore per una specifica ref.\r\n * Se il valore di 'hasError' è identico a quello attuale o se la ref non esiste,\r\n * l'operazione viene interrotta per evitare aggiornamenti inutili.\r\n */\r\nfunction updateHasError(id: string, hasError: boolean): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentValue;\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n const oldItem = oldMap.get(id);\r\n if (!oldItem) return;\r\n\r\n // Controllo: se con lo stesso valore, salta\r\n if (oldItem.hasError === hasError) return;\r\n\r\n // Aggiorna l'oggetto\r\n const newItemMap: HttpRef = { ...oldItem, hasError };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n","import { isErrorResponse, UniHttpError } from 'uni-error/http';\r\nimport type { ErrorResponse, FileDatasource } from 'uni-model-type/type';\r\n\r\n/**\r\n * Esegue una richiesta HTTP nativa gestendo l'imbuto dei 4 casi d'errore.\r\n */\r\nasync function execute(url: URL, init: RequestInit): Promise<Response | undefined> {\r\n const startTime = performance.now();\r\n\r\n try {\r\n /* Esecuzione della richiesta HTTP nativa */\r\n const res = await fetch(url, init);\r\n\r\n /* Calcolo durata */\r\n const durationMs = Math.round(performance.now() - startTime);\r\n\r\n /* Gestione dello stato 204: chiamata andata a buon fine ma senza dati di ritorno */\r\n if (res.status === 204) {\r\n return undefined;\r\n }\r\n\r\n /* Gestione ok HTTP: chiamata andata a buon fine. Viene restituita la risposta al chiamante. */\r\n if (res.ok) {\r\n return res;\r\n }\r\n\r\n /* Gestione Errore HTTP: la chiamata è arrivata al server ma ha restituito uno stato 4xx o 5xx */\r\n let httpError: unknown;\r\n\r\n try {\r\n /* Clonazione della risposta per l'ispezione del payload senza consumare lo stream originale */\r\n const resClone = res.clone();\r\n\r\n /* Verifica se il formato è un JSON */\r\n const contentType = res.headers.get('content-type') ?? '';\r\n const isJson = contentType.startsWith('application/json');\r\n\r\n /* Estrazione del corpo dell'errore in base al formato rilevato */\r\n httpError = isJson ? await resClone.json() : await resClone.text();\r\n } catch {\r\n /* Fallback in caso di fallimento della clonazione o del parsing del testo */\r\n httpError = `Failed to parse error response body (Status: ${res.status})`;\r\n }\r\n\r\n // ERRORE CON STATUS, CASO A: errore applicativo backend ('be')\r\n // Se il payload estratto supera il controllo 'isHttpException', significa che la richiesta è stata elaborata dal codice C#, ha intercettato il GlobalExceptionHandler ed è ritornata come JSON strutturato.\r\n // Questo scenario si applica a qualsiasi codice (400, 404, 500, ecc.) purché sia formattato dal backend.\r\n if (isErrorResponse(httpError)) {\r\n const errorResponse = httpError;\r\n throw new UniHttpError({\r\n type: 'be',\r\n url,\r\n httpStatus: res.status,\r\n durationMs,\r\n userAgent: navigator.userAgent,\r\n queryParams: url.searchParams,\r\n init,\r\n error: errorResponse,\r\n });\r\n }\r\n\r\n // ERRORE CON STATUS, CASO B: errore infrastrutturale del server ('server')\r\n // Se l'esecuzione raggiunge questo punto, il server ha risposto con un errore (es. 404, 405, 502, 504) ma non ha restituito il JSON customizzato.\r\n // Rappresenta il blocco da parte del server web (IIS, Nginx, Proxy) che ha rifiutato la chiamata o ha risposto con una pagina HTML/Testo standard.\r\n // Di conseguenza, il flag 'isBe' deve essere impostato a false poiché non deriva dalla logica applicativa.\r\n const defaultMessage = `HTTP Error ${res.status}${res.statusText ? ` (${res.statusText})` : ''}`;\r\n const errorTracker = new Error(defaultMessage);\r\n const errorResponse: ErrorResponse = {\r\n exception: {\r\n isBe: false,\r\n type: 'ServerError',\r\n message:\r\n typeof httpError === 'string' && httpError.trim()\r\n ? httpError // Se è presente l'HTML o del testo reale del server, viene utilizzato questo\r\n : defaultMessage, // Se il corpo della risposta è vuoto, viene usato il messaggio di sicurezza\r\n stackTrace: errorTracker.stack ?? '',\r\n },\r\n innerException: null,\r\n };\r\n throw new UniHttpError({\r\n type: 'server',\r\n url,\r\n httpStatus: res.status,\r\n durationMs,\r\n userAgent: navigator.userAgent,\r\n queryParams: url.searchParams,\r\n init,\r\n error: errorResponse,\r\n });\r\n } catch (error: unknown) {\r\n // ERRORE CON/SENZA STATUS: già gestito, rilancio diretto.\r\n // Se l'errore è un'istanza di UniHttpError (lanciata nei blocchi superiori per 'be' o 'server'), significa che è già stata catalogata correttamente.\r\n // Viene eseguito il rilancio diretto.\r\n if (error instanceof UniHttpError) {\r\n throw error;\r\n }\r\n\r\n // ERRORE SENZA STATUS, CASO A: errore di rete locale ('network')\r\n // Si verifica solo se la fetch() fallisce prima di stabilire un contatto con il server.\r\n // Il browser solleva un 'TypeError' (es. \"Failed to fetch\").\r\n if (error instanceof TypeError) {\r\n const fallbackException: ErrorResponse = {\r\n exception: {\r\n isBe: false,\r\n type: error.name || 'NetworkError',\r\n message: error.message,\r\n stackTrace: error.stack ?? '',\r\n },\r\n innerException: null,\r\n };\r\n throw new UniHttpError({\r\n type: 'network',\r\n url,\r\n httpStatus: 0,\r\n durationMs: 0,\r\n userAgent: navigator.userAgent,\r\n queryParams: url.searchParams,\r\n init,\r\n error: fallbackException,\r\n });\r\n }\r\n\r\n // ERRORE SENZA STATUS, CASO B: errore frontend ('fe')\r\n // Qualsiasi altro errore imprevisto che non derivi da un fallimento della fetch o della risposta.\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function executeHttp<T>(url: URL, init: RequestInit): Promise<T | undefined> {\r\n /* Esegue la chiamata HTTP e restituisce il corpo decodificato come JSON */\r\n const res = await execute(url, init);\r\n if (!res) return undefined;\r\n\r\n /* Estrae il contenuto come testo */\r\n const text = await res.text();\r\n\r\n /* Controllo: se il testo è vuoto (''), ritorna undefined */\r\n if (!text || text.trim().length === 0) {\r\n return undefined;\r\n }\r\n\r\n /* Parsa manualmente il testo, dato che lo stream è stato già letto */\r\n return JSON.parse(text) as T;\r\n}\r\n\r\nexport async function executeBlob(\r\n url: URL,\r\n init: RequestInit,\r\n): Promise<FileDatasource | undefined> {\r\n /* Esegue la chiamata HTTP */\r\n const res = await execute(url, init);\r\n if (!res) return undefined;\r\n\r\n /* Estrae il contenuto come Blob direttamente */\r\n const blob = await res.blob();\r\n\r\n /* Controllo: se il blob è vuoto (0 byte), ritorna undefined */\r\n if (blob.size === 0) {\r\n return undefined;\r\n }\r\n\r\n /* Estrae il nome del file dall'header */\r\n const disposition = res.headers.get('Content-Disposition');\r\n let fileName = 'download.pdf'; // Fallback di default\r\n if (disposition) {\r\n const matches = /filename[^;=\\n]*=((['\"]).*?\\2|[^;\\n]*)/.exec(disposition);\r\n if (!!matches && matches[1]) {\r\n fileName = matches[1].replaceAll(/['\"]/g, '');\r\n }\r\n }\r\n\r\n /* Genera l'URL temporaneo dal blob */\r\n const fileUrl = URL.createObjectURL(blob);\r\n\r\n return { url: fileUrl, name: fileName };\r\n}\r\n","import { UniTypeDateManager } from 'uni-manager/type';\r\nimport type { HttpBody, HttpConfig } from 'uni-model-type/type';\r\n\r\n/**\r\n * Costruisce un URL completo per l'API partendo dai parametri di configurazione.\r\n */\r\nexport function getUrl<T>(hostname: string, port: number, config: HttpConfig<T>): URL {\r\n const { pathParams, path, hasApiPrefix } = config;\r\n\r\n // Costruzione url\r\n const cleanPath = path.replaceAll(/^\\/+|\\/+$/g, '');\r\n const segments = [hasApiPrefix === false ? '' : 'api', cleanPath].filter(Boolean);\r\n const pathFixed = '/' + segments.join('/');\r\n const url = new URL(pathFixed, `http://${hostname}:${port}`);\r\n\r\n if (pathParams) {\r\n // Regex per intercettare stringhe in formato ISO string\r\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})?)?$/;\r\n\r\n for (const [key, rawValue] of Object.entries(pathParams)) {\r\n if (rawValue === undefined || rawValue === null) {\r\n continue;\r\n }\r\n\r\n // Conversione in array per usare un solo ciclo\r\n const valuesArray = Array.isArray(rawValue) ? rawValue : [rawValue];\r\n\r\n for (const item of valuesArray) {\r\n if (item === undefined || item === null) {\r\n continue;\r\n }\r\n\r\n let formattedValue: string;\r\n\r\n // Caso: Date nativo\r\n if (item instanceof Date) {\r\n formattedValue = UniTypeDateManager.toYYYYMMDD(item);\r\n }\r\n // Caso: Date formato ISO string\r\n else if (typeof item === 'string' && isoDateRegex.test(item)) {\r\n const parsedDate = new Date(item);\r\n formattedValue = Number.isNaN(parsedDate.getTime())\r\n ? item\r\n : UniTypeDateManager.toYYYYMMDD(parsedDate);\r\n }\r\n // Default\r\n else {\r\n formattedValue = String(item);\r\n }\r\n\r\n url.searchParams.append(key, formattedValue);\r\n }\r\n }\r\n }\r\n\r\n return url;\r\n}\r\n\r\n/**\r\n * Normalizza i valori del body cosi da sistemare le incongruenze tra ui e db\r\n */\r\nexport function normalizeHttpBody<T extends HttpBody>(body: T, isRoot = true): T {\r\n // PRIMITIVI GENERICI\r\n // Tipi gestiti: null, undefined, number, boolean, symbol, bigint, string\r\n if (body === null || typeof body !== 'object') {\r\n // Sotto-gestione specifica per il tipo: string\r\n if (typeof body === 'string') {\r\n return body.trim() as T;\r\n }\r\n return body;\r\n }\r\n\r\n // DATE\r\n // Tipi gestiti: Date\r\n // Formattazione esplicita manuale in YYYY-MM-DD\r\n if (body instanceof Date) {\r\n const year = body.getFullYear();\r\n const month = String(body.getMonth() + 1).padStart(2, '0');\r\n const day = String(body.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${day}` as unknown as T;\r\n }\r\n\r\n // STRUTTURE DATI ITERABILI\r\n // Tipi gestiti: Array (qualsiasi array, es. string[], number[], Object[])\r\n // Se è un array, viene mappato ricorsivamente ogni singolo elemento al suo interno (passando isRoot = false perché gli elementi dell'array non sono l'oggetto root principale)\r\n if (Array.isArray(body)) {\r\n return body.map((item) => normalizeHttpBody(item, false)) as unknown as T;\r\n }\r\n\r\n // OGGETTI\r\n // Tipi gestiti: Record<string, any>, generici oggetti JavaScript ({ })\r\n // Rimuove chiave 'id' al primo livello e prosegue ricorsivamente\r\n const entries = Object.entries(body)\r\n .filter(([key]) => !(isRoot && key.toLowerCase() === 'id'))\r\n .map(([key, value]) => [key, normalizeHttpBody(value, false)]);\r\n\r\n // Ricostruisce l'oggetto normalizzato\r\n return Object.fromEntries(entries) as T;\r\n}\r\n","import { BehaviorSubject, Observable, distinctUntilChanged, map, tap } from 'rxjs';\r\nimport { UniToastManager } from 'uni-manager/toast';\r\nimport type {\r\n FileDatasource,\r\n HttpBody,\r\n HttpConfig,\r\n HttpConfigPolling,\r\n HttpRef,\r\n ToastConfig,\r\n} from 'uni-model-type/type';\r\n\r\nimport { http$, httpPolling$ } from './core';\r\nimport { executeBlob, executeHttp } from './execute';\r\nimport { getUrl, normalizeHttpBody } from './util';\r\n\r\nconst CONFIG_TOAST_DEFAULT: ToastConfig = {\r\n type: 'success',\r\n label: 'OperationCompleted',\r\n};\r\n\r\nexport class UniHttpManager {\r\n /* ------------------------------------------------------------------------------- */\r\n /* ----------------------------------- Config ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Hostname del server (es. 'api.example.com' o 'localhost') */\r\n private static hostname: string;\r\n\r\n /** Porta del server su cui effettuare le chiamate (es. 80, 443 o 3000) */\r\n private static port: number;\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* --------------------------------- Metodi: get --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Restituisce se lo store ha chiamate in attesa di risposta o meno */\r\n public static get hasWaitingRequests$(): Observable<boolean> {\r\n return this.store$.pipe(\r\n map((requestMap) => {\r\n for (const request of requestMap.values()) {\r\n if (request.pendingCount > 0) return true;\r\n }\r\n return false;\r\n }),\r\n distinctUntilChanged(),\r\n );\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ------------------------------------ Store ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Store privato (Subject) */\r\n public static store = new BehaviorSubject<Map<string, HttpRef>>(new Map());\r\n\r\n /** Store pubblico (Observable) */\r\n public static store$: Observable<Map<string, HttpRef>> = this.store.asObservable();\r\n\r\n /** Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable */\r\n public static get currentValue(): Map<string, HttpRef> {\r\n return this.store.getValue();\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: setup -------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Inizializza la configurazione di rete del manager.\r\n * Deve essere chiamato prima di effettuare qualsiasi richiesta HTTP.\r\n */\r\n public static setup(hostname: string, port: number): void {\r\n this.hostname = hostname;\r\n this.port = port;\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: CRUD --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /*\r\n * Esegue una singola richiesta HTTP GET.\r\n * Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.\r\n */\r\n public static read$<T>(config: HttpConfig<T>): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'GET',\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'one', config, () => executeHttp<T>(url, initCustom)).pipe(\r\n tap((res) => {\r\n if (Array.isArray(res) && config.toast === undefined) {\r\n UniToastManager.show({\r\n label: 'ItemsFound',\r\n params: { count: res.length },\r\n });\r\n }\r\n }),\r\n );\r\n }\r\n\r\n /**\r\n * Esegue una richiesta HTTP POST inviando un payload JSON nel corpo della richiesta.\r\n * Imposta automaticamente l'header 'Content-Type' come 'application/json'.\r\n */\r\n public static create$<T>(config: HttpConfig<T>, body: HttpBody): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...config.init?.headers,\r\n },\r\n body: JSON.stringify(normalizeHttpBody(body)),\r\n };\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<T> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'one', configCustom, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Esegue una singola richiesta HTTP PUT per aggiornare una risorsa esistente.\r\n */\r\n public static update$<T>(config: HttpConfig<T>, body?: HttpBody): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = { ...config.init, method: 'PUT' };\r\n if (body !== undefined) {\r\n initCustom.headers = {\r\n 'Content-Type': 'application/json',\r\n ...config.init?.headers,\r\n };\r\n initCustom.body = JSON.stringify(normalizeHttpBody(body));\r\n }\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<T> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'one', configCustom, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Esegue una richiesta HTTP DELETE per rimuovere una risorsa.\r\n * Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.\r\n */\r\n public static delete$<T>(config: HttpConfig<T>): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'DELETE',\r\n };\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<T> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'one', configCustom, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------- Metodi: CRUD file/image ---------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Recupera un'immagine tramite una richiesta GET e la trasforma in un formato gestibile (es. Blob o Base64).\r\n * Delega la logica di conversione alla funzione executeImage.\r\n */\r\n public static readImage$(\r\n config: HttpConfig<FileDatasource>,\r\n ): Observable<FileDatasource | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'GET',\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'image', config, () => executeBlob(url, initCustom));\r\n }\r\n\r\n /**\r\n * Recupera un file (es. PDF) tramite una richiesta GET e restituisce un Object URL temporaneo.\r\n * Delega la logica di conversione alla funzione executeFile.\r\n */\r\n public static readFile$(\r\n config: HttpConfig<FileDatasource>,\r\n ): Observable<FileDatasource | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'GET',\r\n };\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<FileDatasource> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return http$(url, 'file', configCustom, () => executeBlob(url, initCustom));\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ---------------------------- Metodi: CRUD polling ----------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Avvia un ciclo di polling basato su richieste GET.\r\n * Continua a emettere valori in base alla configurazione di intervallo definita in HttpConfigPolling.\r\n */\r\n public static readPolling$<T>(config: HttpConfigPolling<T>): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'GET',\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return httpPolling$(url, config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Avvia un ciclo di polling basato su richieste POST.\r\n * Invia il body specificato a ogni iterazione del ciclo.\r\n */\r\n public static createPolling$<T>(\r\n config: HttpConfigPolling<T>,\r\n body: HttpBody,\r\n ): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n };\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return httpPolling$(url, config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Avvia un ciclo di polling basato su richieste PUT.\r\n */\r\n public static updatePolling$<T>(\r\n config: HttpConfigPolling<T>,\r\n body?: HttpBody,\r\n ): Observable<T | undefined> {\r\n /* Config */\r\n const initCustom: RequestInit = {\r\n ...config.init,\r\n method: 'PUT',\r\n };\r\n if (body !== undefined) {\r\n initCustom.headers = {\r\n ...initCustom.headers,\r\n 'Content-Type': 'application/json',\r\n };\r\n initCustom.body = JSON.stringify(body);\r\n }\r\n\r\n /* API */\r\n const url = getUrl(this.hostname, this.port, config);\r\n return httpPolling$(url, config, () => executeHttp<T>(url, initCustom));\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uni-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"lodash-es": ">=4.18.1",
|
|
6
6
|
"rxjs": ">=7.8.2",
|
|
7
|
-
"uni-
|
|
8
|
-
"uni-
|
|
7
|
+
"uni-model-type": ">=0.1.3",
|
|
8
|
+
"uni-error": ">=0.1.16"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"tslib": "^2.3.0"
|