@jantstack/adonis-authz 1.1.0 → 2.0.0-alpha.1

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.
Files changed (132) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +417 -58
  3. package/build/commands/authz_catalog_diff.d.ts +28 -0
  4. package/build/commands/authz_catalog_diff.d.ts.map +1 -0
  5. package/build/commands/authz_catalog_diff.js +67 -0
  6. package/build/commands/authz_catalog_diff.js.map +1 -0
  7. package/build/commands/authz_catalog_sync.d.ts +20 -0
  8. package/build/commands/authz_catalog_sync.d.ts.map +1 -0
  9. package/build/commands/authz_catalog_sync.js +58 -0
  10. package/build/commands/authz_catalog_sync.js.map +1 -0
  11. package/build/commands/main.d.ts +2 -0
  12. package/build/commands/main.d.ts.map +1 -1
  13. package/build/commands/main.js +2 -0
  14. package/build/commands/main.js.map +1 -1
  15. package/build/commands/openfga_import.d.ts +8 -2
  16. package/build/commands/openfga_import.d.ts.map +1 -1
  17. package/build/commands/openfga_import.js +29 -6
  18. package/build/commands/openfga_import.js.map +1 -1
  19. package/build/commands/openfga_provision.d.ts.map +1 -1
  20. package/build/commands/openfga_provision.js +2 -1
  21. package/build/commands/openfga_provision.js.map +1 -1
  22. package/build/index.d.ts +45 -6
  23. package/build/index.d.ts.map +1 -1
  24. package/build/index.js +37 -4
  25. package/build/index.js.map +1 -1
  26. package/build/src/catalog.d.ts +249 -2
  27. package/build/src/catalog.d.ts.map +1 -1
  28. package/build/src/catalog.js +709 -59
  29. package/build/src/catalog.js.map +1 -1
  30. package/build/src/catalog_cache.d.ts +300 -0
  31. package/build/src/catalog_cache.d.ts.map +1 -0
  32. package/build/src/catalog_cache.js +656 -0
  33. package/build/src/catalog_cache.js.map +1 -0
  34. package/build/src/clock.d.ts +24 -0
  35. package/build/src/clock.d.ts.map +1 -0
  36. package/build/src/clock.js +7 -0
  37. package/build/src/clock.js.map +1 -0
  38. package/build/src/define_config.d.ts +102 -6
  39. package/build/src/define_config.d.ts.map +1 -1
  40. package/build/src/define_config.js.map +1 -1
  41. package/build/src/drivers/backend_guard.d.ts +92 -0
  42. package/build/src/drivers/backend_guard.d.ts.map +1 -0
  43. package/build/src/drivers/backend_guard.js +221 -0
  44. package/build/src/drivers/backend_guard.js.map +1 -0
  45. package/build/src/drivers/database_driver.d.ts +242 -15
  46. package/build/src/drivers/database_driver.d.ts.map +1 -1
  47. package/build/src/drivers/database_driver.js +692 -127
  48. package/build/src/drivers/database_driver.js.map +1 -1
  49. package/build/src/drivers/openfga_driver.d.ts +341 -27
  50. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  51. package/build/src/drivers/openfga_driver.js +1020 -271
  52. package/build/src/drivers/openfga_driver.js.map +1 -1
  53. package/build/src/drivers/sql_expiry.d.ts +53 -0
  54. package/build/src/drivers/sql_expiry.d.ts.map +1 -0
  55. package/build/src/drivers/sql_expiry.js +66 -0
  56. package/build/src/drivers/sql_expiry.js.map +1 -0
  57. package/build/src/errors.d.ts +333 -0
  58. package/build/src/errors.d.ts.map +1 -1
  59. package/build/src/errors.js +352 -0
  60. package/build/src/errors.js.map +1 -1
  61. package/build/src/expiry.d.ts +27 -0
  62. package/build/src/expiry.d.ts.map +1 -0
  63. package/build/src/expiry.js +50 -0
  64. package/build/src/expiry.js.map +1 -0
  65. package/build/src/hierarchical_resolver.d.ts +56 -0
  66. package/build/src/hierarchical_resolver.d.ts.map +1 -0
  67. package/build/src/hierarchical_resolver.js +87 -0
  68. package/build/src/hierarchical_resolver.js.map +1 -0
  69. package/build/src/identity.d.ts +155 -0
  70. package/build/src/identity.d.ts.map +1 -0
  71. package/build/src/identity.js +359 -0
  72. package/build/src/identity.js.map +1 -0
  73. package/build/src/manager.d.ts +225 -7
  74. package/build/src/manager.d.ts.map +1 -1
  75. package/build/src/manager.js +1670 -23
  76. package/build/src/manager.js.map +1 -1
  77. package/build/src/memoize_ancestors.d.ts +23 -0
  78. package/build/src/memoize_ancestors.d.ts.map +1 -0
  79. package/build/src/memoize_ancestors.js +42 -0
  80. package/build/src/memoize_ancestors.js.map +1 -0
  81. package/build/src/middleware/app_access_middleware.d.ts +8 -6
  82. package/build/src/middleware/app_access_middleware.d.ts.map +1 -1
  83. package/build/src/middleware/app_access_middleware.js +10 -26
  84. package/build/src/middleware/app_access_middleware.js.map +1 -1
  85. package/build/src/models/authz_assignment.d.ts +5 -5
  86. package/build/src/models/authz_assignment.d.ts.map +1 -1
  87. package/build/src/models/authz_deny.d.ts +5 -5
  88. package/build/src/models/authz_deny.d.ts.map +1 -1
  89. package/build/src/models/authz_permission.d.ts +11 -5
  90. package/build/src/models/authz_permission.d.ts.map +1 -1
  91. package/build/src/models/authz_permission.js +4 -0
  92. package/build/src/models/authz_permission.js.map +1 -1
  93. package/build/src/models/authz_role.d.ts +13 -6
  94. package/build/src/models/authz_role.d.ts.map +1 -1
  95. package/build/src/models/authz_role.js +6 -1
  96. package/build/src/models/authz_role.js.map +1 -1
  97. package/build/src/models/authz_role_permission.d.ts +5 -5
  98. package/build/src/models/authz_role_permission.d.ts.map +1 -1
  99. package/build/src/openfga.d.ts +13 -0
  100. package/build/src/openfga.d.ts.map +1 -0
  101. package/build/src/openfga.js +12 -0
  102. package/build/src/openfga.js.map +1 -0
  103. package/build/src/sql_descendants.d.ts +51 -0
  104. package/build/src/sql_descendants.d.ts.map +1 -0
  105. package/build/src/sql_descendants.js +129 -0
  106. package/build/src/sql_descendants.js.map +1 -0
  107. package/build/src/testing/contract.d.ts +138 -7
  108. package/build/src/testing/contract.d.ts.map +1 -1
  109. package/build/src/testing/contract.js +2946 -24
  110. package/build/src/testing/contract.js.map +1 -1
  111. package/build/src/testing/main.d.ts +4 -2
  112. package/build/src/testing/main.d.ts.map +1 -1
  113. package/build/src/testing/main.js +2 -1
  114. package/build/src/testing/main.js.map +1 -1
  115. package/build/src/testing/scope_tree.d.ts +65 -0
  116. package/build/src/testing/scope_tree.d.ts.map +1 -0
  117. package/build/src/testing/scope_tree.js +145 -0
  118. package/build/src/testing/scope_tree.js.map +1 -0
  119. package/build/src/traits/authz_scopes.d.ts +30 -6
  120. package/build/src/traits/authz_scopes.d.ts.map +1 -1
  121. package/build/src/traits/authz_scopes.js +30 -18
  122. package/build/src/traits/authz_scopes.js.map +1 -1
  123. package/build/src/traits/has_uuid.d.ts +5 -5
  124. package/build/src/traits/has_uuid.d.ts.map +1 -1
  125. package/build/src/types.d.ts +530 -28
  126. package/build/src/types.d.ts.map +1 -1
  127. package/build/src/types.js +10 -4
  128. package/build/src/types.js.map +1 -1
  129. package/build/stubs/config/app_acl.stub +4 -2
  130. package/build/stubs/config/authorization.stub +66 -12
  131. package/build/stubs/migration.stub +57 -13
  132. package/package.json +11 -6
