uni-manager 0.1.25 → 0.1.26
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.
|
@@ -55,11 +55,11 @@ function errorHandler(ref, err, errorMode) {
|
|
|
55
55
|
* Gestisce l'esecuzione e il ciclo di vita di una singola richiesta HTTP.
|
|
56
56
|
* Si occupa della registrazione della reference, della gestione dei loader, dei toast di successo e dell'intercettazione degli errori.
|
|
57
57
|
*/
|
|
58
|
-
function http$(url, refType, config,
|
|
58
|
+
function http$(url, refType, config, promiseCallback) {
|
|
59
59
|
/* Recupero configurazione */
|
|
60
60
|
const { ref, toast, hasLoader } = config;
|
|
61
61
|
return defer(() => {
|
|
62
|
-
const http$ = from(
|
|
62
|
+
const http$ = from(promiseCallback());
|
|
63
63
|
return http$.pipe(tap({
|
|
64
64
|
subscribe: () => {
|
|
65
65
|
/* Creazione reference */
|
|
@@ -231,6 +231,9 @@ function updateHasError(id, hasError) {
|
|
|
231
231
|
UniHttpManager.store.next(newMap);
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
// =============================================================================
|
|
235
|
+
// MOTORE DI ESECUZIONE HTTP
|
|
236
|
+
// =============================================================================
|
|
234
237
|
/**
|
|
235
238
|
* Esegue una richiesta HTTP nativa gestendo l'imbuto dei 4 casi d'errore.
|
|
236
239
|
*/
|
|
@@ -242,10 +245,6 @@ async function execute(request) {
|
|
|
242
245
|
const res = await fetch(request);
|
|
243
246
|
/* Calcolo durata */
|
|
244
247
|
const durationMs = Math.round(performance.now() - startTime);
|
|
245
|
-
/* Gestione dello stato 204: chiamata andata a buon fine ma senza dati di ritorno */
|
|
246
|
-
if (res.status === 204) {
|
|
247
|
-
return undefined;
|
|
248
|
-
}
|
|
249
248
|
/* Gestione ok HTTP: chiamata andata a buon fine. Viene restituita la risposta al chiamante. */
|
|
250
249
|
if (res.ok) {
|
|
251
250
|
return res;
|
|
@@ -340,15 +339,16 @@ async function execute(request) {
|
|
|
340
339
|
}
|
|
341
340
|
}
|
|
342
341
|
async function executeHttp(request) {
|
|
343
|
-
/* Esegue la chiamata HTTP
|
|
342
|
+
/* Esegue la chiamata HTTP */
|
|
344
343
|
const res = await execute(request);
|
|
345
|
-
|
|
346
|
-
|
|
344
|
+
/* Gestione dello stato 204: chiamata andata a buon fine ma senza dati di ritorno */
|
|
345
|
+
if (res.status === 204)
|
|
346
|
+
return;
|
|
347
347
|
/* Estrae il contenuto come testo */
|
|
348
348
|
const text = await res.text();
|
|
349
|
-
/* Controllo: se il testo è vuoto ('')
|
|
349
|
+
/* Controllo: se il testo è vuoto ('') lancia errore */
|
|
350
350
|
if (!text || text.trim().length === 0) {
|
|
351
|
-
|
|
351
|
+
throw response204Error(request, res);
|
|
352
352
|
}
|
|
353
353
|
/* Parsa manualmente il testo, dato che lo stream è stato già letto */
|
|
354
354
|
return JSON.parse(text);
|
|
@@ -356,13 +356,14 @@ async function executeHttp(request) {
|
|
|
356
356
|
async function executeBlob(request) {
|
|
357
357
|
/* Esegue la chiamata HTTP */
|
|
358
358
|
const res = await execute(request);
|
|
359
|
-
|
|
360
|
-
|
|
359
|
+
/* Gestione dello stato 204: chiamata andata a buon fine ma senza dati di ritorno */
|
|
360
|
+
if (res.status === 204)
|
|
361
|
+
return;
|
|
361
362
|
/* Estrae il contenuto come Blob direttamente */
|
|
362
363
|
const blob = await res.blob();
|
|
363
|
-
/* Controllo: se il blob è vuoto (0 byte)
|
|
364
|
+
/* Controllo: se il blob è vuoto (0 byte) lancia errore */
|
|
364
365
|
if (blob.size === 0) {
|
|
365
|
-
|
|
366
|
+
throw response204Error(request, res);
|
|
366
367
|
}
|
|
367
368
|
/* Estrae il nome del file dall'header */
|
|
368
369
|
const disposition = res.headers.get('Content-Disposition');
|
|
@@ -375,8 +376,32 @@ async function executeBlob(request) {
|
|
|
375
376
|
}
|
|
376
377
|
/* Genera l'URL temporaneo dal blob */
|
|
377
378
|
const fileUrl = URL.createObjectURL(blob);
|
|
379
|
+
setTimeout(() => {
|
|
380
|
+
URL.revokeObjectURL(fileUrl);
|
|
381
|
+
}, 60_000);
|
|
378
382
|
return { url: fileUrl, name: fileName };
|
|
379
383
|
}
|
|
384
|
+
// =============================================================================
|
|
385
|
+
// HELPERS
|
|
386
|
+
// =============================================================================
|
|
387
|
+
function response204Error(request, res) {
|
|
388
|
+
return new UniHttpError({
|
|
389
|
+
type: 'be',
|
|
390
|
+
request,
|
|
391
|
+
httpStatus: res.status,
|
|
392
|
+
durationMs: 0,
|
|
393
|
+
userAgent: navigator.userAgent,
|
|
394
|
+
error: {
|
|
395
|
+
exception: {
|
|
396
|
+
isBe: true,
|
|
397
|
+
type: 'ProtocolError',
|
|
398
|
+
message: 'Expected payload of type T, but received empty response.',
|
|
399
|
+
stackTrace: '',
|
|
400
|
+
},
|
|
401
|
+
innerException: null,
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
}
|
|
380
405
|
|
|
381
406
|
/**
|
|
382
407
|
* Costruisce un oggetto Request completo e standardizzato per l'API partendo dai parametri di configurazione.
|
|
@@ -435,10 +460,73 @@ function getRequest(hostname, port, config, defaultRequestInit) {
|
|
|
435
460
|
// Ritorna l'oggetto Request completo di URL formattato e init con tutte le proprietà standard del browser
|
|
436
461
|
return new Request(url, initCustom);
|
|
437
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
* Controlla che le chiavi degli oggetti nel body rispettino i tipi attesi:
|
|
465
|
+
* - Se terminano con 'timestamp' -> il valore deve essere number
|
|
466
|
+
* - Se terminano con 'date' o 'at' -> il valore deve essere un oggetto Date
|
|
467
|
+
* - Se iniziano con 'is', 'has', 'should', 'can' -> il valore deve essere boolean
|
|
468
|
+
* - Se terminano/corrispondono a 'id', 'count', 'qty', 'total' -> il valore deve essere number
|
|
469
|
+
*/
|
|
470
|
+
function validateHttpBody(body) {
|
|
471
|
+
// Gestione degli array: validazione ricorsiva di ciascun elemento
|
|
472
|
+
if (Array.isArray(body)) {
|
|
473
|
+
for (const item of body) {
|
|
474
|
+
validateHttpBody(item);
|
|
475
|
+
}
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
// Gestione degli oggetti
|
|
479
|
+
if (body !== null && typeof body === 'object' && !(body instanceof Date)) {
|
|
480
|
+
for (const [key, value] of Object.entries(body)) {
|
|
481
|
+
const lowerKey = key.toLowerCase();
|
|
482
|
+
// Controllo Timestamp: deve essere un numero positivo e una data valida
|
|
483
|
+
if (lowerKey.endsWith('timestamp') || lowerKey.endsWith('timestampms')) {
|
|
484
|
+
if (typeof value !== 'number' || Number.isNaN(value) || value < 0) {
|
|
485
|
+
throw new Error(`Validation failed: key "${key}" must be a valid positive number representing a timestamp.`);
|
|
486
|
+
}
|
|
487
|
+
// Verifica ulteriore se il timestamp è "ragionevole" (es. dopo il 1970 e prima del 3000)
|
|
488
|
+
const date = new Date(value);
|
|
489
|
+
if (Number.isNaN(date.getTime())) {
|
|
490
|
+
throw new TypeError(`Validation failed: key "${key}" does not represent a valid date.`);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
// Controllo Date: deve essere un'istanza valida di Date
|
|
494
|
+
if (lowerKey.endsWith('date') || lowerKey.endsWith('at')) {
|
|
495
|
+
const isDateInstance = value instanceof Date && !Number.isNaN(value.getTime());
|
|
496
|
+
if (!isDateInstance) {
|
|
497
|
+
throw new Error(`Validation failed: key "${key}" must be a valid Date object.`);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
// Controllo Booleani: chiavi che iniziano con prefissi logici
|
|
501
|
+
// Generale: prefisso seguito da maiuscola (es: 'isActive' passa, 'islandName' (i minuscola) viene ignorato)
|
|
502
|
+
const isBooleanPattern = /^(is|has|should|can)[A-Z]/;
|
|
503
|
+
if (isBooleanPattern.test(key) && typeof value !== 'boolean') {
|
|
504
|
+
throw new Error(`Validation failed: key "${key}" must be a boolean.`);
|
|
505
|
+
}
|
|
506
|
+
// Controllo Numerico
|
|
507
|
+
if ((lowerKey === 'id' ||
|
|
508
|
+
lowerKey.endsWith('id') ||
|
|
509
|
+
lowerKey.endsWith('count') ||
|
|
510
|
+
lowerKey.endsWith('qty') ||
|
|
511
|
+
lowerKey.endsWith('total')) &&
|
|
512
|
+
typeof value !== 'number') {
|
|
513
|
+
throw new Error(`Validation failed: key "${key}" must be a number.`);
|
|
514
|
+
}
|
|
515
|
+
// Analisi ricorsiva per la verifica di eventuali sotto-oggetti o sotto-array
|
|
516
|
+
validateHttpBody(value);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
438
520
|
/**
|
|
439
521
|
* Normalizza i valori del body così da sistemare le incongruenze tra ui e db
|
|
522
|
+
* - Applica il trim alle stringhe
|
|
523
|
+
* - Converte gli oggetti Date in stringhe YYYY-MM-DD
|
|
524
|
+
* - Rimuove la proprietà 'id' se presente al livello principale (root).
|
|
440
525
|
*/
|
|
441
|
-
function normalizeHttpBody(body, isRoot = true
|
|
526
|
+
function normalizeHttpBody(body, method, isRoot = true) {
|
|
527
|
+
if (isRoot) {
|
|
528
|
+
validateHttpBody(body);
|
|
529
|
+
}
|
|
442
530
|
// PRIMITIVI GENERICI
|
|
443
531
|
// Tipi gestiti: null, undefined, number, boolean, symbol, bigint, string
|
|
444
532
|
if (body === null || typeof body !== 'object') {
|
|
@@ -451,12 +539,6 @@ function normalizeHttpBody(body, isRoot = true, currentKey = '') {
|
|
|
451
539
|
// DATE
|
|
452
540
|
// Tipi gestiti: Date
|
|
453
541
|
if (body instanceof Date) {
|
|
454
|
-
const lowerKey = currentKey.toLowerCase();
|
|
455
|
-
// Se la chiave finisce per timestamp, restituisce il valore numerico in millisecondi
|
|
456
|
-
if (lowerKey.endsWith('timestamp') || lowerKey.endsWith('timestampms')) {
|
|
457
|
-
return body.getTime();
|
|
458
|
-
}
|
|
459
|
-
// Altrimenti formattazione esplicita manuale in YYYY-MM-DD
|
|
460
542
|
const year = body.getFullYear();
|
|
461
543
|
const month = String(body.getMonth() + 1).padStart(2, '0');
|
|
462
544
|
const day = String(body.getDate()).padStart(2, '0');
|
|
@@ -466,15 +548,15 @@ function normalizeHttpBody(body, isRoot = true, currentKey = '') {
|
|
|
466
548
|
// Tipi gestiti: Array (qualsiasi array, es. string[], number[], Object[])
|
|
467
549
|
// 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)
|
|
468
550
|
if (Array.isArray(body)) {
|
|
469
|
-
return body.map((item) => normalizeHttpBody(item,
|
|
551
|
+
return body.map((item) => normalizeHttpBody(item, method, false));
|
|
470
552
|
}
|
|
471
553
|
// OGGETTI
|
|
472
554
|
// Tipi gestiti: Record<string, any>, generici oggetti JavaScript ({ })
|
|
473
|
-
//
|
|
555
|
+
// Rimozione della chiave 'id' al primo livello (root) e prosegue ricorsivamente
|
|
474
556
|
const entries = Object.entries(body)
|
|
475
|
-
.filter(([key]) => !(isRoot && key.toLowerCase() === 'id'))
|
|
476
|
-
.map(([key, value]) => [key, normalizeHttpBody(value,
|
|
477
|
-
//
|
|
557
|
+
.filter(([key]) => !(method === 'post' && isRoot && key.toLowerCase() === 'id'))
|
|
558
|
+
.map(([key, value]) => [key, normalizeHttpBody(value, method, false)]);
|
|
559
|
+
// Ricostruzione dell'oggetto normalizzato
|
|
478
560
|
return Object.fromEntries(entries);
|
|
479
561
|
}
|
|
480
562
|
|
|
@@ -512,22 +594,16 @@ class UniHttpManager {
|
|
|
512
594
|
this.hostname = hostname;
|
|
513
595
|
this.port = port;
|
|
514
596
|
}
|
|
515
|
-
/* ------------------------------------------------------------------------------- */
|
|
516
|
-
/* -------------------------------- Metodi: CRUD --------------------------------- */
|
|
517
|
-
/* ------------------------------------------------------------------------------- */
|
|
518
|
-
/*
|
|
519
|
-
* Esegue una singola richiesta HTTP GET.
|
|
520
|
-
* Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.
|
|
521
|
-
*/
|
|
522
597
|
static read$(config) {
|
|
523
598
|
/* Config */
|
|
524
599
|
const defaultRequestInit = {
|
|
525
600
|
method: 'GET',
|
|
526
601
|
};
|
|
602
|
+
// const a = this.create$(config, { id: 4 });
|
|
527
603
|
const request = getRequest(this.hostname, this.port, config, defaultRequestInit);
|
|
528
604
|
/* API */
|
|
529
605
|
return http$(request.url, 'one', config, () => executeHttp(request)).pipe(tap((res) => {
|
|
530
|
-
if (Array.isArray(res) && config.toast === undefined) {
|
|
606
|
+
if (Array.isArray(res) && config.hasToast && config.toast === undefined) {
|
|
531
607
|
UniToastManager.show({
|
|
532
608
|
label: 'ItemsFound',
|
|
533
609
|
params: { count: res.length },
|
|
@@ -535,10 +611,6 @@ class UniHttpManager {
|
|
|
535
611
|
}
|
|
536
612
|
}));
|
|
537
613
|
}
|
|
538
|
-
/**
|
|
539
|
-
* Esegue una richiesta HTTP POST inviando un payload JSON nel corpo della richiesta.
|
|
540
|
-
* Imposta automaticamente l'header 'Content-Type' come 'application/json'.
|
|
541
|
-
*/
|
|
542
614
|
static create$(config, body) {
|
|
543
615
|
/* Config */
|
|
544
616
|
const defaultRequestInit = {
|
|
@@ -548,7 +620,7 @@ class UniHttpManager {
|
|
|
548
620
|
'Content-Type': 'application/json',
|
|
549
621
|
...config.init?.headers,
|
|
550
622
|
},
|
|
551
|
-
body: JSON.stringify(normalizeHttpBody(body)),
|
|
623
|
+
body: JSON.stringify(normalizeHttpBody(body, 'post')),
|
|
552
624
|
};
|
|
553
625
|
const request = getRequest(this.hostname, this.port, config, defaultRequestInit);
|
|
554
626
|
/* Config custom (toast di default) */
|
|
@@ -559,9 +631,6 @@ class UniHttpManager {
|
|
|
559
631
|
/* API */
|
|
560
632
|
return http$(request.url, 'one', configCustom, () => executeHttp(request));
|
|
561
633
|
}
|
|
562
|
-
/**
|
|
563
|
-
* Esegue una singola richiesta HTTP PUT per aggiornare una risorsa esistente.
|
|
564
|
-
*/
|
|
565
634
|
static update$(config, body) {
|
|
566
635
|
/* Config */
|
|
567
636
|
const defaultRequestInit = { method: 'PUT' };
|
|
@@ -570,7 +639,7 @@ class UniHttpManager {
|
|
|
570
639
|
'Content-Type': 'application/json',
|
|
571
640
|
...config.init?.headers,
|
|
572
641
|
};
|
|
573
|
-
defaultRequestInit.body = JSON.stringify(normalizeHttpBody(body));
|
|
642
|
+
defaultRequestInit.body = JSON.stringify(normalizeHttpBody(body, 'put'));
|
|
574
643
|
}
|
|
575
644
|
const request = getRequest(this.hostname, this.port, config, defaultRequestInit);
|
|
576
645
|
/* Config custom (toast di default) */
|
|
@@ -581,10 +650,6 @@ class UniHttpManager {
|
|
|
581
650
|
/* API */
|
|
582
651
|
return http$(request.url, 'one', configCustom, () => executeHttp(request));
|
|
583
652
|
}
|
|
584
|
-
/**
|
|
585
|
-
* Esegue una richiesta HTTP DELETE per rimuovere una risorsa.
|
|
586
|
-
* Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.
|
|
587
|
-
*/
|
|
588
653
|
static delete$(config) {
|
|
589
654
|
/* Config */
|
|
590
655
|
const defaultRequestInit = {
|
|
@@ -633,13 +698,6 @@ class UniHttpManager {
|
|
|
633
698
|
/* API */
|
|
634
699
|
return http$(request.url, 'file', configCustom, () => executeBlob(request));
|
|
635
700
|
}
|
|
636
|
-
/* ------------------------------------------------------------------------------- */
|
|
637
|
-
/* ---------------------------- Metodi: CRUD polling ----------------------------- */
|
|
638
|
-
/* ------------------------------------------------------------------------------- */
|
|
639
|
-
/**
|
|
640
|
-
* Avvia un ciclo di polling basato su richieste GET.
|
|
641
|
-
* Continua a emettere valori in base alla configurazione di intervallo definita in HttpConfigPolling.
|
|
642
|
-
*/
|
|
643
701
|
static readPolling$(config) {
|
|
644
702
|
/* Config */
|
|
645
703
|
const defaultRequestInit = {
|
|
@@ -649,24 +707,17 @@ class UniHttpManager {
|
|
|
649
707
|
/* API */
|
|
650
708
|
return httpPolling$(request.url, config, () => executeHttp(request));
|
|
651
709
|
}
|
|
652
|
-
/**
|
|
653
|
-
* Avvia un ciclo di polling basato su richieste POST.
|
|
654
|
-
* Invia il body specificato a ogni iterazione del ciclo.
|
|
655
|
-
*/
|
|
656
710
|
static createPolling$(config, body) {
|
|
657
711
|
/* Config */
|
|
658
712
|
const defaultRequestInit = {
|
|
659
713
|
method: 'POST',
|
|
660
714
|
headers: { 'Content-Type': 'application/json' },
|
|
661
|
-
body: JSON.stringify(normalizeHttpBody(body)),
|
|
715
|
+
body: JSON.stringify(normalizeHttpBody(body, 'post')),
|
|
662
716
|
};
|
|
663
717
|
const request = getRequest(this.hostname, this.port, config, defaultRequestInit);
|
|
664
718
|
/* API */
|
|
665
719
|
return httpPolling$(request.url, config, () => executeHttp(request));
|
|
666
720
|
}
|
|
667
|
-
/**
|
|
668
|
-
* Avvia un ciclo di polling basato su richieste PUT.
|
|
669
|
-
*/
|
|
670
721
|
static updatePolling$(config, body) {
|
|
671
722
|
/* Config */
|
|
672
723
|
const defaultRequestInit = {
|
|
@@ -677,7 +728,7 @@ class UniHttpManager {
|
|
|
677
728
|
'Content-Type': 'application/json',
|
|
678
729
|
...config.init?.headers,
|
|
679
730
|
};
|
|
680
|
-
defaultRequestInit.body = JSON.stringify(normalizeHttpBody(body));
|
|
731
|
+
defaultRequestInit.body = JSON.stringify(normalizeHttpBody(body, 'put'));
|
|
681
732
|
}
|
|
682
733
|
const request = getRequest(this.hostname, this.port, config, defaultRequestInit);
|
|
683
734
|
/* API */
|
|
@@ -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: string,\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, new URL(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: string,\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, new URL(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(request: Request): Promise<Response | undefined> {\r\n const startTime = performance.now();\r\n const requestClone = request.clone();\r\n\r\n try {\r\n /* Esecuzione della richiesta HTTP nativa */\r\n const res: Response | undefined = await fetch(request);\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 request: requestClone,\r\n httpStatus: res.status,\r\n durationMs,\r\n userAgent: navigator.userAgent,\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 request: requestClone,\r\n httpStatus: res.status,\r\n durationMs,\r\n userAgent: navigator.userAgent,\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 request: requestClone,\r\n httpStatus: 0,\r\n durationMs: 0,\r\n userAgent: navigator.userAgent,\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>(request: Request): Promise<T | undefined> {\r\n /* Esegue la chiamata HTTP e restituisce il corpo decodificato come JSON */\r\n const res = await execute(request);\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(request: Request): Promise<FileDatasource | undefined> {\r\n /* Esegue la chiamata HTTP */\r\n const res = await execute(request);\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 oggetto Request completo e standardizzato per l'API partendo dai parametri di configurazione.\r\n * Gestisce la composizione dell'URL, la formattazione delle date nei query parametri e il merge dell'init.\r\n */\r\nexport function getRequest<T>(\r\n hostname: string,\r\n port: number,\r\n config: HttpConfig<T>,\r\n defaultRequestInit: RequestInit,\r\n): Request {\r\n const { queryParams, path, hasApiPrefix } = config;\r\n\r\n // Rimuove eventuali barre iniziali o finali dal path per evitare doppi slash (es. //api//)\r\n const cleanPath = path.replaceAll(/^\\/+|\\/+$/g, '');\r\n\r\n // Inserisce il prefisso 'api' a meno che non sia esplicitamente disabilitato nel config\r\n const segments = [hasApiPrefix === false ? '' : 'api', cleanPath].filter(Boolean);\r\n const pathFixed = '/' + segments.join('/');\r\n\r\n // Generazione dell'oggetto URL nativo combinando la base (host+porta) e il path strutturato\r\n const url = new URL(pathFixed, `http://${hostname}:${port}`);\r\n\r\n // Aggiunta query params\r\n if (queryParams) {\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(queryParams)) {\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 in formato nativo -> Convertito in YYYY-MM-DD\r\n if (item instanceof Date) {\r\n formattedValue = UniTypeDateManager.toYYYYMMDD(item);\r\n }\r\n // Caso: Date in formato ISO string -> Parsato e convertito in YYYY-MM-DD\r\n else if (typeof item === 'string' && isoDateRegex.test(item)) {\r\n const parsedDate = new Date(item);\r\n // Se la stringa superava la regex ma la data non è valida -> fallback sulla stringa originale\r\n formattedValue = Number.isNaN(parsedDate.getTime())\r\n ? item\r\n : UniTypeDateManager.toYYYYMMDD(parsedDate);\r\n }\r\n // Caso: Default (Numeri, Booleani, Stringhe standard) -> Conversione a stringa pulita\r\n else {\r\n formattedValue = String(item);\r\n }\r\n\r\n // Appende il parametro formattato nell'URL\r\n url.searchParams.append(key, formattedValue);\r\n }\r\n }\r\n }\r\n\r\n // Unisce le configurazioni base registrate nel config dell'endpoint con quelle puntuali della singola chiamata\r\n const initCustom: RequestInit = {\r\n ...defaultRequestInit,\r\n ...config.init,\r\n };\r\n\r\n // Ritorna l'oggetto Request completo di URL formattato e init con tutte le proprietà standard del browser\r\n return new Request(url, initCustom);\r\n}\r\n\r\n/**\r\n * Normalizza i valori del body così da sistemare le incongruenze tra ui e db\r\n */\r\nexport function normalizeHttpBody<T extends HttpBody>(body: T, isRoot = true, currentKey = ''): 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 if (body instanceof Date) {\r\n const lowerKey = currentKey.toLowerCase();\r\n\r\n // Se la chiave finisce per timestamp, restituisce il valore numerico in millisecondi\r\n if (lowerKey.endsWith('timestamp') || lowerKey.endsWith('timestampms')) {\r\n return body.getTime() as unknown as T;\r\n }\r\n\r\n // Altrimenti formattazione esplicita manuale in YYYY-MM-DD\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, currentKey)) 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, key)]);\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 { getRequest, 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) => [...requestMap.values()].some((x) => x.pendingCount > 0)),\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 defaultRequestInit: RequestInit = {\r\n method: 'GET',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return http$(request.url, 'one', config, () => executeHttp<T>(request)).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 defaultRequestInit: 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 const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\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 return http$(request.url, 'one', configCustom, () => executeHttp<T>(request));\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 defaultRequestInit: RequestInit = { method: 'PUT' };\r\n if (body !== undefined) {\r\n defaultRequestInit.headers = {\r\n 'Content-Type': 'application/json',\r\n ...config.init?.headers,\r\n };\r\n defaultRequestInit.body = JSON.stringify(normalizeHttpBody(body));\r\n }\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\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 return http$(request.url, 'one', configCustom, () => executeHttp<T>(request));\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 defaultRequestInit: RequestInit = {\r\n method: 'DELETE',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\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 return http$(request.url, 'one', configCustom, () => executeHttp<T>(request));\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 defaultRequestInit: RequestInit = {\r\n method: 'GET',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return http$(request.url, 'image', config, () => executeBlob(request));\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 defaultRequestInit: RequestInit = {\r\n method: 'GET',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\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 return http$(request.url, 'file', configCustom, () => executeBlob(request));\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 defaultRequestInit: RequestInit = {\r\n method: 'GET',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return httpPolling$(request.url, config, () => executeHttp<T>(request));\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 defaultRequestInit: RequestInit = {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(normalizeHttpBody(body)),\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return httpPolling$(request.url, config, () => executeHttp<T>(request));\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 defaultRequestInit: RequestInit = {\r\n method: 'PUT',\r\n };\r\n if (body !== undefined) {\r\n defaultRequestInit.headers = {\r\n 'Content-Type': 'application/json',\r\n ...config.init?.headers,\r\n };\r\n defaultRequestInit.body = JSON.stringify(normalizeHttpBody(body));\r\n }\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return httpPolling$(request.url, config, () => executeHttp<T>(request));\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: string,\r\n refType: HttpRef['type'],\r\n config: HttpConfig<T>,\r\n promiseCallback: () => 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(promiseCallback());\r\n return http$.pipe(\r\n tap({\r\n subscribe: () => {\r\n /* Creazione reference */\r\n add(ref, new URL(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: string,\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, new URL(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// MOTORE DI ESECUZIONE HTTP\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(request: Request): Promise<Response> {\r\n const startTime = performance.now();\r\n const requestClone = request.clone();\r\n\r\n try {\r\n /* Esecuzione della richiesta HTTP nativa */\r\n const res = await fetch(request);\r\n\r\n /* Calcolo durata */\r\n const durationMs = Math.round(performance.now() - startTime);\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 request: requestClone,\r\n httpStatus: res.status,\r\n durationMs,\r\n userAgent: navigator.userAgent,\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 request: requestClone,\r\n httpStatus: res.status,\r\n durationMs,\r\n userAgent: navigator.userAgent,\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 request: requestClone,\r\n httpStatus: 0,\r\n durationMs: 0,\r\n userAgent: navigator.userAgent,\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\n// =============================================================================\r\n// API PUBBLICHE: GESTIONE DATI E FILE\r\n// =============================================================================\r\nexport async function executeHttp(request: Request): Promise<void>;\r\nexport async function executeHttp<T>(request: Request): Promise<T>;\r\nexport async function executeHttp<T>(request: Request): Promise<T | void> {\r\n /* Esegue la chiamata HTTP */\r\n const res = await execute(request);\r\n\r\n /* Gestione dello stato 204: chiamata andata a buon fine ma senza dati di ritorno */\r\n if (res.status === 204) return;\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 ('') lancia errore */\r\n if (!text || text.trim().length === 0) {\r\n throw response204Error(request, res);\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(request: Request): Promise<FileDatasource | void> {\r\n /* Esegue la chiamata HTTP */\r\n const res = await execute(request);\r\n\r\n /* Gestione dello stato 204: chiamata andata a buon fine ma senza dati di ritorno */\r\n if (res.status === 204) return;\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) lancia errore */\r\n if (blob.size === 0) {\r\n throw response204Error(request, res);\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 setTimeout(() => {\r\n URL.revokeObjectURL(fileUrl);\r\n }, 60_000);\r\n\r\n return { url: fileUrl, name: fileName };\r\n}\r\n\r\n// =============================================================================\r\n// HELPERS\r\n// =============================================================================\r\nfunction response204Error(request: Request, res: Response): UniHttpError {\r\n return new UniHttpError({\r\n type: 'be',\r\n request,\r\n httpStatus: res.status,\r\n durationMs: 0,\r\n userAgent: navigator.userAgent,\r\n error: {\r\n exception: {\r\n isBe: true,\r\n type: 'ProtocolError',\r\n message: 'Expected payload of type T, but received empty response.',\r\n stackTrace: '',\r\n },\r\n innerException: null,\r\n },\r\n });\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 oggetto Request completo e standardizzato per l'API partendo dai parametri di configurazione.\r\n * Gestisce la composizione dell'URL, la formattazione delle date nei query parametri e il merge dell'init.\r\n */\r\nexport function getRequest<T>(\r\n hostname: string,\r\n port: number,\r\n config: HttpConfig<T>,\r\n defaultRequestInit: RequestInit,\r\n): Request {\r\n const { queryParams, path, hasApiPrefix } = config;\r\n\r\n // Rimuove eventuali barre iniziali o finali dal path per evitare doppi slash (es. //api//)\r\n const cleanPath = path.replaceAll(/^\\/+|\\/+$/g, '');\r\n\r\n // Inserisce il prefisso 'api' a meno che non sia esplicitamente disabilitato nel config\r\n const segments = [hasApiPrefix === false ? '' : 'api', cleanPath].filter(Boolean);\r\n const pathFixed = '/' + segments.join('/');\r\n\r\n // Generazione dell'oggetto URL nativo combinando la base (host+porta) e il path strutturato\r\n const url = new URL(pathFixed, `http://${hostname}:${port}`);\r\n\r\n // Aggiunta query params\r\n if (queryParams) {\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(queryParams)) {\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 in formato nativo -> Convertito in YYYY-MM-DD\r\n if (item instanceof Date) {\r\n formattedValue = UniTypeDateManager.toYYYYMMDD(item);\r\n }\r\n // Caso: Date in formato ISO string -> Parsato e convertito in YYYY-MM-DD\r\n else if (typeof item === 'string' && isoDateRegex.test(item)) {\r\n const parsedDate = new Date(item);\r\n // Se la stringa superava la regex ma la data non è valida -> fallback sulla stringa originale\r\n formattedValue = Number.isNaN(parsedDate.getTime())\r\n ? item\r\n : UniTypeDateManager.toYYYYMMDD(parsedDate);\r\n }\r\n // Caso: Default (Numeri, Booleani, Stringhe standard) -> Conversione a stringa pulita\r\n else {\r\n formattedValue = String(item);\r\n }\r\n\r\n // Appende il parametro formattato nell'URL\r\n url.searchParams.append(key, formattedValue);\r\n }\r\n }\r\n }\r\n\r\n // Unisce le configurazioni base registrate nel config dell'endpoint con quelle puntuali della singola chiamata\r\n const initCustom: RequestInit = {\r\n ...defaultRequestInit,\r\n ...config.init,\r\n };\r\n\r\n // Ritorna l'oggetto Request completo di URL formattato e init con tutte le proprietà standard del browser\r\n return new Request(url, initCustom);\r\n}\r\n\r\n/**\r\n * Controlla che le chiavi degli oggetti nel body rispettino i tipi attesi:\r\n * - Se terminano con 'timestamp' -> il valore deve essere number\r\n * - Se terminano con 'date' o 'at' -> il valore deve essere un oggetto Date\r\n * - Se iniziano con 'is', 'has', 'should', 'can' -> il valore deve essere boolean\r\n * - Se terminano/corrispondono a 'id', 'count', 'qty', 'total' -> il valore deve essere number\r\n */\r\nexport function validateHttpBody<T>(body: HttpBody<T>): void {\r\n // Gestione degli array: validazione ricorsiva di ciascun elemento\r\n if (Array.isArray(body)) {\r\n for (const item of body) {\r\n validateHttpBody(item);\r\n }\r\n return;\r\n }\r\n\r\n // Gestione degli oggetti\r\n if (body !== null && typeof body === 'object' && !(body instanceof Date)) {\r\n for (const [key, value] of Object.entries(body)) {\r\n const lowerKey = key.toLowerCase();\r\n\r\n // Controllo Timestamp: deve essere un numero positivo e una data valida\r\n if (lowerKey.endsWith('timestamp') || lowerKey.endsWith('timestampms')) {\r\n if (typeof value !== 'number' || Number.isNaN(value) || value < 0) {\r\n throw new Error(\r\n `Validation failed: key \"${key}\" must be a valid positive number representing a timestamp.`,\r\n );\r\n }\r\n // Verifica ulteriore se il timestamp è \"ragionevole\" (es. dopo il 1970 e prima del 3000)\r\n const date = new Date(value);\r\n if (Number.isNaN(date.getTime())) {\r\n throw new TypeError(`Validation failed: key \"${key}\" does not represent a valid date.`);\r\n }\r\n }\r\n\r\n // Controllo Date: deve essere un'istanza valida di Date\r\n if (lowerKey.endsWith('date') || lowerKey.endsWith('at')) {\r\n const isDateInstance = value instanceof Date && !Number.isNaN(value.getTime());\r\n if (!isDateInstance) {\r\n throw new Error(`Validation failed: key \"${key}\" must be a valid Date object.`);\r\n }\r\n }\r\n\r\n // Controllo Booleani: chiavi che iniziano con prefissi logici\r\n // Generale: prefisso seguito da maiuscola (es: 'isActive' passa, 'islandName' (i minuscola) viene ignorato)\r\n const isBooleanPattern = /^(is|has|should|can)[A-Z]/;\r\n if (isBooleanPattern.test(key) && typeof value !== 'boolean') {\r\n throw new Error(`Validation failed: key \"${key}\" must be a boolean.`);\r\n }\r\n\r\n // Controllo Numerico\r\n if (\r\n (lowerKey === 'id' ||\r\n lowerKey.endsWith('id') ||\r\n lowerKey.endsWith('count') ||\r\n lowerKey.endsWith('qty') ||\r\n lowerKey.endsWith('total')) &&\r\n typeof value !== 'number'\r\n ) {\r\n throw new Error(`Validation failed: key \"${key}\" must be a number.`);\r\n }\r\n\r\n // Analisi ricorsiva per la verifica di eventuali sotto-oggetti o sotto-array\r\n validateHttpBody(value);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Normalizza i valori del body così da sistemare le incongruenze tra ui e db\r\n * - Applica il trim alle stringhe\r\n * - Converte gli oggetti Date in stringhe YYYY-MM-DD\r\n * - Rimuove la proprietà 'id' se presente al livello principale (root).\r\n */\r\nexport function normalizeHttpBody<T>(\r\n body: HttpBody<T>,\r\n method: 'post' | 'put',\r\n isRoot = true,\r\n): unknown {\r\n if (isRoot) {\r\n validateHttpBody(body);\r\n }\r\n\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();\r\n }\r\n return body;\r\n }\r\n\r\n // DATE\r\n // Tipi gestiti: Date\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}`;\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, method, false));\r\n }\r\n\r\n // OGGETTI\r\n // Tipi gestiti: Record<string, any>, generici oggetti JavaScript ({ })\r\n // Rimozione della chiave 'id' al primo livello (root) e prosegue ricorsivamente\r\n const entries = Object.entries(body)\r\n .filter(([key]) => !(method === 'post' && isRoot && key.toLowerCase() === 'id'))\r\n .map(([key, value]) => [key, normalizeHttpBody(value, method, false)]);\r\n\r\n // Ricostruzione dell'oggetto normalizzato\r\n return Object.fromEntries(entries);\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 HttpBodyPrimitive,\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 { getRequest, 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) => [...requestMap.values()].some((x) => x.pendingCount > 0)),\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$(config: HttpConfig<void>): Observable<void>;\r\n public static read$<T>(config: HttpConfig<T>): Observable<T>;\r\n public static read$<T>(config: HttpConfig<T>): Observable<T | void> {\r\n /* Config */\r\n const defaultRequestInit: RequestInit = {\r\n method: 'GET',\r\n };\r\n // const a = this.create$(config, { id: 4 });\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return http$(request.url, 'one', config, () => executeHttp<T>(request)).pipe(\r\n tap((res) => {\r\n if (Array.isArray(res) && config.hasToast && 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$<TBody extends HttpBodyPrimitive>(\r\n config: HttpConfig<void>,\r\n body: HttpBody<TBody>,\r\n ): Observable<void>;\r\n public static create$<TResponse, TBody extends HttpBodyPrimitive>(\r\n config: HttpConfig<TResponse>,\r\n body: HttpBody<TBody>,\r\n ): Observable<TResponse>;\r\n public static create$<TResponse, TBody extends HttpBodyPrimitive>(\r\n config: HttpConfig<TResponse>,\r\n body: HttpBody<TBody>,\r\n ): Observable<TResponse | void> {\r\n /* Config */\r\n const defaultRequestInit: 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, 'post')),\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<TResponse> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n return http$(request.url, 'one', configCustom, () => executeHttp<TResponse>(request));\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$(config: HttpConfig<void>): Observable<void>;\r\n public static update$<TBody extends HttpBodyPrimitive>(\r\n config: HttpConfig<void>,\r\n body: HttpBody<TBody>,\r\n ): Observable<void>;\r\n public static update$<TResponse>(config: HttpConfig<TResponse>): Observable<TResponse>;\r\n public static update$<TResponse, TBody extends HttpBodyPrimitive>(\r\n config: HttpConfig<TResponse>,\r\n body: HttpBody<TBody>,\r\n ): Observable<TResponse>;\r\n public static update$<TResponse, TBody extends HttpBodyPrimitive>(\r\n config: HttpConfig<TResponse>,\r\n body?: HttpBody<TBody>,\r\n ): Observable<TResponse | void> {\r\n /* Config */\r\n const defaultRequestInit: RequestInit = { method: 'PUT' };\r\n if (body !== undefined) {\r\n defaultRequestInit.headers = {\r\n 'Content-Type': 'application/json',\r\n ...config.init?.headers,\r\n };\r\n defaultRequestInit.body = JSON.stringify(normalizeHttpBody(body, 'put'));\r\n }\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* Config custom (toast di default) */\r\n const configCustom: HttpConfig<TResponse> = {\r\n ...config,\r\n toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),\r\n };\r\n\r\n /* API */\r\n return http$(request.url, 'one', configCustom, () => executeHttp<TResponse>(request));\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$(config: HttpConfig<void>): Observable<void>;\r\n public static delete$<T>(config: HttpConfig<T>): Observable<T>;\r\n public static delete$<T>(config: HttpConfig<T>): Observable<T | void> {\r\n /* Config */\r\n const defaultRequestInit: RequestInit = {\r\n method: 'DELETE',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\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 return http$(request.url, 'one', configCustom, () => executeHttp<T>(request));\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$(config: HttpConfig<FileDatasource>): Observable<FileDatasource | void> {\r\n /* Config */\r\n const defaultRequestInit: RequestInit = {\r\n method: 'GET',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return http$(request.url, 'image', config, () => executeBlob(request));\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$(config: HttpConfig<FileDatasource>): Observable<FileDatasource | void> {\r\n /* Config */\r\n const defaultRequestInit: RequestInit = {\r\n method: 'GET',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\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 return http$(request.url, 'file', configCustom, () => executeBlob(request));\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$(config: HttpConfigPolling<void>): Observable<void>;\r\n public static readPolling$<T>(config: HttpConfigPolling<T>): Observable<T>;\r\n public static readPolling$<T>(config: HttpConfigPolling<T>): Observable<T | void> {\r\n /* Config */\r\n const defaultRequestInit: RequestInit = {\r\n method: 'GET',\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return httpPolling$(request.url, config, () => executeHttp<T>(request));\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$<TBody extends HttpBodyPrimitive>(\r\n config: HttpConfigPolling<void>,\r\n body: HttpBody<TBody>,\r\n ): Observable<void>;\r\n public static createPolling$<TResponse, TBody extends HttpBodyPrimitive>(\r\n config: HttpConfigPolling<TResponse>,\r\n body: HttpBody<TBody>,\r\n ): Observable<TResponse>;\r\n public static createPolling$<TResponse, TBody extends HttpBodyPrimitive>(\r\n config: HttpConfigPolling<TResponse>,\r\n body: HttpBody<TBody>,\r\n ): Observable<TResponse | void> {\r\n /* Config */\r\n const defaultRequestInit: RequestInit = {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(normalizeHttpBody(body, 'post')),\r\n };\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return httpPolling$(request.url, config, () => executeHttp<TResponse>(request));\r\n }\r\n\r\n /**\r\n * Avvia un ciclo di polling basato su richieste PUT.\r\n */\r\n public static updatePolling$(config: HttpConfigPolling<void>): Observable<void>;\r\n public static updatePolling$<TBody extends HttpBodyPrimitive>(\r\n config: HttpConfigPolling<void>,\r\n body: HttpBody<TBody>,\r\n ): Observable<void>;\r\n public static updatePolling$<TResponse>(\r\n config: HttpConfigPolling<TResponse>,\r\n ): Observable<TResponse>;\r\n public static updatePolling$<TResponse, TBody extends HttpBodyPrimitive>(\r\n config: HttpConfigPolling<TResponse>,\r\n body: HttpBody<TBody>,\r\n ): Observable<TResponse>;\r\n public static updatePolling$<TResponse, TBody extends HttpBodyPrimitive>(\r\n config: HttpConfigPolling<TResponse>,\r\n body?: HttpBody<TBody>,\r\n ): Observable<TResponse | void> {\r\n /* Config */\r\n const defaultRequestInit: RequestInit = {\r\n method: 'PUT',\r\n };\r\n if (body !== undefined) {\r\n defaultRequestInit.headers = {\r\n 'Content-Type': 'application/json',\r\n ...config.init?.headers,\r\n };\r\n defaultRequestInit.body = JSON.stringify(normalizeHttpBody(body, 'put'));\r\n }\r\n const request: Request = getRequest(this.hostname, this.port, config, defaultRequestInit);\r\n\r\n /* API */\r\n return httpPolling$(request.url, config, () => executeHttp<TResponse>(request));\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;AAeM,SAAU,eAAe,CAC7B,QAAqB,EAAA;;IAKrB,QAAQ,QAAQ;AACd,QAAA,KAAK,WAAW,CAAC,WAAW,EAAE;YAC5B,OAAO,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,CAAC;QACzC;AACA,QAAA,KAAK,WAAW,CAAC,UAAU,EAAE;YAC3B,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO,CAAC;QACxC;AACA,QAAA,KAAK,WAAW,CAAC,SAAS,EAAE;YAC1B,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO,CAAC;QACvC;AACA,QAAA,KAAK,WAAW,CAAC,UAAU,EAAE;YAC3B,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO,CAAC;QACxC;;AAEJ;SAEgB,YAAY,CAC1B,GAAW,EACX,GAAY,EACZ,SAA2B,EAAA;;AAG3B,IAAA,IAAI,GAAG,YAAY,YAAY,EAAE;QAC/B,QAAQ,SAAS;AACf,YAAA,KAAK,gBAAgB,CAAC,MAAM,EAAE;gBAC5B,OAAO,EAAE,EAAE;YACb;AACA,YAAA,KAAK,gBAAgB,CAAC,IAAI,EAAE;AAC1B,gBAAA,OAAO,KAAK;YACd;AACA,YAAA,KAAK,gBAAgB,CAAC,iBAAiB,EAAE;AACvC,gBAAA,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC;gBAC7B,OAAO,EAAE,EAAE;YACb;AACA,YAAA,KAAK,gBAAgB,CAAC,IAAI,EAAE;AAC1B,gBAAA,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC;AAC7B,gBAAA,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC;YAC9B;;IAEJ;SAAO;AACL,QAAA,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC;IAC9B;AACF;;AC5CA;AACA;AACA;AACA;;;AAGG;AACG,SAAU,KAAK,CACnB,GAAW,EACX,OAAwB,EACxB,MAAqB,EACrB,eAA6C,EAAA;;IAG7C,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM;IAExC,OAAO,KAAK,CAAC,MAAK;AAChB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;AACrC,QAAA,OAAO,KAAK,CAAC,IAAI,CACf,GAAG,CAAC;YACF,SAAS,EAAE,MAAK;;gBAEd,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;;AAG/B,gBAAA,IAAI,SAAS,KAAK,KAAK,EAAE;AACvB,oBAAA,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC;gBACzB;YACF,CAAC;YACD,WAAW,EAAE,MAAK;;gBAEhB,MAAM,CAAC,GAAG,CAAC;YACb,CAAC;AACD,YAAA,IAAI,EAAE,CAAC,GAAG,KAAI;;gBAEZ,IAAI,KAAK,EAAE;AACT,oBAAA,eAAe,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;gBACtC;YACF,CAAC;AACF,SAAA,CAAC,EACF,UAAU,CAAC,CAAC,GAAG,KAAI;;AAEjB,YAAA,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC;;YAGzB,OAAO,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,gBAAgB,CAAC,IAAI,CAAC;AACtD,QAAA,CAAC,CAAC,EACF,QAAQ,CAAC,MAAK;;AAEZ,YAAA,IAAI,SAAS,KAAK,KAAK,EAAE;AACvB,gBAAA,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC1B;QACF,CAAC,CAAC,CACH;AACH,IAAA,CAAC,CAAC;AACJ;AAEA;;;AAGG;SACa,YAAY,CAC1B,GAAW,EACX,MAA4B,EAC5B,cAA4C,EAAA;;IAG5C,MAAM,EACJ,QAAQ,EACR,GAAG,EACH,QAAQ,GAAG,WAAW,CAAC,UAAU,EACjC,SAAS,GAAG,gBAAgB,CAAC,IAAI,EACjC,aAAa,GAAG,aAAa,CAAC,WAAW,EACzC,cAAc,GACf,GAAG,MAAM;IAEV,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;AACjC,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CACzB,GAAG,CAAC;QACF,SAAS,EAAE,MAAK;;YAEd,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;QACnC,CAAC;QACD,WAAW,EAAE,MAAK;;YAEhB,MAAM,CAAC,GAAG,CAAC;QACb,CAAC;KACF,CAAC,EACF,eAAe,CAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAI;;QAErC,IAAI,KAAK,KAAK,CAAC,IAAI,cAAc,EAAE,SAAS,KAAK,KAAK,EAAE;AACtD,YAAA,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC;QACzB;QAEA,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACpC,OAAO,KAAK,CAAC,IAAI,CACf,GAAG,CAAC,CAAC,GAAG,KAAI;;AAEV,gBAAA,IAAI,SAAS,KAAK,gBAAgB,CAAC,iBAAiB,EAAE;AACpD,oBAAA,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC;AAC1B,oBAAA,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC7B;;gBAGA,IAAI,KAAK,KAAK,CAAC,IAAI,cAAc,EAAE,KAAK,EAAE;oBACxC,eAAe,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC;gBACrD;AACF,YAAA,CAAC,CAAC,EACF,UAAU,CAAC,CAAC,GAAG,KAAI;;AAEjB,gBAAA,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC;;gBAGzB,OAAO,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC;AAC1C,YAAA,CAAC,CAAC,EACF,QAAQ,CAAC,MAAK;;gBAEZ,IAAI,KAAK,KAAK,CAAC,IAAI,cAAc,EAAE,SAAS,KAAK,KAAK,EAAE;AACtD,oBAAA,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC1B;YACF,CAAC,CAAC,CACH;AACH,QAAA,CAAC,CAAC;IACJ,CAAC,CAAC,CACH;AAED,IAAA,OAAO,aAAa,KAAK,aAAa,CAAC;UACnC,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;UACpE,OAAO;AACb;AAEA;AACA;AACA;AACA;;;AAGG;AACH,SAAS,GAAG,CAAC,EAAU,EAAE,GAAQ,EAAE,IAAqB,EAAA;;AAEtD,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY;;AAG1C,IAAA,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE;;AAGpB,IAAA,MAAM,UAAU,GAAY;QAC1B,IAAI;AACJ,QAAA,MAAM,EAAE,SAAS;QACjB,GAAG;AACH,QAAA,QAAQ,EAAE,KAAK;AACf,QAAA,YAAY,EAAE,CAAC;KAChB;;AAGD,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC;;AAG1B,IAAA,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC;AAEA;;AAEG;AACH,SAAS,MAAM,CAAC,EAAU,EAAA;;AAExB,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY;;AAG1C,IAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE;;AAGrB,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,IAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;AACjB,IAAA,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC;AAEA;;;;AAIG;AACH,SAAS,eAAe,CAAC,EAAU,EAAE,KAAa,EAAA;;AAEhD,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY;;IAG1C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAC9B,IAAA,IAAI,CAAC,OAAO;QAAE;;AAGd,IAAA,MAAM,UAAU,GAAY;AAC1B,QAAA,GAAG,OAAO;AACV,QAAA,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,GAAG,KAAK,CAAC;KACxD;;AAGD,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC;;AAG1B,IAAA,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC;AAEA;;;;AAIG;AACH,SAAS,cAAc,CAAC,EAAU,EAAE,QAAiB,EAAA;;AAEnD,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY;;IAG1C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAC9B,IAAA,IAAI,CAAC,OAAO;QAAE;;AAGd,IAAA,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE;;IAGnC,MAAM,UAAU,GAAY,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE;;AAGpD,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC;;AAG1B,IAAA,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC;;ACvPA;AACA;AACA;AACA;;AAEG;AACH,eAAe,OAAO,CAAC,OAAgB,EAAA;AACrC,IAAA,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;AACnC,IAAA,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,EAAE;AAEpC,IAAA,IAAI;;AAEF,QAAA,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;;AAGhC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;;AAG5D,QAAA,IAAI,GAAG,CAAC,EAAE,EAAE;AACV,YAAA,OAAO,GAAG;QACZ;;AAGA,QAAA,IAAI,SAAkB;AAEtB,QAAA,IAAI;;AAEF,YAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,EAAE;;AAG5B,YAAA,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE;YACzD,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,kBAAkB,CAAC;;AAGzD,YAAA,SAAS,GAAG,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;QACpE;AAAE,QAAA,MAAM;;AAEN,YAAA,SAAS,GAAG,CAAA,6CAAA,EAAgD,GAAG,CAAC,MAAM,GAAG;QAC3E;;;;AAKA,QAAA,IAAI,eAAe,CAAC,SAAS,CAAC,EAAE;YAC9B,MAAM,aAAa,GAAG,SAAS;YAC/B,MAAM,IAAI,YAAY,CAAC;AACrB,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,OAAO,EAAE,YAAY;gBACrB,UAAU,EAAE,GAAG,CAAC,MAAM;gBACtB,UAAU;gBACV,SAAS,EAAE,SAAS,CAAC,SAAS;AAC9B,gBAAA,KAAK,EAAE,aAAa;AACrB,aAAA,CAAC;QACJ;;;;;QAMA,MAAM,cAAc,GAAG,CAAA,WAAA,EAAc,GAAG,CAAC,MAAM,CAAA,EAAG,GAAG,CAAC,UAAU,GAAG,CAAA,EAAA,EAAK,GAAG,CAAC,UAAU,CAAA,CAAA,CAAG,GAAG,EAAE,CAAA,CAAE;AAChG,QAAA,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,cAAc,CAAC;AAC9C,QAAA,MAAM,aAAa,GAAkB;AACnC,YAAA,SAAS,EAAE;AACT,gBAAA,IAAI,EAAE,KAAK;AACX,gBAAA,IAAI,EAAE,aAAa;gBACnB,OAAO,EACL,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI;sBAC3C,SAAS;sBACT,cAAc;AACpB,gBAAA,UAAU,EAAE,YAAY,CAAC,KAAK,IAAI,EAAE;AACrC,aAAA;AACD,YAAA,cAAc,EAAE,IAAI;SACrB;QACD,MAAM,IAAI,YAAY,CAAC;AACrB,YAAA,IAAI,EAAE,QAAQ;AACd,YAAA,OAAO,EAAE,YAAY;YACrB,UAAU,EAAE,GAAG,CAAC,MAAM;YACtB,UAAU;YACV,SAAS,EAAE,SAAS,CAAC,SAAS;AAC9B,YAAA,KAAK,EAAE,aAAa;AACrB,SAAA,CAAC;IACJ;IAAE,OAAO,KAAc,EAAE;;;;AAIvB,QAAA,IAAI,KAAK,YAAY,YAAY,EAAE;AACjC,YAAA,MAAM,KAAK;QACb;;;;AAKA,QAAA,IAAI,KAAK,YAAY,SAAS,EAAE;AAC9B,YAAA,MAAM,iBAAiB,GAAkB;AACvC,gBAAA,SAAS,EAAE;AACT,oBAAA,IAAI,EAAE,KAAK;AACX,oBAAA,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,cAAc;oBAClC,OAAO,EAAE,KAAK,CAAC,OAAO;AACtB,oBAAA,UAAU,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;AAC9B,iBAAA;AACD,gBAAA,cAAc,EAAE,IAAI;aACrB;YACD,MAAM,IAAI,YAAY,CAAC;AACrB,gBAAA,IAAI,EAAE,SAAS;AACf,gBAAA,OAAO,EAAE,YAAY;AACrB,gBAAA,UAAU,EAAE,CAAC;AACb,gBAAA,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,SAAS,CAAC,SAAS;AAC9B,gBAAA,KAAK,EAAE,iBAAiB;AACzB,aAAA,CAAC;QACJ;;;AAIA,QAAA,MAAM,KAAK;IACb;AACF;AAOO,eAAe,WAAW,CAAI,OAAgB,EAAA;;AAEnD,IAAA,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC;;AAGlC,IAAA,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE;;AAGxB,IAAA,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE;;AAG7B,IAAA,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;AACrC,QAAA,MAAM,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC;IACtC;;AAGA,IAAA,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM;AAC9B;AAEO,eAAe,WAAW,CAAC,OAAgB,EAAA;;AAEhD,IAAA,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC;;AAGlC,IAAA,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE;;AAGxB,IAAA,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE;;AAG7B,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;AACnB,QAAA,MAAM,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC;IACtC;;IAGA,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;AAC1D,IAAA,IAAI,QAAQ,GAAG,cAAc,CAAC;IAC9B,IAAI,WAAW,EAAE;QACf,MAAM,OAAO,GAAG,wCAAwC,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1E,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE;AAC3B,YAAA,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C;IACF;;IAGA,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC;IAEzC,UAAU,CAAC,MAAK;AACd,QAAA,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC;IAC9B,CAAC,EAAE,MAAM,CAAC;IAEV,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;AACzC;AAEA;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,OAAgB,EAAE,GAAa,EAAA;IACvD,OAAO,IAAI,YAAY,CAAC;AACtB,QAAA,IAAI,EAAE,IAAI;QACV,OAAO;QACP,UAAU,EAAE,GAAG,CAAC,MAAM;AACtB,QAAA,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,SAAS,CAAC,SAAS;AAC9B,QAAA,KAAK,EAAE;AACL,YAAA,SAAS,EAAE;AACT,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,IAAI,EAAE,eAAe;AACrB,gBAAA,OAAO,EAAE,0DAA0D;AACnE,gBAAA,UAAU,EAAE,EAAE;AACf,aAAA;AACD,YAAA,cAAc,EAAE,IAAI;AACrB,SAAA;AACF,KAAA,CAAC;AACJ;;ACrMA;;;AAGG;AACG,SAAU,UAAU,CACxB,QAAgB,EAChB,IAAY,EACZ,MAAqB,EACrB,kBAA+B,EAAA;IAE/B,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM;;IAGlD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,EAAE,CAAC;;IAGnD,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IACjF,MAAM,SAAS,GAAG,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;;AAG1C,IAAA,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,CAAA,OAAA,EAAU,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAC;;IAG5D,IAAI,WAAW,EAAE;;QAEf,MAAM,YAAY,GAAG,0EAA0E;AAE/F,QAAA,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;YACzD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE;gBAC/C;YACF;;AAGA,YAAA,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAEnE,YAAA,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE;gBAC9B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE;oBACvC;gBACF;AAEA,gBAAA,IAAI,cAAsB;;AAG1B,gBAAA,IAAI,IAAI,YAAY,IAAI,EAAE;AACxB,oBAAA,cAAc,GAAG,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC;gBACtD;;AAEK,qBAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AAC5D,oBAAA,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC;;oBAEjC,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE;AAChD,0BAAE;AACF,0BAAE,kBAAkB,CAAC,UAAU,CAAC,UAAU,CAAC;gBAC/C;;qBAEK;AACH,oBAAA,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC;gBAC/B;;gBAGA,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC;YAC9C;QACF;IACF;;AAGA,IAAA,MAAM,UAAU,GAAgB;AAC9B,QAAA,GAAG,kBAAkB;QACrB,GAAG,MAAM,CAAC,IAAI;KACf;;AAGD,IAAA,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC;AACrC;AAEA;;;;;;AAMG;AACG,SAAU,gBAAgB,CAAI,IAAiB,EAAA;;AAEnD,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AACvB,QAAA,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE;YACvB,gBAAgB,CAAC,IAAI,CAAC;QACxB;QACA;IACF;;AAGA,IAAA,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,EAAE,IAAI,YAAY,IAAI,CAAC,EAAE;AACxE,QAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/C,YAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE;;AAGlC,YAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;AACtE,gBAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;AACjE,oBAAA,MAAM,IAAI,KAAK,CACb,2BAA2B,GAAG,CAAA,2DAAA,CAA6D,CAC5F;gBACH;;AAEA,gBAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC;gBAC5B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AAChC,oBAAA,MAAM,IAAI,SAAS,CAAC,2BAA2B,GAAG,CAAA,kCAAA,CAAoC,CAAC;gBACzF;YACF;;AAGA,YAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AACxD,gBAAA,MAAM,cAAc,GAAG,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC9E,IAAI,CAAC,cAAc,EAAE;AACnB,oBAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAA,8BAAA,CAAgC,CAAC;gBACjF;YACF;;;YAIA,MAAM,gBAAgB,GAAG,2BAA2B;AACpD,YAAA,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE;AAC5D,gBAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAA,oBAAA,CAAsB,CAAC;YACvE;;YAGA,IACE,CAAC,QAAQ,KAAK,IAAI;AAChB,gBAAA,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;AACvB,gBAAA,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AAC1B,gBAAA,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;AACxB,gBAAA,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AAC5B,gBAAA,OAAO,KAAK,KAAK,QAAQ,EACzB;AACA,gBAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAA,mBAAA,CAAqB,CAAC;YACtE;;YAGA,gBAAgB,CAAC,KAAK,CAAC;QACzB;IACF;AACF;AAEA;;;;;AAKG;AACG,SAAU,iBAAiB,CAC/B,IAAiB,EACjB,MAAsB,EACtB,MAAM,GAAG,IAAI,EAAA;IAEb,IAAI,MAAM,EAAE;QACV,gBAAgB,CAAC,IAAI,CAAC;IACxB;;;IAIA,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;;AAE7C,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AAC5B,YAAA,OAAO,IAAI,CAAC,IAAI,EAAE;QACpB;AACA,QAAA,OAAO,IAAI;IACb;;;AAIA,IAAA,IAAI,IAAI,YAAY,IAAI,EAAE;AACxB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;AAC/B,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAC1D,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AACnD,QAAA,OAAO,GAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,GAAG,EAAE;IAClC;;;;AAKA,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AACvB,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACnE;;;;AAKA,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI;SAChC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC;SAC9E,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;;AAGxE,IAAA,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;AACpC;;ACpLA,MAAM,oBAAoB,GAAgB;AACxC,IAAA,IAAI,EAAE,SAAS;AACf,IAAA,KAAK,EAAE,oBAAoB;CAC5B;MAEY,cAAc,CAAA;;;;;AAclB,IAAA,WAAW,mBAAmB,GAAA;AACnC,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CACrB,GAAG,CAAC,CAAC,UAAU,KAAK,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAC7E,oBAAoB,EAAE,CACvB;IACH;;;;;aAMc,IAAA,CAAA,KAAK,GAAG,IAAI,eAAe,CAAuB,IAAI,GAAG,EAAE,CAAC,CAAC;;AAG7D,IAAA,SAAA,IAAA,CAAA,MAAM,GAAqC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;;AAG5E,IAAA,WAAW,YAAY,GAAA;AAC5B,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;IAC9B;;;;AAKA;;;AAGG;AACI,IAAA,OAAO,KAAK,CAAC,QAAgB,EAAE,IAAY,EAAA;AAChD,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;AACxB,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;IAClB;IAWO,OAAO,KAAK,CAAI,MAAqB,EAAA;;AAE1C,QAAA,MAAM,kBAAkB,GAAgB;AACtC,YAAA,MAAM,EAAE,KAAK;SACd;;AAED,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;QAGzF,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAC1E,GAAG,CAAC,CAAC,GAAG,KAAI;AACV,YAAA,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE;gBACvE,eAAe,CAAC,IAAI,CAAC;AACnB,oBAAA,KAAK,EAAE,YAAY;AACnB,oBAAA,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE;AAC9B,iBAAA,CAAC;YACJ;QACF,CAAC,CAAC,CACH;IACH;AAcO,IAAA,OAAO,OAAO,CACnB,MAA6B,EAC7B,IAAqB,EAAA;;AAGrB,QAAA,MAAM,kBAAkB,GAAgB;YACtC,GAAG,MAAM,CAAC,IAAI;AACd,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,OAAO,EAAE;AACP,gBAAA,cAAc,EAAE,kBAAkB;AAClC,gBAAA,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO;AACxB,aAAA;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;SACtD;AACD,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;AAGzF,QAAA,MAAM,YAAY,GAA0B;AAC1C,YAAA,GAAG,MAAM;AACT,YAAA,KAAK,EAAE,MAAM,CAAC,QAAQ,KAAK,KAAK,GAAG,SAAS,IAAI,MAAM,CAAC,KAAK,IAAI,oBAAoB,CAAC;SACtF;;AAGD,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAY,OAAO,CAAC,CAAC;IACvF;AAeO,IAAA,OAAO,OAAO,CACnB,MAA6B,EAC7B,IAAsB,EAAA;;AAGtB,QAAA,MAAM,kBAAkB,GAAgB,EAAE,MAAM,EAAE,KAAK,EAAE;AACzD,QAAA,IAAI,IAAI,KAAK,SAAS,EAAE;YACtB,kBAAkB,CAAC,OAAO,GAAG;AAC3B,gBAAA,cAAc,EAAE,kBAAkB;AAClC,gBAAA,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO;aACxB;AACD,YAAA,kBAAkB,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1E;AACA,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;AAGzF,QAAA,MAAM,YAAY,GAA0B;AAC1C,YAAA,GAAG,MAAM;AACT,YAAA,KAAK,EAAE,MAAM,CAAC,QAAQ,KAAK,KAAK,GAAG,SAAS,IAAI,MAAM,CAAC,KAAK,IAAI,oBAAoB,CAAC;SACtF;;AAGD,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAY,OAAO,CAAC,CAAC;IACvF;IAQO,OAAO,OAAO,CAAI,MAAqB,EAAA;;AAE5C,QAAA,MAAM,kBAAkB,GAAgB;AACtC,YAAA,MAAM,EAAE,QAAQ;SACjB;AACD,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;AAGzF,QAAA,MAAM,YAAY,GAAkB;AAClC,YAAA,GAAG,MAAM;AACT,YAAA,KAAK,EAAE,MAAM,CAAC,QAAQ,KAAK,KAAK,GAAG,SAAS,IAAI,MAAM,CAAC,KAAK,IAAI,oBAAoB,CAAC;SACtF;;AAGD,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAI,OAAO,CAAC,CAAC;IAC/E;;;;AAKA;;;AAGG;IACI,OAAO,UAAU,CAAC,MAAkC,EAAA;;AAEzD,QAAA,MAAM,kBAAkB,GAAgB;AACtC,YAAA,MAAM,EAAE,KAAK;SACd;AACD,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;AAGzF,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IACxE;AAEA;;;AAGG;IACI,OAAO,SAAS,CAAC,MAAkC,EAAA;;AAExD,QAAA,MAAM,kBAAkB,GAAgB;AACtC,YAAA,MAAM,EAAE,KAAK;SACd;AACD,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;AAGzF,QAAA,MAAM,YAAY,GAA+B;AAC/C,YAAA,GAAG,MAAM;AACT,YAAA,KAAK,EAAE,MAAM,CAAC,QAAQ,KAAK,KAAK,GAAG,SAAS,IAAI,MAAM,CAAC,KAAK,IAAI,oBAAoB,CAAC;SACtF;;AAGD,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7E;IAWO,OAAO,YAAY,CAAI,MAA4B,EAAA;;AAExD,QAAA,MAAM,kBAAkB,GAAgB;AACtC,YAAA,MAAM,EAAE,KAAK;SACd;AACD,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;AAGzF,QAAA,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,WAAW,CAAI,OAAO,CAAC,CAAC;IACzE;AAcO,IAAA,OAAO,cAAc,CAC1B,MAAoC,EACpC,IAAqB,EAAA;;AAGrB,QAAA,MAAM,kBAAkB,GAAgB;AACtC,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;SACtD;AACD,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;AAGzF,QAAA,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,WAAW,CAAY,OAAO,CAAC,CAAC;IACjF;AAiBO,IAAA,OAAO,cAAc,CAC1B,MAAoC,EACpC,IAAsB,EAAA;;AAGtB,QAAA,MAAM,kBAAkB,GAAgB;AACtC,YAAA,MAAM,EAAE,KAAK;SACd;AACD,QAAA,IAAI,IAAI,KAAK,SAAS,EAAE;YACtB,kBAAkB,CAAC,OAAO,GAAG;AAC3B,gBAAA,cAAc,EAAE,kBAAkB;AAClC,gBAAA,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO;aACxB;AACD,YAAA,kBAAkB,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1E;AACA,QAAA,MAAM,OAAO,GAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC;;AAGzF,QAAA,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,WAAW,CAAY,OAAO,CAAC,CAAC;IACjF;;;AC9TF;;AAEG;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uni-manager-locale.mjs","sources":["../../../projects/uni-manager/locale/manager.ts","../../../projects/uni-manager/locale/uni-manager-locale.ts"],"sourcesContent":["import { BehaviorSubject } from 'rxjs';\r\n\r\nexport class UniLocaleManager {\r\n /* ------------------------------------------------------------------------------- */\r\n /* ----------------------------------- Config ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Codice lingua corrente (es. 'it-IT', 'en-US') usato per formattare date e numeri */\r\n private static _locale = navigator.language ?? 'en-US';\r\n\r\n /** Elenco dei codici lingua supportati dall'applicazione (es. ['it-IT', 'en-US']) */\r\n private static _localesSupported: string[] = [];\r\n\r\n /** Prefisso globale applicato a tutte le chiavi di traduzione (es. 'APP_') */\r\n private static _prefix: string | undefined = undefined;\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* --------------------------------- Metodi: get --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Restituisce il codice lingua corrente */\r\n public static get locale(): string {\r\n return this._locale;\r\n }\r\n\r\n /** Restituisce l'array contenente tutti i codici locale supportati.*/\r\n public static get localesSupported(): string[] {\r\n return this._localesSupported;\r\n }\r\n\r\n /** Restituisce solo la lingua (es. 'it') */\r\n public static get language(): string {\r\n return this._locale.split('-')[0];\r\n }\r\n\r\n /** Restituisce solo il paese (es. 'IT') */\r\n public static get region(): string {\r\n const parts = this._locale.split('-');\r\n return parts.length > 1 ? parts[1] : '';\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ------------------------------------ Store ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Store privato (Subject) */\r\n public static store = new BehaviorSubject<Record<string, string>>({});\r\n\r\n /** Store pubblico (Observable) */\r\n public static store$ = this.store.asObservable();\r\n\r\n /** Ottiene il dizionario attuale senza sottoscrizione */\r\n public static get currentValue(): Record<string, string> {\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(locale: string | null | undefined, prefix?: string): void {\r\n this._locale = locale ?? 'en-US';\r\n this._prefix = prefix;\r\n }\r\n\r\n /** Imposta l'elenco dei codici lingua supportati dall'applicazione */\r\n public static setLocalesSupported(locales: string[] | undefined): void {\r\n this._localesSupported = locales ?? [];\r\n }\r\n\r\n /**\r\n * Aggiorna lo store locale con il dizionario delle traduzioni fornito.\r\n * Se viene passato undefined, lo store viene inizializzato come oggetto vuoto.\r\n */\r\n public static setTranslations(translations: Record<string, string> | undefined): void {\r\n this.store.next(translations ?? {});\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ----------------------------- Metodi: traduzioni ------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Traduce una label in base al dizionario caricato.\r\n * Gestisce la composizione della chiave, i parametri dinamici (interpolazione) e il fallback.\r\n */\r\n public static translate(\r\n key: string,\r\n prefix = 'lbl',\r\n params?: Record<string, string | number | Date>,\r\n ): string {\r\n if (!key) return '-';\r\n\r\n // Costruzione chiave: prefissoGlobale + prefissoLocale + LabelConInizialeMaiuscola\r\n const keyParts = key.trim().split(/(?=[A-Z])/);\r\n const rootKeyParts = keyParts.filter((p) => p.toLowerCase() !== prefix.toLowerCase());\r\n const cleanKey = rootKeyParts.length > 0 ? rootKeyParts.join('') : undefined;\r\n const capitalizedKey = cleanKey ? cleanKey.charAt(0).toUpperCase() + cleanKey.slice(1) : '';\r\n const finalKey = `${this._prefix ?? ''}${prefix}${capitalizedKey}`;\r\n\r\n // Cerca la chiave in minuscolo (standardizzazione)\r\n let translation = this.currentValue?.[finalKey.toLowerCase()];\r\n\r\n // Log e fallback se la traduzione manca\r\n if (!translation) {\r\n console.warn(`Translation missing for key: ${finalKey}`);\r\n return `🔑 ${finalKey}`;\r\n }\r\n\r\n // Interpolazione variabili\r\n if (params) {\r\n for (const [key, value] of Object.entries(params)) {\r\n const displayValue =\r\n value instanceof Date ? value.toLocaleDateString(this._locale) : String(value);\r\n\r\n translation = translation.replaceAll(`{{${key}}}`, displayValue);\r\n }\r\n }\r\n\r\n return translation;\r\n }\r\n\r\n /**\r\n * Traduce una stringa che contiene parametri separati da un carattere specifico.\r\n * Supporta ora un numero arbitrario di parametri in formato \"label/param1/param2\"\r\n * o semplicemente \"label\".\r\n */\r\n public static translateInlineParams(keyWithParams: string, splitChar: string): string {\r\n if (!keyWithParams) return '-';\r\n\r\n const [label, ...params] = keyWithParams.split(splitChar);\r\n\r\n // Se non ci sono parametri, esegui una traduzione semplice\r\n if (params.length === 0) {\r\n return this.translate(label);\r\n }\r\n\r\n // Mappa i parametri in un oggetto di interpolazione: { inlineParam0: val, inlineParam1: val, ... }\r\n const interpolationParameters: Record<string, string> = {};\r\n for (const [index, val] of params.entries()) {\r\n interpolationParameters[`param${index}`] = val;\r\n }\r\n\r\n return this.translate(label, 'lbl', interpolationParameters);\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ------------------------------- Metodi: numeri -------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Converte un valore numerico in una stringa formattata secondo il locale impostato.\r\n * Disabilita i separatori delle migliaia e forza un numero fisso di decimali.\r\n */\r\n public static toStringNumber(value: number, decimal: number): string {\r\n return new Intl.NumberFormat(this._locale, {\r\n useGrouping: true,\r\n minimumFractionDigits: decimal,\r\n maximumFractionDigits: decimal,\r\n numberingSystem: 'latn',\r\n }).format(value);\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: date --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Formatta una data o una stringa in base al locale corrente.\r\n * Gestisce tre modalità predefinite (date, time, full) e accetta opzioni personalizzate Intl.\r\n */\r\n public static toDate(\r\n date: string | Date,\r\n mode: 'date' | 'time' | 'full' = 'full',\r\n force?: { oldLang: string; newLocale: string },\r\n ): string {\r\n const dt = new Date(date);\r\n\r\n // Controllo: validità data\r\n if (Number.isNaN(dt.getTime())) {\r\n console.error(`[UniLocaleManager] Data non valida fornita a formatDateTime:`, date);\r\n return '';\r\n }\r\n\r\n // Controllo: locale da forzare\r\n const locale = force && this._locale.startsWith(force.oldLang) ? force.newLocale : this._locale;\r\n\r\n switch (mode) {\r\n case 'date': {\r\n return dt.toLocaleDateString(locale);\r\n }\r\n case 'time': {\r\n return dt.toLocaleTimeString(locale);\r\n }\r\n case 'full': {\r\n return dt.toLocaleString(locale);\r\n }\r\n }\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-locale.mjs","sources":["../../../projects/uni-manager/locale/manager.ts","../../../projects/uni-manager/locale/uni-manager-locale.ts"],"sourcesContent":["import { BehaviorSubject } from 'rxjs';\r\n\r\nexport class UniLocaleManager {\r\n /* ------------------------------------------------------------------------------- */\r\n /* ----------------------------------- Config ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Codice lingua corrente (es. 'it-IT', 'en-US') usato per formattare date e numeri */\r\n private static _locale = navigator.language ?? 'en-US';\r\n\r\n /** Elenco dei codici lingua supportati dall'applicazione (es. ['it-IT', 'en-US']) */\r\n private static _localesSupported: string[] = [];\r\n\r\n /** Prefisso globale applicato a tutte le chiavi di traduzione (es. 'APP_') */\r\n private static _prefix: string | undefined = undefined;\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* --------------------------------- Metodi: get --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Restituisce il codice lingua corrente */\r\n public static get locale(): string {\r\n return this._locale;\r\n }\r\n\r\n /** Restituisce l'array contenente tutti i codici locale supportati.*/\r\n public static get localesSupported(): string[] {\r\n return this._localesSupported;\r\n }\r\n\r\n /** Restituisce solo la lingua (es. 'it') */\r\n public static get language(): string {\r\n return this._locale.split('-')[0];\r\n }\r\n\r\n /** Restituisce solo il paese (es. 'IT') */\r\n public static get region(): string {\r\n const parts = this._locale.split('-');\r\n return parts.length > 1 ? parts[1] : '';\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ------------------------------------ Store ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Store privato (Subject) */\r\n public static store = new BehaviorSubject<Record<string, string>>({});\r\n\r\n /** Store pubblico (Observable) */\r\n public static store$ = this.store.asObservable();\r\n\r\n /** Ottiene il dizionario attuale senza sottoscrizione */\r\n public static get currentValue(): Record<string, string> {\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(locale: string | null | undefined, prefix?: string): void {\r\n this._locale = locale ?? 'en-US';\r\n this._prefix = prefix;\r\n }\r\n\r\n /** Imposta l'elenco dei codici lingua supportati dall'applicazione */\r\n public static setLocalesSupported(locales: string[] | undefined): void {\r\n this._localesSupported = locales ?? [];\r\n }\r\n\r\n /**\r\n * Aggiorna lo store locale con il dizionario delle traduzioni fornito.\r\n * Se viene passato undefined, lo store viene inizializzato come oggetto vuoto.\r\n */\r\n public static setTranslations(translations: Record<string, string> | undefined): void {\r\n this.store.next(translations ?? {});\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ----------------------------- Metodi: traduzioni ------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Traduce una label in base al dizionario caricato.\r\n * Gestisce la composizione della chiave, i parametri dinamici (interpolazione) e il fallback.\r\n */\r\n public static translate(\r\n key: string,\r\n prefix = 'lbl',\r\n params?: Record<string, string | number | Date>,\r\n ): string {\r\n if (!key) return '-';\r\n\r\n // Costruzione chiave: prefissoGlobale + prefissoLocale + LabelConInizialeMaiuscola\r\n const keyParts = key.trim().split(/(?=[A-Z])/);\r\n const rootKeyParts = keyParts.filter((p) => p.toLowerCase() !== prefix.toLowerCase());\r\n const cleanKey = rootKeyParts.length > 0 ? rootKeyParts.join('') : undefined;\r\n const capitalizedKey = cleanKey ? cleanKey.charAt(0).toUpperCase() + cleanKey.slice(1) : '';\r\n const finalKey = `${this._prefix ?? ''}${prefix}${capitalizedKey}`;\r\n\r\n // Cerca la chiave in minuscolo (standardizzazione)\r\n let translation = this.currentValue?.[finalKey.toLowerCase()];\r\n\r\n // Log e fallback se la traduzione manca\r\n if (!translation) {\r\n console.warn(`Translation missing for key: ${finalKey}`);\r\n return `🔑 ${finalKey}`;\r\n }\r\n\r\n // Interpolazione variabili\r\n if (params) {\r\n for (const [key, value] of Object.entries(params)) {\r\n const displayValue =\r\n value instanceof Date ? value.toLocaleDateString(this._locale) : String(value);\r\n\r\n translation = translation.replaceAll(`{{${key}}}`, displayValue);\r\n }\r\n }\r\n\r\n return translation;\r\n }\r\n\r\n /**\r\n * Traduce una stringa che contiene parametri separati da un carattere specifico.\r\n * Supporta ora un numero arbitrario di parametri in formato \"label/param1/param2\"\r\n * o semplicemente \"label\".\r\n */\r\n public static translateInlineParams(keyWithParams: string, splitChar: string): string {\r\n if (!keyWithParams) return '-';\r\n\r\n const [label, ...params] = keyWithParams.split(splitChar);\r\n\r\n // Se non ci sono parametri, esegui una traduzione semplice\r\n if (params.length === 0) {\r\n return this.translate(label);\r\n }\r\n\r\n // Mappa i parametri in un oggetto di interpolazione: { inlineParam0: val, inlineParam1: val, ... }\r\n const interpolationParameters: Record<string, string> = {};\r\n for (const [index, val] of params.entries()) {\r\n interpolationParameters[`param${index}`] = val;\r\n }\r\n\r\n return this.translate(label, 'lbl', interpolationParameters);\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ------------------------------- Metodi: numeri -------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Converte un valore numerico in una stringa formattata secondo il locale impostato.\r\n * Disabilita i separatori delle migliaia e forza un numero fisso di decimali.\r\n */\r\n public static toStringNumber(value: number, decimal: number): string {\r\n return new Intl.NumberFormat(this._locale, {\r\n useGrouping: true,\r\n minimumFractionDigits: decimal,\r\n maximumFractionDigits: decimal,\r\n numberingSystem: 'latn',\r\n }).format(value);\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: date --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Formatta una data o una stringa in base al locale corrente.\r\n * Gestisce tre modalità predefinite (date, time, full) e accetta opzioni personalizzate Intl.\r\n */\r\n public static toDate(\r\n date: Date | string | number,\r\n mode: 'date' | 'time' | 'full' = 'full',\r\n force?: { oldLang: string; newLocale: string },\r\n ): string {\r\n const dt = new Date(date);\r\n\r\n // Controllo: validità data\r\n if (Number.isNaN(dt.getTime())) {\r\n console.error(`[UniLocaleManager] Data non valida fornita a formatDateTime:`, date);\r\n return '';\r\n }\r\n\r\n // Controllo: locale da forzare\r\n const locale = force && this._locale.startsWith(force.oldLang) ? force.newLocale : this._locale;\r\n\r\n switch (mode) {\r\n case 'date': {\r\n return dt.toLocaleDateString(locale);\r\n }\r\n case 'time': {\r\n return dt.toLocaleTimeString(locale);\r\n }\r\n case 'full': {\r\n return dt.toLocaleString(locale);\r\n }\r\n }\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.26",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"lodash-es": ">=4.18.1",
|
|
6
5
|
"rxjs": ">=7.8.2",
|
|
7
|
-
"
|
|
8
|
-
"uni-
|
|
6
|
+
"lodash-es": ">=4.18.1",
|
|
7
|
+
"uni-model-type": ">=0.1.9",
|
|
8
|
+
"uni-error": ">=0.1.22"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"tslib": "^2.3.0"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Observable, BehaviorSubject } from 'rxjs';
|
|
2
|
-
import { HttpRef, HttpConfig, HttpBody, FileDatasource, HttpConfigPolling } from 'uni-model-type/type';
|
|
2
|
+
import { HttpRef, HttpConfig, HttpBodyPrimitive, HttpBody, FileDatasource, HttpConfigPolling } from 'uni-model-type/type';
|
|
3
3
|
|
|
4
4
|
declare class UniHttpManager {
|
|
5
5
|
/** Hostname del server (es. 'api.example.com' o 'localhost') */
|
|
@@ -19,45 +19,56 @@ declare class UniHttpManager {
|
|
|
19
19
|
* Deve essere chiamato prima di effettuare qualsiasi richiesta HTTP.
|
|
20
20
|
*/
|
|
21
21
|
static setup(hostname: string, port: number): void;
|
|
22
|
-
static read
|
|
22
|
+
static read$(config: HttpConfig<void>): Observable<void>;
|
|
23
|
+
static read$<T>(config: HttpConfig<T>): Observable<T>;
|
|
23
24
|
/**
|
|
24
25
|
* Esegue una richiesta HTTP POST inviando un payload JSON nel corpo della richiesta.
|
|
25
26
|
* Imposta automaticamente l'header 'Content-Type' come 'application/json'.
|
|
26
27
|
*/
|
|
27
|
-
static create$<
|
|
28
|
+
static create$<TBody extends HttpBodyPrimitive>(config: HttpConfig<void>, body: HttpBody<TBody>): Observable<void>;
|
|
29
|
+
static create$<TResponse, TBody extends HttpBodyPrimitive>(config: HttpConfig<TResponse>, body: HttpBody<TBody>): Observable<TResponse>;
|
|
28
30
|
/**
|
|
29
31
|
* Esegue una singola richiesta HTTP PUT per aggiornare una risorsa esistente.
|
|
30
32
|
*/
|
|
31
|
-
static update
|
|
33
|
+
static update$(config: HttpConfig<void>): Observable<void>;
|
|
34
|
+
static update$<TBody extends HttpBodyPrimitive>(config: HttpConfig<void>, body: HttpBody<TBody>): Observable<void>;
|
|
35
|
+
static update$<TResponse>(config: HttpConfig<TResponse>): Observable<TResponse>;
|
|
36
|
+
static update$<TResponse, TBody extends HttpBodyPrimitive>(config: HttpConfig<TResponse>, body: HttpBody<TBody>): Observable<TResponse>;
|
|
32
37
|
/**
|
|
33
38
|
* Esegue una richiesta HTTP DELETE per rimuovere una risorsa.
|
|
34
39
|
* Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.
|
|
35
40
|
*/
|
|
36
|
-
static delete
|
|
41
|
+
static delete$(config: HttpConfig<void>): Observable<void>;
|
|
42
|
+
static delete$<T>(config: HttpConfig<T>): Observable<T>;
|
|
37
43
|
/**
|
|
38
44
|
* Recupera un'immagine tramite una richiesta GET e la trasforma in un formato gestibile (es. Blob o Base64).
|
|
39
45
|
* Delega la logica di conversione alla funzione executeImage.
|
|
40
46
|
*/
|
|
41
|
-
static readImage$(config: HttpConfig<FileDatasource>): Observable<FileDatasource |
|
|
47
|
+
static readImage$(config: HttpConfig<FileDatasource>): Observable<FileDatasource | void>;
|
|
42
48
|
/**
|
|
43
49
|
* Recupera un file (es. PDF) tramite una richiesta GET e restituisce un Object URL temporaneo.
|
|
44
50
|
* Delega la logica di conversione alla funzione executeFile.
|
|
45
51
|
*/
|
|
46
|
-
static readFile$(config: HttpConfig<FileDatasource>): Observable<FileDatasource |
|
|
52
|
+
static readFile$(config: HttpConfig<FileDatasource>): Observable<FileDatasource | void>;
|
|
47
53
|
/**
|
|
48
54
|
* Avvia un ciclo di polling basato su richieste GET.
|
|
49
55
|
* Continua a emettere valori in base alla configurazione di intervallo definita in HttpConfigPolling.
|
|
50
56
|
*/
|
|
51
|
-
static readPolling
|
|
57
|
+
static readPolling$(config: HttpConfigPolling<void>): Observable<void>;
|
|
58
|
+
static readPolling$<T>(config: HttpConfigPolling<T>): Observable<T>;
|
|
52
59
|
/**
|
|
53
60
|
* Avvia un ciclo di polling basato su richieste POST.
|
|
54
61
|
* Invia il body specificato a ogni iterazione del ciclo.
|
|
55
62
|
*/
|
|
56
|
-
static createPolling$<
|
|
63
|
+
static createPolling$<TBody extends HttpBodyPrimitive>(config: HttpConfigPolling<void>, body: HttpBody<TBody>): Observable<void>;
|
|
64
|
+
static createPolling$<TResponse, TBody extends HttpBodyPrimitive>(config: HttpConfigPolling<TResponse>, body: HttpBody<TBody>): Observable<TResponse>;
|
|
57
65
|
/**
|
|
58
66
|
* Avvia un ciclo di polling basato su richieste PUT.
|
|
59
67
|
*/
|
|
60
|
-
static updatePolling
|
|
68
|
+
static updatePolling$(config: HttpConfigPolling<void>): Observable<void>;
|
|
69
|
+
static updatePolling$<TBody extends HttpBodyPrimitive>(config: HttpConfigPolling<void>, body: HttpBody<TBody>): Observable<void>;
|
|
70
|
+
static updatePolling$<TResponse>(config: HttpConfigPolling<TResponse>): Observable<TResponse>;
|
|
71
|
+
static updatePolling$<TResponse, TBody extends HttpBodyPrimitive>(config: HttpConfigPolling<TResponse>, body: HttpBody<TBody>): Observable<TResponse>;
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
export { UniHttpManager };
|
|
@@ -54,7 +54,7 @@ declare class UniLocaleManager {
|
|
|
54
54
|
* Formatta una data o una stringa in base al locale corrente.
|
|
55
55
|
* Gestisce tre modalità predefinite (date, time, full) e accetta opzioni personalizzate Intl.
|
|
56
56
|
*/
|
|
57
|
-
static toDate(date: string |
|
|
57
|
+
static toDate(date: Date | string | number, mode?: 'date' | 'time' | 'full', force?: {
|
|
58
58
|
oldLang: string;
|
|
59
59
|
newLocale: string;
|
|
60
60
|
}): string;
|