uni-manager 0.1.0 → 0.1.2
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.
- package/fesm2022/uni-manager-http.mjs +91 -89
- package/fesm2022/uni-manager-http.mjs.map +1 -1
- package/fesm2022/uni-manager-locale.mjs +3 -3
- package/fesm2022/uni-manager-locale.mjs.map +1 -1
- package/fesm2022/uni-manager-toast.mjs +16 -14
- package/fesm2022/uni-manager-toast.mjs.map +1 -1
- package/fesm2022/uni-manager.mjs +110 -106
- package/fesm2022/uni-manager.mjs.map +1 -1
- package/package.json +2 -2
- package/types/uni-manager-http.d.ts +6 -11
- package/types/uni-manager-locale.d.ts +1 -1
- package/types/uni-manager-toast.d.ts +2 -4
- package/types/uni-manager.d.ts +9 -16
|
@@ -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/internal/BehaviorSubject';\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 interpolationParams?: 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 (interpolationParams) {\r\n for (const [key, value] of Object.entries(interpolationParams)) {\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":";;MAEa,gBAAgB,CAAA;;;;;AAKZ,IAAA,SAAA,IAAA,CAAA,OAAO,GAAG,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC;;aAGxC,IAAA,CAAA,iBAAiB,GAAa,EAAE,CAAC;;aAGjC,IAAA,CAAA,OAAO,GAAuB,SAAS,CAAC;;;;;AAMhD,IAAA,WAAW,MAAM,GAAA;QACtB,OAAO,IAAI,CAAC,OAAO;IACrB;;AAGO,IAAA,WAAW,gBAAgB,GAAA;QAChC,OAAO,IAAI,CAAC,iBAAiB;IAC/B;;AAGO,IAAA,WAAW,QAAQ,GAAA;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACnC;;AAGO,IAAA,WAAW,MAAM,GAAA;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC;AACrC,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE;IACzC;;;;;AAMc,IAAA,SAAA,IAAA,CAAA,KAAK,GAAG,IAAI,eAAe,CAAyB,EAAE,CAAC,CAAC;;AAGxD,IAAA,SAAA,IAAA,CAAA,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;;AAG1C,IAAA,WAAW,YAAY,GAAA;AAC5B,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;IAC9B;;;;AAKA;;;AAGG;AACI,IAAA,OAAO,KAAK,CAAC,MAAiC,EAAE,MAAe,EAAA;AACpE,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,OAAO;AAChC,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM;IACvB;;IAGO,OAAO,mBAAmB,CAAC,OAA6B,EAAA;AAC7D,QAAA,IAAI,CAAC,iBAAiB,GAAG,OAAO,IAAI,EAAE;IACxC;AAEA;;;AAGG;IACI,OAAO,eAAe,CAAC,YAAgD,EAAA;QAC5E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;IACrC;;;;AAKA;;;AAGG;IACI,OAAO,SAAS,CACrB,GAAW,EACX,MAAM,GAAG,KAAK,EACd,mBAA4D,EAAA;AAE5D,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,GAAG;;QAGpB,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC;QAC9C,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;QACrF,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,SAAS;QAC5E,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE;AAC3F,QAAA,MAAM,QAAQ,GAAG,CAAA,EAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA,EAAG,MAAM,CAAA,EAAG,cAAc,EAAE;;AAGlE,QAAA,IAAI,WAAW,GAAG,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;;QAG7D,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,OAAO,CAAC,IAAI,CAAC,gCAAgC,QAAQ,CAAA,CAAE,CAAC;YACxD,OAAO,CAAA,GAAA,EAAM,QAAQ,CAAA,CAAE;QACzB;;QAGA,IAAI,mBAAmB,EAAE;AACvB,YAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE;gBAC9D,MAAM,YAAY,GAChB,KAAK,YAAY,IAAI,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;gBAEhF,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA,EAAA,EAAK,GAAG,CAAA,EAAA,CAAI,EAAE,YAAY,CAAC;YAClE;QACF;AAEA,QAAA,OAAO,WAAW;IACpB;AAEA;;;;AAIG;AACI,IAAA,OAAO,qBAAqB,CAAC,aAAqB,EAAE,SAAiB,EAAA;AAC1E,QAAA,IAAI,CAAC,aAAa;AAAE,YAAA,OAAO,GAAG;AAE9B,QAAA,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC;;AAGzD,QAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;AACvB,YAAA,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QAC9B;;QAGA,MAAM,uBAAuB,GAA2B,EAAE;AAC1D,QAAA,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE;AAC3C,YAAA,uBAAuB,CAAC,CAAA,KAAA,EAAQ,KAAK,EAAE,CAAC,GAAG,GAAG;QAChD;QAEA,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,uBAAuB,CAAC;IAC9D;;;;AAKA;;;AAGG;AACI,IAAA,OAAO,cAAc,CAAC,KAAa,EAAE,OAAe,EAAA;QACzD,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE;AACzC,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,qBAAqB,EAAE,OAAO;AAC9B,YAAA,qBAAqB,EAAE,OAAO;AAC9B,YAAA,eAAe,EAAE,MAAM;AACxB,SAAA,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;IAClB;;;;AAKA;;;AAGG;IACI,OAAO,MAAM,CAClB,IAAmB,EACnB,IAAA,GAAiC,MAAM,EACvC,KAA8C,EAAA;AAE9C,QAAA,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC;;QAGzB,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE;AAC9B,YAAA,OAAO,CAAC,KAAK,CAAC,8DAA8D,EAAE,IAAI,CAAC;AACnF,YAAA,OAAO,EAAE;QACX;;QAGA,MAAM,MAAM,GAAG,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO;QAE/F,QAAQ,IAAI;YACV,KAAK,MAAM,EAAE;AACX,gBAAA,OAAO,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC;YACtC;YACA,KAAK,MAAM,EAAE;AACX,gBAAA,OAAO,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC;YACtC;YACA,KAAK,MAAM,EAAE;AACX,gBAAA,OAAO,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC;YAClC;;IAEJ;;;ACnMF;;AAEG;;;;"}
|
|
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/internal/BehaviorSubject';\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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"}
|
|
@@ -27,22 +27,24 @@ class UniToastManager {
|
|
|
27
27
|
* Mostra un toast di successo basato su una risposta HTTP e una label di traduzione.
|
|
28
28
|
*/
|
|
29
29
|
static showHttp(config, res) {
|
|
30
|
-
const {
|
|
30
|
+
const { params, resParams, formatters } = config;
|
|
31
31
|
/* Parametri statici di base */
|
|
32
|
-
const allParams = { ...
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
const allParams = { ...params };
|
|
33
|
+
if (res !== undefined && res !== null) {
|
|
34
|
+
/* Se è un array aggiunge il parametro 'count' con la lunghezza dell'array */
|
|
35
|
+
if (Array.isArray(res)) {
|
|
36
|
+
allParams['count'] = res.length;
|
|
37
|
+
}
|
|
38
|
+
else if (typeof res === 'object' && resParams?.length) {
|
|
39
|
+
// Se la proprietà NON esiste nella risposta, allora salta
|
|
40
|
+
for (const resParam of resParams ?? []) {
|
|
41
|
+
if (!(resParam in res))
|
|
42
|
+
continue;
|
|
43
|
+
// Se esiste un formatter per questa chiave lo si usa, altrimenti valore grezzo
|
|
44
|
+
const rawValue = res[resParam];
|
|
45
|
+
allParams[resParam] = formatters?.[resParam] ? formatters[resParam](rawValue) : rawValue;
|
|
46
|
+
}
|
|
41
47
|
}
|
|
42
|
-
}
|
|
43
|
-
/* Config parametro lunghezza risposta: conteggio array */
|
|
44
|
-
if (resLengthParam && Array.isArray(res)) {
|
|
45
|
-
allParams[resLengthParam] = res.length;
|
|
46
48
|
}
|
|
47
49
|
/* Messaggio tradotto */
|
|
48
50
|
this.show({ ...config, params: allParams });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uni-manager-toast.mjs","sources":["../../../projects/uni-manager/toast/manager.ts","../../../projects/uni-manager/toast/uni-manager-toast.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { UniLocaleManager } from 'uni-manager/locale';\r\nimport type { IToastManager, ToastConfig, ToastHttpConfig } from './model';\r\n\r\nexport class UniToastManager {\r\n /* ------------------------------------------------------------------------------- */\r\n /* ----------------------------------- Config ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Riferimento interno all'istanza */\r\n private static manager: IToastManager;\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: setup -------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Inizializza il manager con una serie di operazioni\r\n */\r\n public static setup(operations: IToastManager): void {\r\n this.manager = operations;\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: show --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Mostra un toast di successo basato su una risposta HTTP e una label di traduzione.\r\n */\r\n public static show(\r\n config:
|
|
1
|
+
{"version":3,"file":"uni-manager-toast.mjs","sources":["../../../projects/uni-manager/toast/manager.ts","../../../projects/uni-manager/toast/uni-manager-toast.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { UniLocaleManager } from 'uni-manager/locale';\r\nimport type { IToastManager, ToastConfig, ToastHttpConfig } from './model';\r\n\r\nexport class UniToastManager {\r\n /* ------------------------------------------------------------------------------- */\r\n /* ----------------------------------- Config ------------------------------------ */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Riferimento interno all'istanza */\r\n private static manager: IToastManager;\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: setup -------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Inizializza il manager con una serie di operazioni\r\n */\r\n public static setup(operations: IToastManager): void {\r\n this.manager = operations;\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: show --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Mostra un toast di successo basato su una risposta HTTP e una label di traduzione.\r\n */\r\n public static show(\r\n config: ToastConfig & {\r\n prefix?: string;\r\n suffix?: string;\r\n },\r\n ): void {\r\n /* Messaggio tradotto */\r\n const msg = UniLocaleManager.translate(config.label, 'toast', config.params);\r\n const msgFixed = `${config.prefix ?? ''}${msg}${config.suffix ?? ''}`;\r\n this.manager[config.type ?? 'info'](msgFixed, config);\r\n }\r\n\r\n /**\r\n * Mostra un toast di successo basato su una risposta HTTP e una label di traduzione.\r\n */\r\n public static showHttp<T>(config: ToastConfig & ToastHttpConfig<T>, res: T | undefined): void {\r\n const { params, resParams, formatters } = config;\r\n\r\n /* Parametri statici di base */\r\n const allParams: Record<string, any> = { ...params };\r\n\r\n if (res !== undefined && res !== null) {\r\n /* Se è un array aggiunge il parametro 'count' con la lunghezza dell'array */\r\n if (Array.isArray(res)) {\r\n allParams['count'] = res.length;\r\n } else if (typeof res === 'object' && resParams?.length) {\r\n // Se la proprietà NON esiste nella risposta, allora salta\r\n for (const resParam of resParams ?? []) {\r\n if (!(resParam in res)) continue;\r\n\r\n // Se esiste un formatter per questa chiave lo si usa, altrimenti valore grezzo\r\n const rawValue = res[resParam];\r\n allParams[resParam] = formatters?.[resParam] ? formatters[resParam](rawValue) : rawValue;\r\n }\r\n }\r\n }\r\n\r\n /* Messaggio tradotto */\r\n this.show({ ...config, params: allParams });\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;MAIa,eAAe,CAAA;;;;AAU1B;;AAEG;IACI,OAAO,KAAK,CAAC,UAAyB,EAAA;AAC3C,QAAA,IAAI,CAAC,OAAO,GAAG,UAAU;IAC3B;;;;AAKA;;AAEG;IACI,OAAO,IAAI,CAChB,MAGC,EAAA;;AAGD,QAAA,MAAM,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;AAC5E,QAAA,MAAM,QAAQ,GAAG,CAAA,EAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA,EAAG,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE;AACrE,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC;IACvD;AAEA;;AAEG;AACI,IAAA,OAAO,QAAQ,CAAI,MAAwC,EAAE,GAAkB,EAAA;QACpF,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM;;AAGhD,QAAA,MAAM,SAAS,GAAwB,EAAE,GAAG,MAAM,EAAE;QAEpD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;;AAErC,YAAA,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;AACtB,gBAAA,SAAS,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM;YACjC;iBAAO,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,SAAS,EAAE,MAAM,EAAE;;AAEvD,gBAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,IAAI,EAAE,EAAE;AACtC,oBAAA,IAAI,EAAE,QAAQ,IAAI,GAAG,CAAC;wBAAE;;AAGxB,oBAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;oBAC9B,SAAS,CAAC,QAAQ,CAAC,GAAG,UAAU,GAAG,QAAQ,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,QAAQ;gBAC1F;YACF;QACF;;AAGA,QAAA,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC7C;AACD;;ACnED;;AAEG;;;;"}
|
package/fesm2022/uni-manager.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import { concatMap } from 'rxjs/internal/operators/concatMap';
|
|
|
17
17
|
import { exhaustMap } from 'rxjs/internal/operators/exhaustMap';
|
|
18
18
|
import { mergeMap } from 'rxjs/internal/operators/mergeMap';
|
|
19
19
|
import { switchMap } from 'rxjs/internal/operators/switchMap';
|
|
20
|
-
import { UniHttpError,
|
|
20
|
+
import { UniHttpError, isHttpException } from 'uni-error/http';
|
|
21
21
|
import { UniTypeDateManager as UniTypeDateManager$1 } from 'uni-manager/type';
|
|
22
22
|
import { UniLocaleManager as UniLocaleManager$1 } from 'uni-manager/locale';
|
|
23
23
|
|
|
@@ -207,28 +207,27 @@ function operatorHandler(operator) {
|
|
|
207
207
|
}
|
|
208
208
|
function errorHandler(err, errorMode, ref) {
|
|
209
209
|
// Controllo: sia effettivamente un errore di tipo 'UniHttpError'
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
case PollingErrorMode.STOP: {
|
|
228
|
-
UniErrorManager$1.add(ref, err);
|
|
229
|
-
return throwError(() => err);
|
|
210
|
+
if (err instanceof UniHttpError) {
|
|
211
|
+
switch (errorMode) {
|
|
212
|
+
case PollingErrorMode.IGNORE: {
|
|
213
|
+
return of();
|
|
214
|
+
}
|
|
215
|
+
case PollingErrorMode.SKIP: {
|
|
216
|
+
return EMPTY;
|
|
217
|
+
}
|
|
218
|
+
case PollingErrorMode.IGNORE_WITH_ERROR: {
|
|
219
|
+
UniErrorManager$1.add(ref, err);
|
|
220
|
+
return of();
|
|
221
|
+
}
|
|
222
|
+
case PollingErrorMode.STOP: {
|
|
223
|
+
UniErrorManager$1.add(ref, err);
|
|
224
|
+
return throwError(() => err);
|
|
225
|
+
}
|
|
230
226
|
}
|
|
231
227
|
}
|
|
228
|
+
else {
|
|
229
|
+
return throwError(() => err);
|
|
230
|
+
}
|
|
232
231
|
}
|
|
233
232
|
|
|
234
233
|
/* ------------------------------------------------------------------------------- */
|
|
@@ -263,6 +262,8 @@ function http$(url, refType, config, promiseFactory) {
|
|
|
263
262
|
}
|
|
264
263
|
},
|
|
265
264
|
}), catchError((err) => {
|
|
265
|
+
// Aggiorna la ref nella map
|
|
266
|
+
updateHasError(ref, true);
|
|
266
267
|
/* Gestione errore */
|
|
267
268
|
return errorHandler(err, PollingErrorMode.STOP, ref);
|
|
268
269
|
}), finalize(() => {
|
|
@@ -308,6 +309,8 @@ function httpPolling$(url, config, promiseFactory) {
|
|
|
308
309
|
UniToastManager$1.showHttp(firstIteration.toast, res);
|
|
309
310
|
}
|
|
310
311
|
}), catchError((err) => {
|
|
312
|
+
// Aggiorna la ref nella map
|
|
313
|
+
updateHasError(ref, true);
|
|
311
314
|
/* Gestione errore */
|
|
312
315
|
return errorHandler(err, errorMode, ref);
|
|
313
316
|
}), finalize(() => {
|
|
@@ -409,66 +412,65 @@ function updateHasError(id, hasError) {
|
|
|
409
412
|
// Aggiorna il nuovo stato notificando l'observer
|
|
410
413
|
UniHttpManager.store.next(newMap);
|
|
411
414
|
}
|
|
412
|
-
/**
|
|
413
|
-
* Svuota completamente la lista delle refs
|
|
414
|
-
*/
|
|
415
|
-
function removeAll() {
|
|
416
|
-
// Crea una nuova istanza della Map
|
|
417
|
-
const newMap = new Map();
|
|
418
|
-
// Aggiorna il nuovo stato notificando l'observer
|
|
419
|
-
UniHttpManager.store.next(newMap);
|
|
420
|
-
}
|
|
421
415
|
|
|
422
416
|
async function execute(url, init) {
|
|
423
417
|
try {
|
|
424
|
-
/*
|
|
418
|
+
/* Esecuzione della richiesta HTTP nativa */
|
|
425
419
|
const res = await fetch(url, init);
|
|
426
|
-
/*
|
|
420
|
+
/* Gestione dello stato 204: assenza di contenuto legittima */
|
|
427
421
|
if (res.status === 204) {
|
|
428
422
|
return undefined;
|
|
429
423
|
}
|
|
430
|
-
/*
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
424
|
+
/*Gestione ok HTTP: risposta ricevuta dal server con stato valido */
|
|
425
|
+
if (res.ok) {
|
|
426
|
+
return res;
|
|
427
|
+
}
|
|
428
|
+
/* Gestione Errore HTTP: risposta ricevuta dal server ma con stato non valido */
|
|
429
|
+
let httpErrorPayload;
|
|
430
|
+
try {
|
|
431
|
+
/* Clonazione della risposta per l'ispezione del payload senza consumare lo stream originale */
|
|
432
|
+
const resClone = res.clone();
|
|
433
|
+
/* Recupero se è un json */
|
|
434
|
+
const contentType = res.headers.get('content-type') ?? '';
|
|
435
|
+
const isJson = contentType.startsWith('application/json');
|
|
436
|
+
/* Estrazione del corpo dell'errore in base al formato rilevato */
|
|
437
|
+
httpErrorPayload = isJson ? await resClone.json() : await resClone.text();
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
/* Fallback in caso di fallimento della clonazione o del parsing del testo */
|
|
441
|
+
httpErrorPayload = `Failed to parse error response body (Status: ${res.status})`;
|
|
442
|
+
}
|
|
443
|
+
// Controllo: se il payload estratto rispetta è di tipo HttpException
|
|
444
|
+
if (isHttpException(httpErrorPayload)) {
|
|
445
|
+
// const type = httpErrorPayload.isBe ? 'be' : 'ice';
|
|
446
|
+
throw new UniHttpError('be', res.status, url, httpErrorPayload);
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
// Fallback per errori non di tipo HttpException (es. pagine HTML di errore di IIS/Nginx o stringhe piane)
|
|
450
|
+
const error = new Error(res.statusText || `HTTP Error ${res.status}`);
|
|
451
|
+
const fallbackException = {
|
|
452
|
+
message: typeof httpErrorPayload === 'string' && httpErrorPayload
|
|
453
|
+
? httpErrorPayload
|
|
454
|
+
: error.message,
|
|
455
|
+
type: 'ErrorBase',
|
|
456
|
+
stackTrace: error.stack ?? '',
|
|
457
|
+
isBe: true,
|
|
458
|
+
};
|
|
459
|
+
throw new UniHttpError('base', res.status, url, fallbackException);
|
|
458
460
|
}
|
|
459
|
-
/* Risposta ok */
|
|
460
|
-
return res;
|
|
461
461
|
}
|
|
462
462
|
catch (error) {
|
|
463
|
+
// Fallback per errori di rete locale (es. assenza di linea, DNS fallito, timeout di fetch)
|
|
463
464
|
if (error instanceof TypeError) {
|
|
464
|
-
|
|
465
|
-
exceptionMessage: `${error.name}: ${error.message}\n${error.stack}`,
|
|
466
|
-
exceptionType: error.name,
|
|
465
|
+
const fallbackNetworkException = {
|
|
467
466
|
message: error.message,
|
|
467
|
+
type: error.name || 'TypeError',
|
|
468
468
|
stackTrace: error.stack ?? '',
|
|
469
|
-
|
|
469
|
+
isBe: true,
|
|
470
|
+
};
|
|
471
|
+
throw new UniHttpError('network', -1, url, fallbackNetworkException);
|
|
470
472
|
}
|
|
471
|
-
//
|
|
473
|
+
// Rilancio diretto senza alterazioni per istanze di UniHttpError o eccezioni non identificate
|
|
472
474
|
throw error;
|
|
473
475
|
}
|
|
474
476
|
}
|
|
@@ -515,16 +517,16 @@ async function executeBlob(url, init) {
|
|
|
515
517
|
* Costruisce un URL completo per l'API partendo dai parametri di configurazione.
|
|
516
518
|
*/
|
|
517
519
|
function getUrl(hostname, port, config) {
|
|
518
|
-
const {
|
|
520
|
+
const { pathParams, path, hasApiPrefix } = config;
|
|
519
521
|
// Costruzione url
|
|
520
|
-
const prefix = hasApiPrefix ? '
|
|
522
|
+
const prefix = hasApiPrefix === false ? '' : 'api';
|
|
521
523
|
const cleanPath = path.startsWith('/') ? path.slice(1) : path;
|
|
522
524
|
const pathFixed = prefix ? `${prefix}/${cleanPath}` : cleanPath;
|
|
523
525
|
const url = new URL(pathFixed, `http://${hostname}:${port}`);
|
|
524
|
-
if (
|
|
526
|
+
if (pathParams) {
|
|
525
527
|
// Regex per intercettare stringhe in formato ISO string
|
|
526
528
|
const isoDateRegex = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?$/;
|
|
527
|
-
for (const [key, rawValue] of Object.entries(
|
|
529
|
+
for (const [key, rawValue] of Object.entries(pathParams)) {
|
|
528
530
|
if (rawValue === undefined || rawValue === null) {
|
|
529
531
|
continue;
|
|
530
532
|
}
|
|
@@ -641,7 +643,7 @@ class UniHttpManager {
|
|
|
641
643
|
...config.init,
|
|
642
644
|
method: 'GET',
|
|
643
645
|
};
|
|
644
|
-
/*
|
|
646
|
+
/* API */
|
|
645
647
|
const url = getUrl(this.hostname, this.port, config);
|
|
646
648
|
return http$(url, 'one', config, () => executeHttp(url, initCustom)).pipe(tap((res) => {
|
|
647
649
|
if (Array.isArray(res) && config.toast === undefined) {
|
|
@@ -667,12 +669,12 @@ class UniHttpManager {
|
|
|
667
669
|
},
|
|
668
670
|
body: JSON.stringify(normalizeHttpBody(body)),
|
|
669
671
|
};
|
|
670
|
-
/*
|
|
672
|
+
/* Config custom (toast di default) */
|
|
671
673
|
const configCustom = {
|
|
672
674
|
...config,
|
|
673
|
-
toast: config.
|
|
675
|
+
toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),
|
|
674
676
|
};
|
|
675
|
-
/*
|
|
677
|
+
/* API */
|
|
676
678
|
const url = getUrl(this.hostname, this.port, config);
|
|
677
679
|
return http$(url, 'one', configCustom, () => executeHttp(url, initCustom));
|
|
678
680
|
}
|
|
@@ -689,12 +691,12 @@ class UniHttpManager {
|
|
|
689
691
|
};
|
|
690
692
|
initCustom.body = JSON.stringify(normalizeHttpBody(body));
|
|
691
693
|
}
|
|
692
|
-
/*
|
|
694
|
+
/* Config custom (toast di default) */
|
|
693
695
|
const configCustom = {
|
|
694
696
|
...config,
|
|
695
|
-
toast: config.
|
|
697
|
+
toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),
|
|
696
698
|
};
|
|
697
|
-
/*
|
|
699
|
+
/* API */
|
|
698
700
|
const url = getUrl(this.hostname, this.port, config);
|
|
699
701
|
return http$(url, 'one', configCustom, () => executeHttp(url, initCustom));
|
|
700
702
|
}
|
|
@@ -708,12 +710,12 @@ class UniHttpManager {
|
|
|
708
710
|
...config.init,
|
|
709
711
|
method: 'DELETE',
|
|
710
712
|
};
|
|
711
|
-
/*
|
|
713
|
+
/* Config custom (toast di default) */
|
|
712
714
|
const configCustom = {
|
|
713
715
|
...config,
|
|
714
|
-
toast: config.
|
|
716
|
+
toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),
|
|
715
717
|
};
|
|
716
|
-
/*
|
|
718
|
+
/* API */
|
|
717
719
|
const url = getUrl(this.hostname, this.port, config);
|
|
718
720
|
return http$(url, 'one', configCustom, () => executeHttp(url, initCustom));
|
|
719
721
|
}
|
|
@@ -730,9 +732,9 @@ class UniHttpManager {
|
|
|
730
732
|
...config.init,
|
|
731
733
|
method: 'GET',
|
|
732
734
|
};
|
|
733
|
-
/*
|
|
735
|
+
/* API */
|
|
734
736
|
const url = getUrl(this.hostname, this.port, config);
|
|
735
|
-
return http$(url, '
|
|
737
|
+
return http$(url, 'image', config, () => executeBlob(url, initCustom));
|
|
736
738
|
}
|
|
737
739
|
/**
|
|
738
740
|
* Recupera un file (es. PDF) tramite una richiesta GET e restituisce un Object URL temporaneo.
|
|
@@ -744,12 +746,12 @@ class UniHttpManager {
|
|
|
744
746
|
...config.init,
|
|
745
747
|
method: 'GET',
|
|
746
748
|
};
|
|
747
|
-
/*
|
|
749
|
+
/* Config custom (toast di default) */
|
|
748
750
|
const configCustom = {
|
|
749
751
|
...config,
|
|
750
|
-
toast: config.
|
|
752
|
+
toast: config.hasToast === false ? undefined : (config.toast ?? CONFIG_TOAST_DEFAULT),
|
|
751
753
|
};
|
|
752
|
-
/*
|
|
754
|
+
/* API */
|
|
753
755
|
const url = getUrl(this.hostname, this.port, config);
|
|
754
756
|
return http$(url, 'file', configCustom, () => executeBlob(url, initCustom));
|
|
755
757
|
}
|
|
@@ -766,7 +768,7 @@ class UniHttpManager {
|
|
|
766
768
|
...config.init,
|
|
767
769
|
method: 'GET',
|
|
768
770
|
};
|
|
769
|
-
/*
|
|
771
|
+
/* API */
|
|
770
772
|
const url = getUrl(this.hostname, this.port, config);
|
|
771
773
|
return httpPolling$(url, config, () => executeHttp(url, initCustom));
|
|
772
774
|
}
|
|
@@ -782,7 +784,7 @@ class UniHttpManager {
|
|
|
782
784
|
headers: { 'Content-Type': 'application/json' },
|
|
783
785
|
body: JSON.stringify(body),
|
|
784
786
|
};
|
|
785
|
-
/*
|
|
787
|
+
/* API */
|
|
786
788
|
const url = getUrl(this.hostname, this.port, config);
|
|
787
789
|
return httpPolling$(url, config, () => executeHttp(url, initCustom));
|
|
788
790
|
}
|
|
@@ -802,7 +804,7 @@ class UniHttpManager {
|
|
|
802
804
|
};
|
|
803
805
|
initCustom.body = JSON.stringify(body);
|
|
804
806
|
}
|
|
805
|
-
/*
|
|
807
|
+
/* API */
|
|
806
808
|
const url = getUrl(this.hostname, this.port, config);
|
|
807
809
|
return httpPolling$(url, config, () => executeHttp(url, initCustom));
|
|
808
810
|
}
|
|
@@ -878,7 +880,7 @@ class UniLocaleManager {
|
|
|
878
880
|
* Traduce una label in base al dizionario caricato.
|
|
879
881
|
* Gestisce la composizione della chiave, i parametri dinamici (interpolazione) e il fallback.
|
|
880
882
|
*/
|
|
881
|
-
static translate(key, prefix = 'lbl',
|
|
883
|
+
static translate(key, prefix = 'lbl', params) {
|
|
882
884
|
if (!key)
|
|
883
885
|
return '-';
|
|
884
886
|
// Costruzione chiave: prefissoGlobale + prefissoLocale + LabelConInizialeMaiuscola
|
|
@@ -895,8 +897,8 @@ class UniLocaleManager {
|
|
|
895
897
|
return `🔑 ${finalKey}`;
|
|
896
898
|
}
|
|
897
899
|
// Interpolazione variabili
|
|
898
|
-
if (
|
|
899
|
-
for (const [key, value] of Object.entries(
|
|
900
|
+
if (params) {
|
|
901
|
+
for (const [key, value] of Object.entries(params)) {
|
|
900
902
|
const displayValue = value instanceof Date ? value.toLocaleDateString(this._locale) : String(value);
|
|
901
903
|
translation = translation.replaceAll(`{{${key}}}`, displayValue);
|
|
902
904
|
}
|
|
@@ -995,22 +997,24 @@ class UniToastManager {
|
|
|
995
997
|
* Mostra un toast di successo basato su una risposta HTTP e una label di traduzione.
|
|
996
998
|
*/
|
|
997
999
|
static showHttp(config, res) {
|
|
998
|
-
const {
|
|
1000
|
+
const { params, resParams, formatters } = config;
|
|
999
1001
|
/* Parametri statici di base */
|
|
1000
|
-
const allParams = { ...
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1002
|
+
const allParams = { ...params };
|
|
1003
|
+
if (res !== undefined && res !== null) {
|
|
1004
|
+
/* Se è un array aggiunge il parametro 'count' con la lunghezza dell'array */
|
|
1005
|
+
if (Array.isArray(res)) {
|
|
1006
|
+
allParams['count'] = res.length;
|
|
1007
|
+
}
|
|
1008
|
+
else if (typeof res === 'object' && resParams?.length) {
|
|
1009
|
+
// Se la proprietà NON esiste nella risposta, allora salta
|
|
1010
|
+
for (const resParam of resParams ?? []) {
|
|
1011
|
+
if (!(resParam in res))
|
|
1012
|
+
continue;
|
|
1013
|
+
// Se esiste un formatter per questa chiave lo si usa, altrimenti valore grezzo
|
|
1014
|
+
const rawValue = res[resParam];
|
|
1015
|
+
allParams[resParam] = formatters?.[resParam] ? formatters[resParam](rawValue) : rawValue;
|
|
1016
|
+
}
|
|
1009
1017
|
}
|
|
1010
|
-
}
|
|
1011
|
-
/* Config parametro lunghezza risposta: conteggio array */
|
|
1012
|
-
if (resLengthParam && Array.isArray(res)) {
|
|
1013
|
-
allParams[resLengthParam] = res.length;
|
|
1014
1018
|
}
|
|
1015
1019
|
/* Messaggio tradotto */
|
|
1016
1020
|
this.show({ ...config, params: allParams });
|