@@ -12,10 +12,12 @@
12
12
  * suite corre contra cada driver — es el juez del contrato):
13
13
  *
14
14
  * 1. **Scopes jerárquicos, herencia SOLO hacia abajo.** La cadena de un scope
15
- * es `[scope, ...ancestros]` (`app` es la raíz: su cadena es él mismo).
15
+ * es `[scope canónico, ...ancestros]` (`app` es la raíz: su cadena es él
16
+ * mismo); la identidad de un scope es la que devuelve el resolutor, nunca
17
+ * la forma con la que lo escribió el llamante (2.5-B · K1).
16
18
  * Un grant en un scope autoriza en ese scope y en TODOS sus descendientes;
17
19
  * nunca en hermanos ni ancestros. En T1 solo opera `app` (los ancestros de
18
- * `organization`/`unit` se completan en T2/T3 vía `resolveAncestors`).
20
+ * `organization`/`unit` se completan en T2/T3 vía `resolveChain`).
19
21
  * 2. **Deny explícito gana.** Un deny de un permiso en cualquier scope de la
20
22
  * cadena bloquea `authorize`, aunque un rol lo conceda (el deny también
21
23
  * hereda hacia abajo). Quitar el deny restaura el permiso.
@@ -28,8 +30,12 @@
28
30
  * holder sin asignación vigente → `false`, nunca throw en `authorize`.
29
31
  * En cambio `grant`/`deny` con rol/permiso fuera del catálogo → throw
30
32
  * (error de programación, no de autorización).
31
- * 6. **Idempotencia de escritura.** Re-`grant` no duplica (actualiza
32
- * `expiresAt`); re-`revoke`/re-`deny`/re-`removeDeny` son no-ops seguros.
33
+ * 6. **Idempotencia de escritura.** Re-`grant` no duplica (`expiresAt` en
34
+ * tres estados: omitido preserva, `null` quita, `Date` fija);
35
+ * re-`revoke`/re-`deny`/re-`removeDeny` son no-ops seguros.
36
+ * 7. **El árbol es un hecho del contrato.** Un scope que el resolutor no
37
+ * conoce (`null`) deniega, no lista y no admite escrituras; `purgeScope`
38
+ * borra los hechos del scope exacto (los del catálogo) y demuestra cero.
33
39
  */
34
40
  /** Referencia polimórfica al holder: morph name + uuid. */
