import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { ValtechAuthConfig } from '../auth/types'; import * as i0 from "@angular/core"; export type PermissionScope = 'app' | 'org' | 'internal'; /** Etiqueta legible por idioma (es/en). El backend es autoritativo (ADR-024). */ export type LocalizedLabel = Record; export interface PermissionResource { resource: string; scope: PermissionScope; appId?: string; actions: string[]; /** Nombre legible del recurso (es/en), provisto por el backend. */ label?: LocalizedLabel; } export interface PermissionCatalogResponse { operationId: string; appId: string; permissions: PermissionResource[]; /** Nombre legible (es/en) por acción, transversal a los recursos. */ actionLabels?: Record; } /** * Consume el catálogo de permisos del backend (`GET /org/{orgId}/permissions-catalog`). * El backend es la fuente de verdad de qué permisos existen y de su alcance * (globales de plataforma vs. propios de una app). La respuesta incluye el * `appId` del request para que la vista distinga la app actual. * * Promovido desde `showcase` a la lib bajo el proceso de ADR-021. Usa * `VALTECH_AUTH_CONFIG.apiUrl` (como `OrgService`) en vez del `environment` de la * app — la lib no importa el environment del consumer. */ export declare class PermissionCatalogService { private config; private http; constructor(config: ValtechAuthConfig, http: HttpClient); getCatalog(orgId: string): Observable; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } /** Función que resuelve un permiso `resource:action` a su label legible. */ export type PermissionLabeler = (perm: string) => string; /** * Construye el resolvedor de labels de permisos a partir del catálogo del backend * (fuente única de verdad de los labels, ADR-024). Los consumers (permissions-view, * organization-view, member-detail-modal) usan esto en vez de duplicar mapas * hardcodeados `resource→key`/`action→key`. * * - Recurso → `permissions[].label[locale]`; acción → `actionLabels[action][locale]`. * - Wildcards (`*:*`, `resource:*`, `*`) usan `allLabel` (el catálogo no modela el * comodín; el consumer pasa su string i18n, p.ej. "Todos los permisos"). * - Fallback humanizado si el catálogo no trae label (evita salidas vacías como * ": Gestionar" ante un recurso/acción nuevo aún sin etiqueta en el backend). */ export declare function createPermissionLabeler(catalog: Pick, locale: string, opts?: { allLabel?: string; }): PermissionLabeler; /** Alcance de un grupo de permisos: app actual · organización · otra app. */ export type PermissionGroupScope = 'app' | 'org' | 'other'; /** Grupo de permisos agrupados por alcance, con sus labels ya resueltos. */ export interface PermissionScopeGroup { /** Clave estable de track (`app` · `org` · `other:{appId}`). */ key: string; /** Label del badge de alcance (ya traducido). */ label: string; scope: PermissionGroupScope; /** AppId de la otra app (solo cuando `scope === 'other'`). */ appId?: string; /** Labels de cada permiso del grupo (ya resueltos por el labeler). */ perms: string[]; } /** * Etiquetas i18n de los grupos de alcance + resolvedor de nombre de app, que el * consumer pasa ya traducidos (la lib no resuelve i18n por su cuenta acá). */ export interface PermissionGroupLabels { /** Label del grupo "Permisos de la app". */ app: string; /** Label del grupo "Permisos de la organización". */ org: string; /** Prefijo del grupo de otra app (se concatena con el nombre de la app). */ other: string; /** Resuelve el nombre legible de una app por su appId. */ appLabel: (appId: string) => string; } /** * Agrupa una lista de permisos (`resource:action`) por alcance — app actual / * organización / otras apps — usando el catálogo del backend como SSOT del scope * (`PermissionResource.scope` + `appId`). Cada permiso se etiqueta con `labeler`. * * Reutilizado por `val-permissions-view` y `val-member-detail-modal` para que * ambos muestren los chips agrupados y tintados de forma idéntica. Función pura * (sin Angular DI) — el consumer pasa los labels i18n ya resueltos. * * - Recursos ausentes del catálogo o con `scope === 'internal'` se descartan * (defensa en profundidad junto al filtro del backend, ADR-024). * - `scope === 'app'` con `appId === currentAppId` → grupo `app`; otro appId → * grupo `other:{appId}`. `scope === 'org'` → grupo `org`. */ export declare function groupPermissionsByScope(permissions: string[], catalog: Pick, currentAppId: string, labeler: PermissionLabeler, labels: PermissionGroupLabels): PermissionScopeGroup[];