valtech-components 2.0.839 → 2.0.841

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.
@@ -49,7 +49,6 @@ export declare class ChangePasswordModalComponent {
49
49
  /** Modo actual — `loading` mientras se consulta `checkHasPassword()`. */
50
50
  readonly mode: import("@angular/core").Signal<PasswordModalMode>;
51
51
  private readonly _formState;
52
- constructor();
53
52
  /** Traduce una clave del namespace `_auth`. */
54
53
  t(key: string): string;
55
54
  readonly formProps: import("@angular/core").Signal<FormMetadata>;
@@ -0,0 +1,26 @@
1
+ import { HttpInterceptorFn } from '@angular/common/http';
2
+ /**
3
+ * Interceptor HTTP de observabilidad (Capa 1 del estándar de manejo de errores).
4
+ *
5
+ * Para CADA respuesta HTTP con error:
6
+ * 1. Normaliza el error con `interpretError`.
7
+ * 2. Loguea un evento estructurado a consola con el prefijo `[HTTP]`.
8
+ * 3. Reporta el error a Firebase Analytics (`source: 'http'`), si hay analytics.
9
+ *
10
+ * **NO traga el error** — lo re-lanza tal cual. Las páginas y servicios siguen
11
+ * recibiendo el error en su `catch` / `catchError` y deciden la UX (eso es
12
+ * Capa 3: `ValtechErrorService`).
13
+ *
14
+ * `AnalyticsService` se inyecta `@Optional()` — apps sin Firebase Analytics
15
+ * igual obtienen el log estructurado a consola.
16
+ *
17
+ * Decisión sobre 401: **se saltea** del tracking de Analytics. Un 401 es el
18
+ * disparador normal del flujo de refresh de token del `authInterceptor`; el
19
+ * token se renueva y la request se reintenta de forma transparente. Trackear
20
+ * cada 401 inundaría Analytics de ruido (cada sesión genera varios al expirar
21
+ * el access token). El 401 SÍ se loguea a consola (nivel `info`, no `error`)
22
+ * para no perder la traza en debugging local, pero no se reporta como error.
23
+ *
24
+ * Se registra vía {@link provideValtechErrorHandling}.
25
+ */
26
+ export declare const errorLoggingInterceptor: HttpInterceptorFn;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Estándar de manejo de errores del factory Valtech.
3
+ *
4
+ * - `interpretError` (Capa 0) — normaliza cualquier error a `InterpretedError`.
5
+ * Función pura, sin Angular DI.
6
+ * - `provideValtechErrorHandling` (Capa 1) — registra el interceptor HTTP de
7
+ * observabilidad: log estructurado + reporte a Analytics, re-lanza el error.
8
+ * - `ValtechErrorService` (Capa 3) — punto único para el `catch` de una página:
9
+ * normaliza, observa, resuelve un mensaje i18n y muestra un toast.
10
+ */
11
+ export { interpretError } from './interpret-error';
12
+ export type { InterpretedError } from './interpret-error';
13
+ export { errorLoggingInterceptor } from './error-logging.interceptor';
14
+ export { provideValtechErrorHandling } from './provide-error-handling';
15
+ export { ValtechErrorService, VALTECH_NETWORK_ERROR_KEY } from './valtech-error.service';
16
+ export type { ValtechErrorHandleOptions } from './valtech-error.service';
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Error interpretation helper for the Valtech factory.
3
+ *
4
+ * Todos los frontends del factory consumen la misma API (backend Go) y la misma
5
+ * librería. La lógica de interpretar errores debe vivir una sola vez, acá.
6
+ *
7
+ * El backend Go (`apperrors`) SIEMPRE devuelve errores como JSON:
8
+ * { "code": string, "message": string, "operationId": string }
9
+ * donde `message` ya viene en español y es user-friendly.
10
+ *
11
+ * En Angular un error HTTP llega como `HttpErrorResponse` (body en `.error`).
12
+ * Un fallo de red es un `HttpErrorResponse` con `status === 0`.
13
+ *
14
+ * Además `AuthService.handleAuthError` aplana el `HttpErrorResponse` a un
15
+ * `AuthError { code, message }` (code/message al nivel superior). Por eso este
16
+ * helper acepta AMBAS formas — el crudo y el aplanado.
17
+ */
18
+ /**
19
+ * Resultado normalizado de cualquier error. Garantiza una forma estable y
20
+ * predecible para que las webapps no tengan que hacer narrowing manual.
21
+ */
22
+ export interface InterpretedError {
23
+ /** Código del backend, o el sentinel `'NETWORK'` / `'UNKNOWN'`. */
24
+ code: string;
25
+ /** Mensaje del backend (español, user-friendly) o un genérico en español. */
26
+ message: string;
27
+ /** `operationId` del backend, si vino. Útil para soporte / tracing. */
28
+ operationId?: string;
29
+ /** HTTP status, si aplica (`0` para fallos de red). */
30
+ status?: number;
31
+ /** `true` si fue un fallo de red (status 0 / sin respuesta). */
32
+ isNetwork: boolean;
33
+ }
34
+ /**
35
+ * Normaliza CUALQUIER error a un `InterpretedError`.
36
+ *
37
+ * Función pura — sin dependencias de Angular DI, testeable y usable desde
38
+ * cualquier lado (componentes, servicios, interceptores, scripts).
39
+ *
40
+ * Nunca lanza: siempre devuelve un `InterpretedError` válido.
41
+ *
42
+ * Casos cubiertos:
43
+ * - `HttpErrorResponse` con `status === 0` (o sin respuesta) → fallo de red.
44
+ * - `HttpErrorResponse` con body `{ code, message, operationId }` del backend.
45
+ * - `AuthError` aplanado `{ code, message }` (code/message top-level).
46
+ * - `Error` plano de JS → `code: 'UNKNOWN'`, `message: err.message`.
47
+ * - Cualquier otra cosa (string, null, undefined, objeto raro) → genérico.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * try {
52
+ * await firstValueFrom(this.http.get(url));
53
+ * } catch (err) {
54
+ * const e = interpretError(err);
55
+ * if (e.isNetwork) {
56
+ * this.toast.show({ message: e.message, color: 'dark' });
57
+ * } else {
58
+ * this.errorCode.set(e.code);
59
+ * }
60
+ * }
61
+ * ```
62
+ */
63
+ export declare function interpretError(err: unknown): InterpretedError;
@@ -0,0 +1,34 @@
1
+ import { EnvironmentProviders } from '@angular/core';
2
+ /**
3
+ * Provee el manejo de errores estándar del factory Valtech.
4
+ *
5
+ * Registra el {@link errorLoggingInterceptor} (Capa 1 — observabilidad): toda
6
+ * respuesta HTTP con error se normaliza, se loguea de forma estructurada a
7
+ * consola y se reporta a Firebase Analytics. El interceptor **re-lanza** el
8
+ * error, así que las páginas siguen haciendo su `catch`.
9
+ *
10
+ * Se registra vía `withInterceptors`, igual que el `authInterceptor`. Angular
11
+ * fusiona los interceptores de múltiples llamadas a `provideHttpClient` dentro
12
+ * del mismo injector, así que esto compone con `provideValtechAuth()` sin
13
+ * pisarlo. El orden relativo lo determina Angular por orden de provisión;
14
+ * para una traza limpia, declarar `provideValtechErrorHandling()` **después**
15
+ * de `provideValtechAuth(...)` en `main.ts`.
16
+ *
17
+ * La Capa 3 ({@link ValtechErrorService}) es `providedIn: 'root'` — no
18
+ * requiere registro. La Capa 2 (`AnalyticsErrorHandler`, errores no
19
+ * capturados) la activa `provideValtechFirebase` con `enableErrorTracking`.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // main.ts
24
+ * import { provideValtechAuth, provideValtechErrorHandling } from 'valtech-components';
25
+ *
26
+ * bootstrapApplication(AppComponent, {
27
+ * providers: [
28
+ * provideValtechAuth({ apiUrl: environment.apiUrl }),
29
+ * provideValtechErrorHandling(),
30
+ * ],
31
+ * });
32
+ * ```
33
+ */
34
+ export declare function provideValtechErrorHandling(): EnvironmentProviders;
@@ -0,0 +1,102 @@
1
+ import { InterpretedError } from './interpret-error';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Key i18n fija de la librería para fallos de red. Las apps pueden definirla en
5
+ * su contenido i18n (namespace `_global`) para personalizar el texto; si no
6
+ * existe, se usa {@link NETWORK_FALLBACK_MESSAGE}.
7
+ */
8
+ export declare const VALTECH_NETWORK_ERROR_KEY = "valtech.error.network";
9
+ /**
10
+ * Opciones de {@link ValtechErrorService.handle}.
11
+ */
12
+ export interface ValtechErrorHandleOptions {
13
+ /**
14
+ * Identificador del punto de fallo, ej. `'profile.save'`. Se incluye en el
15
+ * log de consola y en el reporte a Analytics para facilitar el tracing.
16
+ */
17
+ context?: string;
18
+ /**
19
+ * Mapa `código de backend → key i18n`. Lo provee la app, que conoce sus
20
+ * propias traducciones. Ej. `{ EMAIL_TAKEN: 'errors.emailTaken' }`.
21
+ */
22
+ i18nMap?: Record<string, string>;
23
+ /**
24
+ * Key i18n a usar cuando no hay match en `i18nMap` (y el error no es de red).
25
+ * Si se omite, se usa un mensaje genérico en español.
26
+ */
27
+ fallbackKey?: string;
28
+ /**
29
+ * Namespace i18n para resolver `i18nMap` / `fallbackKey` / la key de red.
30
+ * Default: `_global`.
31
+ */
32
+ i18nNamespace?: string;
33
+ /** Si mostrar un toast con el mensaje resuelto. Default: `true`. */
34
+ toast?: boolean;
35
+ }
36
+ /**
37
+ * Servicio de UX de errores capturados (Capa 3 del estándar de manejo de errores).
38
+ *
39
+ * Mientras la Capa 1 ({@link errorLoggingInterceptor}) observa TODAS las
40
+ * respuestas HTTP con error, y la Capa 2 (`AnalyticsErrorHandler`) captura los
41
+ * errores NO manejados, la Capa 3 es el punto único que una página usa en su
42
+ * `catch` para convertir un error en feedback al usuario.
43
+ *
44
+ * Responsabilidades de {@link handle}:
45
+ * 1. Normaliza el error (`interpretError`).
46
+ * 2. Loguea a consola + reporta a Analytics (`source: 'handled'`, con `context`).
47
+ * 3. Resuelve un mensaje localizado (ver orden de resolución en {@link handle}).
48
+ * 4. Muestra un toast (`color: 'dark'`, estándar Valtech) salvo `toast: false`.
49
+ * 5. Devuelve el {@link InterpretedError} para que la página decida lógica extra.
50
+ *
51
+ * **Nunca lanza.** `AnalyticsService` se inyecta `@Optional()`.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * private errors = inject(ValtechErrorService);
56
+ *
57
+ * async save() {
58
+ * try {
59
+ * await firstValueFrom(this.api.updateProfile(this.form.value));
60
+ * this.toast.show({ message: 'Perfil actualizado', color: 'dark' });
61
+ * } catch (err) {
62
+ * this.errors.handle(err, {
63
+ * context: 'profile.save',
64
+ * i18nMap: { EMAIL_TAKEN: 'errors.emailTaken' },
65
+ * fallbackKey: 'errors.profileSaveFailed',
66
+ * });
67
+ * }
68
+ * }
69
+ * ```
70
+ */
71
+ export declare class ValtechErrorService {
72
+ private readonly i18n;
73
+ private readonly toast;
74
+ private readonly analytics;
75
+ /**
76
+ * Maneja un error capturado: normaliza, observa y produce feedback de usuario.
77
+ *
78
+ * Orden de resolución del mensaje del toast:
79
+ * 1. `i18nMap[code]` definido → `i18n.t(esa key)`.
80
+ * 2. Sin match y `isNetwork` → key de red ({@link VALTECH_NETWORK_ERROR_KEY}),
81
+ * con fallback al texto español si la app no la tradujo.
82
+ * 3. `fallbackKey` definido → `i18n.t(fallbackKey)`.
83
+ * 4. Genérico en español.
84
+ *
85
+ * @param err Cualquier error capturado.
86
+ * @param opts Opciones de contexto, mapeo i18n y toast.
87
+ * @returns El {@link InterpretedError} normalizado. Nunca lanza.
88
+ */
89
+ handle(err: unknown, opts?: ValtechErrorHandleOptions): InterpretedError;
90
+ /**
91
+ * Resuelve el mensaje a mostrar siguiendo el orden documentado en {@link handle}.
92
+ */
93
+ private resolveMessage;
94
+ /**
95
+ * Traduce una key i18n. Devuelve `null` si la key no está definida — el
96
+ * `I18nService` devuelve un placeholder `[namespace.key]` para keys faltantes;
97
+ * lo detectamos para poder caer a un fallback en lugar de mostrar el placeholder.
98
+ */
99
+ private translate;
100
+ static ɵfac: i0.ɵɵFactoryDeclaration<ValtechErrorService, never>;
101
+ static ɵprov: i0.ɵɵInjectableDeclaration<ValtechErrorService>;
102
+ }
package/lib/version.d.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * Current version of valtech-components.
3
3
  * This is automatically updated during the publish process.
4
4
  */
5
- export declare const VERSION = "2.0.839";
5
+ export declare const VERSION = "2.0.841";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valtech-components",
3
- "version": "2.0.839",
3
+ "version": "2.0.841",
4
4
  "private": false,
5
5
  "bin": {
6
6
  "valtech-firebase-config": "./src/lib/services/firebase/scripts/generate-sw-config.js"
package/public-api.d.ts CHANGED
@@ -255,6 +255,7 @@ export * from './lib/services/navigation';
255
255
  export * from './lib/services/theme.service';
256
256
  export * from './lib/services/toast.service';
257
257
  export * from './lib/services/types';
258
+ export * from './lib/services/errors';
258
259
  export * from './lib/services/confirmation-dialog/confirmation-dialog.service';
259
260
  export * from './lib/services/confirmation-dialog/types';
260
261
  export * from './lib/services/qr-generator/qr-generator.service';