35
41
  export interface SubjectRef {
@@ -40,7 +46,7 @@ export interface SubjectRef {
40
46
  * Nivel de scope. El motor solo conoce la raíz (`app`, uuid null); los demás
41
47
  * niveles los define el CONSUMIDOR — `organization`/`unit` en este chasis,
42
48
  * pero podrían ser `project`, `site`, `case`… El árbol lo declara el
43
- * `ScopeAncestorsResolver` que se inyecta a los drivers, así que el motor no
49
+ * `ScopeChainResolver` que se inyecta a los drivers, así que el motor no
44
50
  * necesita conocer la taxonomía.
45
51
  *
46
52
  * Un consumidor que quiera seguridad de tipos define su propia unión:
@@ -56,10 +62,106 @@ export interface ScopeRef {
56
62
  }
57
63
  /** El scope raíz de aplicación (nivel plataforma). */
58
64
  export declare const APP_SCOPE: ScopeRef;
59
- export interface GrantOptions {
60
- /** Expiración de la asignación. `null`/omitido = sin expiración. */
65
+ /**
66
+ * Opciones comunes a TODA escritura del manager (`grant`, `revoke`, `deny`,
67
+ * `removeDeny`, `scopes.*`) — 2.1, B7.
68
+ */
69
+ export interface WriteOptions {
70
+ /**
71
+ * Quién ordena la escritura. Se valida como identidad (422 si está mal
72
+ * formado) y viaja en `AuthzWriteEvent.actor` para que la auditoría del
73
+ * consumidor no dependa de un `AsyncLocalStorage` que el paquete no tiene.
74
+ * Con `requireActor: true` en el config, omitirlo es 422
75
+ * `E_AUTHZ_ACTOR_REQUIRED` antes de tocar el driver. El motor NO lo evalúa:
76
+ * quién puede conceder qué es policy del consumidor (invariante 8).
77
+ */
78
+ actor?: SubjectRef;
79
+ }
80
+ /**
81
+ * Opciones de las NUEVE escrituras del manager (`grant`, `revoke`, `deny`,
82
+ * `removeDeny`, `scopes.attached/moved/detached` y, desde 3D · M3, la API de
83
+ * delegación `defineScopedRole`/`updateScopedRole`/`deleteScopedRole`) —
84
+ * 2.1, B1; 2D · F2.
85
+ */
86
+ export interface ScopedWriteOptions extends WriteOptions {
87
+ /**
88
+ * Contención: el scope de la escritura tiene que estar DENTRO de `within`
89
+ * (`within ∈ chain(scope)`, inclusive; `APP_SCOPE` contiene todo). Si no,
90
+ * 422 `E_AUTHZ_NOT_WITHIN` y nada se escribe. Es lo que impide que el
91
+ * administrador de la organización A conceda en una unit de B pasando un
92
+ * uuid ajeno: el call-site declara "dentro de MI tenant" y el motor lo
93
+ * comprueba contra el árbol, en fresco (nunca con el memo por request).
94
+ * Qué scope se contrasta: el de `grant`/`revoke`/`deny`/`removeDeny`; el
95
+ * PADRE (nuevo) Y la cadena ACTUAL del hijo en `scopes.moved` (origen y
96
+ * destino, 2E · H1: notifica ANTES de recolgar tu fila), lo mismo en
97
+ * `scopes.attached` cuando el hijo ya existe (es un move; un nodo nuevo
98
+ * solo contrasta el padre); el propio hijo en `scopes.detached`; el OWNER
99
+ * del rol en `defineScopedRole`/`updateScopedRole`/`deleteScopedRole`. Con
100
+ * `requireWithin: true` en el config, omitirlo es 422
101
+ * `E_AUTHZ_WITHIN_REQUIRED`; con `'non-root'`, además `APP_SCOPE` como
102
+ * `within` es 422 `E_AUTHZ_WITHIN_ROOT_FORBIDDEN` (no acota nada).
103
+ * `within` viene de la SESIÓN (el tenant autenticado), nunca del cuerpo
104
+ * de la petición: `within = scope` satisface siempre por definición.
105
+ */
106
+ within?: ScopeRef;
107
+ }
108
+ export interface GrantOptions extends ScopedWriteOptions {
109
+ /**
110
+ * Caducidad de la asignación, en TRES estados (L0.4):
111
+ * - omitido: no tocar una caducidad vigente (si la asignación ya había
112
+ * expirado, revive sin caducidad);
113
+ * - `null`: quitar la caducidad;
114
+ * - `Date`: fijarla.
115
+ * Antes "omitido" borraba la caducidad: un "asegúrate de que tiene el rol"
116
+ * convertía un acceso temporal en permanente.
117
+ */
61
118
  expiresAt?: Date | null;
62
119
  }
120
+ /** Opciones de `deny` (2.1): contención y actor; sin caducidad (un deny que caduca es fail-open por reloj). */
121
+ export type DenyOptions = ScopedWriteOptions;
122
+ /** Lo que un `grant` hizo, para que el manager audite y el juez lo observe. */
123
+ export interface GrantOutcome {
124
+ /** Ya había una asignación de ese rol en ese scope exacto. */
125
+ existed: boolean;
126
+ /** Caducidad que tenía antes (solo si `existed` y se pudo leer). */
127
+ previousExpiresAt?: Date | null;
128
+ /** Caducidad con la que queda tras la escritura. */
129
+ expiresAt: Date | null;
130
+ }
131
+ /**
132
+ * Cómo se direcciona un rol en el puerto (`grant`, `revoke`, `hasRole`,
133
+ * `listSubjects`).
134
+ *
135
+ * - **string** (slug): en cada nivel de la cadena solo cuenta el rol de ESE
136
+ * nivel (el `owner` de app casa en app y hereda hacia abajo; un `owner` de
137
+ * organization jamás casa en app).
138
+ * - **`{ slug, scopeType }`**: el rol de un nivel concreto; solo los scopes
139
+ * de la cadena de ese tipo cuentan (L0.6).
140
+ * - **`{ uuid }`** (3D · M1): la forma EXACTA. Desde que un rol puede ser
141
+ * local a un scope (3B), el slug NO identifica un rol —dos tenants definen
142
+ * `lead@unit`— y un `scopes.moved` legítimo puede juntar dos homónimos en
143
+ * la misma cadena: entonces las dos formas por slug fallan cerradas con
144
+ * 422 `E_AUTHZ_AMBIGUOUS_ROLE` y esta es la única que responde. El uuid
145
+ * tiene que estar en el catálogo (422 `E_AUTHZ_UNKNOWN_ROLE`) y ser
146
+ * visible en el scope de la operación —declarado para su nivel y global o
147
+ * con el owner en la cadena— (422 `E_AUTHZ_ROLE_NOT_VISIBLE`).
148
+ */
149
+ export type RoleQuery = string | {
150
+ slug: string;
151
+ scopeType: ScopeType;
152
+ } | {
153
+ uuid: string;
154
+ };
155
+ /** `RoleQuery` ya validado (`normalizeRoleQuery`): o nombre, o identidad; nunca las dos. */
156
+ export type NormalizedRoleQuery = {
157
+ slug: string;
158
+ scopeType?: ScopeType;
159
+ uuid?: undefined;
160
+ } | {
161
+ uuid: string;
162
+ slug?: undefined;
163
+ scopeType?: undefined;
164
+ };
63
165
  export interface AuthorizationDriver {
64
166
  /**
65
167
  * ¿El holder tiene el permiso en el scope? Evalúa la cadena completa:
@@ -69,26 +171,43 @@ export interface AuthorizationDriver {
69
171
  authorize(subject: SubjectRef, permission: string, scope: ScopeRef): Promise<boolean>;
70
172
  /**
71
173
  * Asigna un rol al holder en un scope. El rol debe existir en el catálogo
72
- * para `scope.type` (throw si no). Idempotente: re-grant actualiza expiresAt.
174
+ * para `scope.type` (422 si no) y el scope para el resolutor (422 si no).
175
+ * Idempotente: re-grant no duplica; `expiresAt` sigue los tres estados de
176
+ * `GrantOptions`. Devuelve qué hizo (`GrantOutcome`).
177
+ */
178
+ grant(subject: SubjectRef, role: RoleQuery, scope: ScopeRef, options?: GrantOptions): Promise<GrantOutcome>;
179
+ /**
180
+ * Quita la asignación del rol en ese scope exacto. El rol debe existir en
181
+ * el catálogo para `scope.type` (422 si no, como `grant`); la asignación
182
+ * puede no existir (no-op).
73
183
  */
74
- grant(subject: SubjectRef, role: string, scope: ScopeRef, options?: GrantOptions): Promise<void>;
75
- /** Quita la asignación del rol en ese scope exacto. No-op si no existía. */
76
- revoke(subject: SubjectRef, role: string, scope: ScopeRef): Promise<void>;
184
+ revoke(subject: SubjectRef, role: RoleQuery, scope: ScopeRef): Promise<void>;
77
185
  /**
78
186
  * ¿El holder tiene el rol (vigente) en el scope o en un ancestro?
79
- * Misma regla de herencia hacia abajo que `authorize`.
187
+ * Misma regla de herencia hacia abajo que `authorize`. Es MEMBRESÍA: el
188
+ * deny no la gobierna, así que nunca decide acceso (para eso, `authorize`).
80
189
  */
81
- hasRole(subject: SubjectRef, role: string, scope: ScopeRef): Promise<boolean>;
190
+ hasRole(subject: SubjectRef, role: RoleQuery, scope: ScopeRef): Promise<boolean>;
82
191
  /**
83
192
  * Deny explícito de UN permiso al holder en un scope (y sus descendientes).
84
193
  * El permiso debe existir en el catálogo (throw si no). Idempotente.
85
194
  */
86
195
  deny(subject: SubjectRef, permission: string, scope: ScopeRef): Promise<void>;
87
- /** Levanta el deny en ese scope exacto. No-op si no existía. */
196
+ /**
197
+ * Levanta el deny en ese scope exacto. El permiso debe existir en el
198
+ * catálogo (422 si no, como `deny`); el deny puede no existir (no-op).
199
+ */
88
200
  removeDeny(subject: SubjectRef, permission: string, scope: ScopeRef): Promise<void>;
89
201
  /** Holders con asignación VIGENTE del rol en ese scope exacto (sin herencia). */
90
- listSubjects(role: string, scope: ScopeRef): Promise<SubjectRef[]>;
91
- /** Roles (slugs) con asignación DIRECTA vigente del holder en ese scope exacto. */
202
+ listSubjects(role: RoleQuery, scope: ScopeRef): Promise<SubjectRef[]>;
203
+ /**
204
+ * Roles (slugs) con asignación DIRECTA vigente del holder en ese scope
205
+ * exacto. Es API de MEMBRESÍA y habla en slugs: desde 3B dos roles pueden
206
+ * compartir `(slug, nivel)` con owners distintos, así que un slug de esta
207
+ * lista puede no bastar para volver a direccionar el rol (`grant`/`hasRole`
208
+ * responderían 422 `E_AUTHZ_AMBIGUOUS_ROLE`). La forma sin ambigüedad es
209
+ * `{ uuid }`, y los uuids de la cadena los da `rolesInChain`.
210
+ */
92
211
  listRoles(subject: SubjectRef, scope: ScopeRef): Promise<string[]>;
93
212
  /**
94
213
  * Scopes del tipo dado donde el holder tiene alguna asignación DIRECTA
@@ -101,29 +220,360 @@ export interface AuthorizationDriver {
101
220
  * abierto): el caller consulta `authorize` sobre un scope concreto.
102
221
  */
103
222
  listScopes(subject: SubjectRef, permission: string): Promise<ScopeRef[]>;
223
+ /**
224
+ * Borra TODAS las asignaciones y denies del scope EXACTO cuyo rol/permiso
225
+ * está en el catálogo (no de sus descendientes: hasta que exista
226
+ * `descendantsOf`, Fase 2, el consumidor purga cada nodo del subárbol que
227
+ * borra). No consulta el árbol: el scope puede ya no existir para el
228
+ * resolutor. Debe demostrar que ESE conjunto quedó a cero o lanzar (500
229
+ * `E_AUTHZ_PURGE_INCOMPLETE`): un borrado parcial silencioso deja hechos
230
+ * huérfanos e indenegables. Los hechos de roles/permisos retirados del
231
+ * catálogo no son membresía ni conceden nada (las lecturas filtran por el
232
+ * catálogo, D5) y los recoge `authz:reconcile` (3b). La raíz no se purga
233
+ * (422).
234
+ */
235
+ purgeScope(scope: ScopeRef): Promise<void>;
236
+ /**
237
+ * Notificaciones del árbol del consumidor (`manager.scopes.*`), ya
238
+ * validadas por el paquete (raíz, existencia del padre, ciclos). Un driver
239
+ * que materializa el árbol como hechos propios (modo facts) las necesita;
240
+ * `database` no (lee el árbol vía `resolveChain`). Opcionales.
241
+ */
242
+ onScopeAttached?(child: ScopeRef, parent: ScopeRef): Promise<void>;
243
+ onScopeMoved?(child: ScopeRef, newParent: ScopeRef): Promise<void>;
244
+ /** Se llama DESPUÉS de `purgeScope` (hechos primero, arista al final: S6). */
245
+ onScopeDetached?(child: ScopeRef): Promise<void>;
246
+ /**
247
+ * Vista del driver que resuelve la CADENA con OTRO resolutor y comparte
248
+ * todo lo demás (conexión, memo del catálogo, deadline). Opcional (2.1):
249
+ * `AuthorizationManager.forRequest()` la usa para leer con un resolutor
250
+ * memoizado por request; un driver que no la implemente sigue funcionando
251
+ * (la vista lee con el driver tal cual, sin memo). Solo el camino de
252
+ * lectura pasa por aquí: las escrituras del manager van al driver original.
253
+ */
254
+ withChainResolver?(resolveChain: ScopeChainResolver): AuthorizationDriver;
255
+ /**
256
+ * Vista del driver que evalúa el TIEMPO con otro reloj (2.5 · J1) y
257
+ * comparte todo lo demás. `now()` es el instante de pared con el que se
258
+ * decide la caducidad —`expires_at > now` en SQL, `current_time` de cada
259
+ * check de FGA, el filtro de caducidad de las enumeraciones y los tres
260
+ * estados de `resolveGrantExpiry`—. Los sellos de auditoría (`created_at`)
261
+ * NO lo usan (2.5-B · K5): no son decisiones.
262
+ * Opcional: el manager lo aplica si el config trae `clock` (500
263
+ * `E_AUTHZ_CONFIG` si el driver no lo implementa: un reloj que no llega al
264
+ * driver mentiría). El juez lo usa con `injectableClock: true` para fijar
265
+ * la caducidad exacta sin dormir.
266
+ */
267
+ withClock?(now: () => Date): AuthorizationDriver;
268
+ /**
269
+ * Denies DIRECTOS vigentes del holder (2.1, B5): con `scope`, los de ese
270
+ * scope exacto (sin herencia, invariante 7; scope desconocido ⇒ `[]`); sin
271
+ * él, todos los del holder con su scope (los de scopes que el árbol ya no
272
+ * conoce no se listan, D8). Solo permisos del catálogo (D5). Opcional:
273
+ * ambos drivers del paquete lo implementan; sin él, `effectivePermissions`
274
+ * y `authorizedScopes` lanzan 500 `E_AUTHZ_UNSUPPORTED` (nunca un `[]`
275
+ * que significaría "sin denies": fail-open).
276
+ */
277
+ listDenies?(subject: SubjectRef, scope?: ScopeRef): Promise<DenyRef[]>;
278
+ /**
279
+ * `authorize` sobre varios scopes, un booleano por posición (2.1, B6).
280
+ * Opcional: el manager compone `Promise.all` de `authorize` sobre una
281
+ * vista memoizada si el driver no lo trae; `openfga` lo implementa con UN
282
+ * batchCheck para todos los scopes, correlacionado por id (L0.14). Misma
283
+ * respuesta que N `authorize`; si una posición no se puede responder
284
+ * (503), no se responde ninguna. Lista vacía ⇒ `[]` sin tocar el backend.
285
+ */
286
+ authorizeMany?(subject: SubjectRef, permission: string, scopes: ScopeRef[]): Promise<boolean[]>;
287
+ /**
288
+ * Purga un ROL del catálogo con sus hechos (3B · B4): revoca TODAS sus
289
+ * asignaciones en TODOS los scopes, borra sus vínculos rol→permiso y la
290
+ * fila del rol, atómicamente, y sube la versión compartida del catálogo
291
+ * (`withAuthzCatalogWrite`). Es lo que `deleteScopedRole` necesita: un rol
292
+ * borrado sin sus asignaciones dejaría hechos huérfanos que resucitarían
293
+ * al recrear el slug. `uuid` mal formado ⇒ 422 `E_AUTHZ_INVALID_IDENTITY`;
294
+ * desconocido ⇒ 422 `E_AUTHZ_UNKNOWN_ROLE`. No distingue global de local
295
+ * (esa barrera es del manager). Un driver que no pueda purgar (openfga
296
+ * hasta 3b: sus bindings no se enumeran por rol) lo DICE con 500
297
+ * `E_AUTHZ_UNSUPPORTED` y no toca nada — capacidad `purgeRole: false`.
298
+ *
299
+ * OPCIONAL en el puerto (3E · Q4): el manager ya lo trata como opcional
300
+ * (`#optional` ⇒ 500 `E_AUTHZ_UNSUPPORTED` nombrándolo) y declararlo
301
+ * obligatorio rompía al COMPILAR a todo driver de terceros escrito para
302
+ * 2.0/2.1. Un driver que no lo trae no puede tener roles locales:
303
+ * `defineScopedRole` lo dice antes de escribir nada (3E · P4).
304
+ */
305
+ purgeRole?(roleUuid: string): Promise<void>;
306
+ /**
307
+ * Roles DIRECTOS vigentes del holder en cada scope de `chain` (2D · G5),
308
+ * como pares `{ scope, role }`; solo roles que EXISTEN en ese scope (D5 +
309
+ * 3B · B2: declarados para su nivel y visibles por owner desde ese nivel).
310
+ * Opcional: es lo que `effectivePermissions` usa para leer los roles de
311
+ * toda la cadena en UNA lectura; sin él, el manager compone N `listRoles`.
312
+ * La cadena llega ya resuelta y validada.
313
+ *
314
+ * Devuelve `CatalogRoleRef` (uuid + slug + nivel + owner), no un slug (3D ·
315
+ * M1): el manager usa el uuid tal cual y NUNCA vuelve del slug al catálogo
316
+ * en el camino de policy. Volver del slug hacía que `effectivePermissions`
317
+ * y `defineScopedRole` atribuyeran al holder los permisos de un homónimo
318
+ * (auditor V1: escalada reproducida).
319
+ */
320
+ rolesInChain?(subject: SubjectRef, chain: ScopeRef[]): Promise<Array<{
321
+ scope: ScopeRef;
322
+ role: CatalogRoleRef;
323
+ }>>;
104
324
  }
325
+ /**
326
+ * Un subárbol excluido de un `all` (2.1, B3; tipo nominal desde 2D · F10):
327
+ * el scope con el deny vivo Y todos sus descendientes. No es una lista de
328
+ * scopes: un `NOT IN (uuids)` con solo `scope` seguiría listando las units
329
+ * de una organización denegada. Expándelo con
330
+ * `authorization.expandExcludedSubtrees(excluded)` (usa tu `descendantsOf`)
331
+ * o resta el subárbol en tu propia consulta (CTE recursiva, `path LIKE`…).
332
+ */
333
+ export interface ExcludedSubtree {
334
+ scope: ScopeRef;
335
+ /** Siempre `true`: recuerda que lo excluido es el subárbol entero. */
336
+ includesDescendants: true;
337
+ }
338
+ /**
339
+ * Respuesta de `authorizedScopes(subject, permission, scopeType)` (2.1, B3):
340
+ * - `none`: ningún scope de ese tipo;
341
+ * - `some`: exactamente estos (directos del tipo + descendientes vía
342
+ * `descendantsOf`, menos los que tienen un deny en su cadena), nunca más
343
+ * de `maxScopes`. Coherente con `authorize` scope a scope cuando
344
+ * `descendantsOf` y `resolveChain` describen el mismo árbol; si
345
+ * discrepan, lanza 503 `E_AUTHZ_RESOLVER_FAILED` (2D · F3);
346
+ * - `all`: hay un grant vigente en la raíz `app` (ancestro común de todo el
347
+ * tipo) — MENOS `excludedSubtrees`: los scopes con deny vivo del permiso,
348
+ * cada uno con su subárbol entero. Nunca `all` a secas con denies vivos
349
+ * (juez cruce 5, auditor E1): quien liste "todo" tiene que restar esto.
350
+ */
351
+ export type AuthorizedScopes = {
352
+ kind: 'none';
353
+ } | {
354
+ kind: 'some';
355
+ scopes: ScopeRef[];
356
+ } | {
357
+ kind: 'all';
358
+ excludedSubtrees: ExcludedSubtree[];
359
+ };
360
+ /** Un deny directo, tal como lo enumera `listDenies` (2.1). */
361
+ export interface DenyRef {
362
+ permission: string;
363
+ scope: ScopeRef;
364
+ }
365
+ /**
366
+ * Mapa morph name → tipo del modelo FGA (`users` → `user`). Lo consume el
367
+ * driver `openfga` (subpath `@jantstack/adonis-authz/openfga`); vive en el
368
+ * puerto para que `defineConfig` lo tipe sin importar el driver (D9).
369
+ */
370
+ export type HolderTypeMap = Record<string, string>;
105
371
  /** Factory registrable en `config/authorization.ts`. */
106
372
  export type AuthorizationDriverFactory = () => AuthorizationDriver | Promise<AuthorizationDriver>;
107
373
  /**
108
- * Resolutor de ancestros de un scope (del más cercano a la raíz). El paquete
374
+ * Resolutor de la CADENA de un scope (2.5-B · K1): `[scope canónico,
375
+ * ...ancestros]`, del más cercano a la raíz, con `app` al final. El paquete
109
376
  * NO conoce el dominio del consumidor: el chasis inyecta el suyo (que sabe de
110
- * organizations/organization_units) al construir cada driver en el config.
111
- * Default de los drivers sin resolutor: `app` → [], resto → [APP_SCOPE].
377
+ * organizations/organization_units) al construir cada driver y el manager.
378
+ *
379
+ * El elemento 0 es el PROPIO scope tal como está en la tabla del consumidor
380
+ * (la fila leída), no tal como lo escribió el llamante: es la identidad con
381
+ * la que el paquete lee y escribe todos los hechos. Un motor que canoniza
382
+ * ids (el tipo `uuid` de PostgreSQL, una collation `*_ci`) puede encontrar
383
+ * la fila para un alias (mayúsculas, guiones quitados); devolverla canónica es
384
+ * lo que hace que el deny escrito con la forma real siga casando. Devolver
385
+ * otro scope como elemento 0 es 503 `E_AUTHZ_RESOLVER_FAILED`.
386
+ *
387
+ * `null` significa "este scope no existe": el motor deniega (`authorize`/
388
+ * `hasRole` → false) y rechaza escribir sobre él (`grant`/`deny` → 422
389
+ * `E_AUTHZ_UNKNOWN_SCOPE`). Ya no hay default plano: un driver sin resolutor
390
+ * solo conoce la raíz `app`, y cualquier otro tipo es 422
391
+ * `E_AUTHZ_NO_SCOPE_RESOLVER` (L0.3). Un resolutor que devuelva `[scope,
392
+ * APP_SCOPE]` para lo que no conoce vuelve a abrir el defecto: es su
393
+ * responsabilidad no hacerlo, y el vocabulario para no hacerlo es `null`. La
394
+ * raíz nunca se pregunta: su cadena es `[APP_SCOPE]` por definición.
112
395
  */
113
- export type ScopeAncestorsResolver = (scope: ScopeRef) => Promise<ScopeRef[]>;
396
+ export type ScopeChainResolver = (scope: ScopeRef) => Promise<ScopeRef[] | null>;
397
+ /**
398
+ * Resolutor de DESCENDIENTES de un scope (2.1, B2): todos los nodos del
399
+ * subárbol (cualquier tipo, cualquier profundidad), sin el propio scope y
400
+ * sin orden exigido. Lo implementa el consumidor (o `sqlDescendantsOf`, el
401
+ * helper opt-in del paquete): el paquete NO lo suple con N+1 llamadas a
402
+ * `resolveChain`. `null` = scope desconocido. Más de `maxNodes` nodos ⇒
403
+ * el consumidor lanza; si devuelve de más, lanza el manager (422
404
+ * `E_AUTHZ_TOO_MANY_SCOPES`). Nunca se llama desde `authorize`/`hasRole`/
405
+ * `list*` (test de arquitectura): solo desde `authorizedScopes`.
406
+ */
407
+ /**
408
+ * El árbol del consumidor hacia ABAJO (2.1): todos los descendientes de
409
+ * `scope`, en cualquier orden y sin incluirlo. `null` = «este árbol no conoce
410
+ * ese scope».
411
+ *
412
+ * Contrato con un scope que `resolveChain` YA NO conoce (3G · W2, auditor
413
+ * pregunta 2): **el consumidor es la autoridad sobre su tabla y puede
414
+ * devolver los hijos** (una ruta materializada, o un `where parent_id = X`,
415
+ * no necesitan la fila del padre) **o `null`**; el paquete no asume ninguna
416
+ * de las dos. La consecuencia está en `scopes.detached`: si el scope no
417
+ * resuelve y por debajo no llega nada, la purga NO se puede declarar
418
+ * completa (`ScopeDetachOutcome.truncated: true`). Y lo que se devuelva se
419
+ * trata como el subárbol real: los roles de esos owners se purgan con la
420
+ * policy de rango medida en la cadena de CADA owner (3G · W1), nunca en la
421
+ * del scope notificado.
422
+ *
423
+ * Más de `maxNodes` nodos ⇒ el resolutor puede devolver la lista larga (el
424
+ * paquete la caza con 422 `E_AUTHZ_TOO_MANY_SCOPES`) o lanzar; en
425
+ * `authorizedScopes` eso es un 422 y en `scopes.detached`/`defineScopedRole`
426
+ * DEGRADA (3F · S2, y ver el aviso de `#assertLevelUnderOwner`).
427
+ */
428
+ export type ScopeDescendantsResolver = (scope: ScopeRef, options: {
429
+ maxNodes: number;
430
+ }) => Promise<ScopeRef[] | null>;
114
431
  /**
115
432
  * Escritura del motor, notificada al hook `onWrite` del config. El chasis lo
116
433
  * usa para auditar/emitir SSE; un consumidor puede loguear, notificar, etc.
117
434
  */
118
435
  export interface AuthzWriteEvent {
119
- action: 'granted' | 'revoked' | 'denied' | 'deny_removed';
120
- subject: SubjectRef;
436
+ /**
437
+ * `extended`: un re-grant cambió la caducidad de una asignación que ya
438
+ * existía (alargada, acortada o quitada) — lleva `previousExpiresAt`. Un
439
+ * re-grant que no cambia nada sigue siendo `granted` (idempotente).
440
+ * `scope_purged`: `scopes.detached` borró todos los hechos del scope; no
441
+ * lleva `subject` (afecta a todos los holders del scope).
442
+ */
443
+ action: 'granted' | 'extended' | 'revoked' | 'denied' | 'deny_removed' | 'scope_purged';
444
+ /** Ausente solo en `scope_purged`. */
445
+ subject?: SubjectRef;
121
446
  scope: ScopeRef;
122
- /** Presente en granted/revoked. */
123
- role?: string;
447
+ /**
448
+ * Quién ordenó la escritura (2.1, B7): lo que el llamante pasó en
449
+ * `WriteOptions.actor`, ya validado. Ausente si no lo pasó.
450
+ */
451
+ actor?: SubjectRef;
452
+ /**
453
+ * Presente en granted/extended/revoked: el/los rol(es) RESUELTOS (3E · Q7,
454
+ * auditor A8), con `uuid`, `slug`, nivel y owner — no la pregunta cruda.
455
+ *
456
+ * En 1.x era `role: string` (el slug) y en 3D pasó a `RoleQuery`: un sink
457
+ * de auditoría que filtraba por slug dejó de casar EN SILENCIO, que es una
458
+ * pérdida de auditoría, no solo de tipos. Con la forma resuelta el sink
459
+ * vuelve a tener el slug —`event.roles.some((r) => r.slug === 'admin')`— y
460
+ * además el uuid, que es lo único que identifica un rol desde 3A.
461
+ *
462
+ * Es una LISTA porque un `revoke` por slug quita los hechos de TODOS los
463
+ * homónimos visibles en el scope (3B); un `grant` resuelve exactamente uno
464
+ * (con dos sería 422 `E_AUTHZ_AMBIGUOUS_ROLE`). Ausente si el rol no se
465
+ * pudo resolver (scope que el árbol no conoce, rol fuera del catálogo): el
466
+ * driver decidirá el resultado, y el evento no inventa.
467
+ */
468
+ roles?: CatalogRoleRef[];
124
469
  /** Presente en denied/deny_removed. */
125
470
  permission?: string;
471
+ /** Caducidad con la que queda la asignación (granted/extended). */
126
472
  expiresAt?: Date | null;
473
+ /** Caducidad que tenía antes (solo extended). */
474
+ previousExpiresAt?: Date | null;
475
+ /**
476
+ * `true` cuando la escritura venció el deadline (503 `E_AUTHZ_BACKEND_TIMEOUT`)
477
+ * y el paquete NO sabe si el backend la aplicó: la petición puede aterrizar
478
+ * después de que el llamante recibiera el error. Se notifica ANTES de
479
+ * propagar el 503 para que la auditoría registre un resultado desconocido
480
+ * en vez de un silencio (que se lee como "no pasó nada"). Un 503 que no es
481
+ * timeout (conexión rechazada) no lo lleva: esa escritura no ocurrió.
482
+ */
483
+ indeterminate?: boolean;
484
+ /**
485
+ * Solo en `scope_purged`: el árbol ya NO conoce el scope notificado —el
486
+ * consumidor borró su fila y avisa después, que es el orden que el paquete
487
+ * admite— o alguno de los roles purgados tenía un owner que tampoco
488
+ * resuelve (3F · S1; 3G · W1/W2). `'owner-detached-unknown'` significa dos
489
+ * cosas a la vez, y las dos importan a quien audita: (a) la purga procede
490
+ * igual —bloquearla dejaba vivos el rol, sus asignaciones y los denies de
491
+ * un scope borrado (auditor N2), sin ninguna salida con `requireActor:
492
+ * true`— y (b) para ESOS roles —los que no tienen dónde medir el rango— la
493
+ * policy de 3E · P3 no se pudo evaluar. Para los demás sí se evalúa: el
494
+ * rango se mide en la cadena del OWNER de cada rol (3G · W1), así que un
495
+ * `detached` de un ancestro desconocido ya NO destruye los roles de
496
+ * descendientes vivos. Sale también con `purgedRoles: 0`.
497
+ */
498
+ reason?: 'owner-detached-unknown';
499
+ /**
500
+ * Solo en `scope_purged`: la purga de roles se acotó al scope EXACTO
501
+ * porque el subárbol no se pudo enumerar (3F · S2). Ver
502
+ * `ScopeDetachOutcome.truncated`.
503
+ */
504
+ truncated?: true;
505
+ }
506
+ /**
507
+ * Lo que devuelve `scopes.detached` (3F · S1/S2). Hasta 3E era `void` y no
508
+ * había forma de saber si la purga alcanzó a todo el subárbol ni si la
509
+ * policy de rango se llegó a evaluar.
510
+ */
511
+ export interface ScopeDetachOutcome {
512
+ /** Roles LOCALES purgados (los del scope y, con `descendantsOf`, los del subárbol). */
513
+ purgedRoles: number;
514
+ /**
515
+ * `true` cuando el subárbol NO se pudo enumerar (más de `maxDescendants`,
516
+ * o un `descendantsOf` que falló) y la purga se acotó al scope EXACTO
517
+ * (3F · S2). Degradar en vez de tumbar la operación es la regla: declarar
518
+ * `scopes.descendantsOf` nunca puede dejarte peor que no declararlo, y
519
+ * hasta 3E un subárbol grande dejaba el `detached` en 503 sin purgar ni
520
+ * los roles ni los hechos (auditor N3). Los roles que quedan abajo no son
521
+ * visibles en ninguna parte —su owner ya no cuelga del árbol—, pero siguen
522
+ * ocupando su `(slug, nivel)`: hay que volver a notificar nodo a nodo o
523
+ * subir la cota.
524
+ *
525
+ * También es `true` cuando el árbol ya NO conoce el scope y `descendantsOf`
526
+ * no devolvió nada debajo (3G · W2, auditor P2): el puerto no le exige
527
+ * responder por un scope que `resolveChain` desconoce —puede devolver sus
528
+ * hijos o `null`, ver `ScopeDescendantsResolver`—, así que un vacío ahí no
529
+ * demuestra que debajo no quedara nada. Decir `truncated: false` era
530
+ * afirmar «purga completa» con el rol de la unit hija vivo y concediendo.
531
+ */
532
+ truncated: boolean;
533
+ /**
534
+ * Igual que en `AuthzWriteEvent`: el scope notificado (o el owner de algún
535
+ * rol purgado) ya no está en el árbol, así que para esos roles la policy
536
+ * de rango no se pudo evaluar. Presente aunque `purgedRoles` sea 0.
537
+ */
538
+ reason?: 'owner-detached-unknown';
539
+ }
540
+ /** Un rol del catálogo tal como lo ve el motor (3A · A2/A3, 3B · B2). */
541
+ export interface CatalogRole {
542
+ /** Identidad interna: lo que llevan `authz_assignments.role_uuid` y los ids de binding de FGA. */
543
+ uuid: string;
544
+ slug: string;
545
+ scopeType: ScopeType;
546
+ /** `'global'` o `scopeKey(owner)` (`<tipo>|<uuid>`): el contenedor fuera del cual el rol no existe. */
547
+ owner: string;
548
+ /** Metadata de policy (invariante 8): el motor no lo evalúa en `authorize`. */
549
+ rank: number;
550
+ }
551
+ /**
552
+ * La IDENTIDAD pública de un rol sin su metadata de policy (3D · M1): lo que
553
+ * devuelve `rolesInChain` y lo que el memo usa para filtrar por owner. El
554
+ * uuid manda; el slug viaja como etiqueta legible.
555
+ */
556
+ export interface CatalogRoleRef {
557
+ slug: string;
558
+ uuid: string;
559
+ scopeType: ScopeType;
560
+ /** `'global'` o `scopeKey(owner)`. */
561
+ owner: string;
562
+ }
563
+ export interface CatalogPermissionSpec {
564
+ /** Formato `recurso:accion`. */
565
+ slug: string;
566
+ description?: string | null;
567
+ /**
568
+ * Niveles (scope types) cuyos roles PUEDEN llevar este permiso (3B · B5):
569
+ * omitido = cualquiera. Es un control de COMPOSICIÓN: `syncAuthzCatalog`,
570
+ * `defineScopedRole`/`updateScopedRole` y `grant` rechazan (422
571
+ * `E_AUTHZ_ROLE_NOT_ASSIGNABLE_AT`) un rol de otro nivel que lo lleve;
572
+ * `authorize` NO lo mira (invariante 1: lo ya asignado sigue concediendo).
573
+ * Es lo que cubre «un rol de unit no puede llevar org:settings» sin romper
574
+ * la herencia hacia abajo (panel 2026-08-28, H).
575
+ */
576
+ assignableAt?: ScopeType[];
127
577
  }
128
578
  export interface CatalogRoleSpec {
129
579
  /** UUID fijo opcional (mismo patrón que organization_acl: estable entre entornos). */
@@ -144,10 +594,62 @@ export interface CatalogRoleSpec {
144
594
  }
145
595
  export interface CatalogSpec {
146
596
  /** Todos los permisos del catálogo (formato `recurso:accion`). */
147
- permissions: Array<{
148
- slug: string;
149
- description?: string | null;
150
- }>;
597
+ permissions: CatalogPermissionSpec[];
598
+ /** Roles GLOBALES (owner `global`): un spec nunca declara roles locales. */
151
599
  roles: CatalogRoleSpec[];
152
600
  }
601
+ /**
602
+ * Un rol LOCAL a un scope, tal como lo define `defineScopedRole(actor,
603
+ * ownerScope, spec)` (3B · B3). Sin `uuid` (lo genera el motor) y con `rank`
604
+ * OBLIGATORIO: `0 < rank < min(rank del actor, rank máximo global)`.
605
+ */
606
+ export interface ScopedRoleSpec {
607
+ slug: string;
608
+ /** Nivel al que el rol es asignable (dentro del owner). Nunca `app`. */
609
+ scopeType: ScopeType;
610
+ name?: string;
611
+ description?: string | null;
612
+ rank: number;
613
+ /** Slugs de permisos: ⊆ `config.delegablePermissions` ∩ efectivos del actor en el owner. */
614
+ permissions: string[];
615
+ }
616
+ /** Lo que `updateScopedRole` puede cambiar de un rol local: nunca su slug, nivel ni owner. */
617
+ export interface ScopedRoleChanges {
618
+ name?: string;
619
+ description?: string | null;
620
+ rank?: number;
621
+ permissions?: string[];
622
+ }
623
+ /**
624
+ * Escritura del CATÁLOGO por la API de delegación (3B · B3), notificada al
625
+ * hook `onCatalogWrite` del config. Siempre lleva `actor` (la API lo exige)
626
+ * y el rol tal como queda (`role_purged`: tal como estaba).
627
+ */
628
+ export interface AuthzCatalogWriteEvent {
629
+ action: 'role_defined' | 'role_updated' | 'role_purged';
630
+ /**
631
+ * Quién lo ordenó. La API de delegación lo exige siempre; ausente solo en
632
+ * los `role_purged` que arrastra `scopes.detached` (3D · M4), donde el
633
+ * actor es el `WriteOptions.actor` de esa notificación del árbol y puede
634
+ * no venir.
635
+ */
636
+ actor?: SubjectRef;
637
+ role: CatalogRole;
638
+ /** El scope owner del rol (`scopeFromKey(role.owner)`). */
639
+ owner: ScopeRef;
640
+ /** Permisos con los que queda el rol (o tenía, si se purga). */
641
+ permissions: string[];
642
+ /**
643
+ * Solo en `role_defined` (3F · S3): los roles LOCALES de un DESCENDIENTE
644
+ * del owner con ese mismo `(slug, nivel)` que el nuevo acaba de
645
+ * ENSOMBRECER. La autoridad manda —global > local de un ancestro > local
646
+ * de un descendiente—, así que el dueño del árbol siempre puede definir su
647
+ * rol aunque alguien de abajo le haya ocupado el nombre; dentro del
648
+ * subárbol de esos owners toda ruta por slug pasa a 422
649
+ * `E_AUTHZ_AMBIGUOUS_ROLE` (se opera por `{ uuid }`) hasta que se purgue
650
+ * uno. Es el mismo trato que `shadowedByGlobal` en el sync, y como allí:
651
+ * se REPORTA, nunca en silencio.
652
+ */
653
+ shadowedByAncestor?: CatalogRoleRef[];
654
+ }
153
655
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}