@jantstack/adonis-authz 2.0.0-alpha.1 → 2.4.0-alpha.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.
Files changed (214) hide show
  1. package/README.md +693 -36
  2. package/build/commands/authz_catalog_diff.js +1 -1
  3. package/build/commands/authz_catalog_diff.js.map +1 -1
  4. package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
  5. package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
  6. package/build/commands/authz_catalog_prune_orphans.js +136 -0
  7. package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
  8. package/build/commands/authz_catalog_sync.d.ts +17 -0
  9. package/build/commands/authz_catalog_sync.d.ts.map +1 -1
  10. package/build/commands/authz_catalog_sync.js +27 -4
  11. package/build/commands/authz_catalog_sync.js.map +1 -1
  12. package/build/commands/authz_freeze.d.ts +44 -0
  13. package/build/commands/authz_freeze.d.ts.map +1 -0
  14. package/build/commands/authz_freeze.js +95 -0
  15. package/build/commands/authz_freeze.js.map +1 -0
  16. package/build/commands/authz_reconcile.d.ts +102 -0
  17. package/build/commands/authz_reconcile.d.ts.map +1 -0
  18. package/build/commands/authz_reconcile.js +294 -0
  19. package/build/commands/authz_reconcile.js.map +1 -0
  20. package/build/commands/authz_relations_reconcile.d.ts +97 -0
  21. package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
  22. package/build/commands/authz_relations_reconcile.js +313 -0
  23. package/build/commands/authz_relations_reconcile.js.map +1 -0
  24. package/build/commands/authz_scopes_relay.d.ts +47 -0
  25. package/build/commands/authz_scopes_relay.d.ts.map +1 -0
  26. package/build/commands/authz_scopes_relay.js +141 -0
  27. package/build/commands/authz_scopes_relay.js.map +1 -0
  28. package/build/commands/authz_unfreeze.d.ts +37 -0
  29. package/build/commands/authz_unfreeze.d.ts.map +1 -0
  30. package/build/commands/authz_unfreeze.js +92 -0
  31. package/build/commands/authz_unfreeze.js.map +1 -0
  32. package/build/commands/main.d.ts +6 -1
  33. package/build/commands/main.d.ts.map +1 -1
  34. package/build/commands/main.js +6 -1
  35. package/build/commands/main.js.map +1 -1
  36. package/build/commands/openfga_provision.d.ts +46 -4
  37. package/build/commands/openfga_provision.d.ts.map +1 -1
  38. package/build/commands/openfga_provision.js +90 -7
  39. package/build/commands/openfga_provision.js.map +1 -1
  40. package/build/configure.d.ts +11 -0
  41. package/build/configure.d.ts.map +1 -1
  42. package/build/configure.js +37 -1
  43. package/build/configure.js.map +1 -1
  44. package/build/index.d.ts +50 -10
  45. package/build/index.d.ts.map +1 -1
  46. package/build/index.js +45 -6
  47. package/build/index.js.map +1 -1
  48. package/build/providers/authz_provider.d.ts +26 -2
  49. package/build/providers/authz_provider.d.ts.map +1 -1
  50. package/build/providers/authz_provider.js +55 -2
  51. package/build/providers/authz_provider.js.map +1 -1
  52. package/build/services/relations.d.ts +14 -0
  53. package/build/services/relations.d.ts.map +1 -0
  54. package/build/services/relations.js +17 -0
  55. package/build/services/relations.js.map +1 -0
  56. package/build/src/{catalog.d.ts → catalog/catalog.d.ts} +41 -2
  57. package/build/src/catalog/catalog.d.ts.map +1 -0
  58. package/build/src/{catalog.js → catalog/catalog.js} +120 -14
  59. package/build/src/catalog/catalog.js.map +1 -0
  60. package/build/src/{catalog_cache.d.ts → catalog/catalog_cache.d.ts} +46 -22
  61. package/build/src/catalog/catalog_cache.d.ts.map +1 -0
  62. package/build/src/{catalog_cache.js → catalog/catalog_cache.js} +53 -43
  63. package/build/src/catalog/catalog_cache.js.map +1 -0
  64. package/build/src/define_config.d.ts +137 -3
  65. package/build/src/define_config.d.ts.map +1 -1
  66. package/build/src/define_config.js.map +1 -1
  67. package/build/src/drivers/database_driver.d.ts +128 -7
  68. package/build/src/drivers/database_driver.d.ts.map +1 -1
  69. package/build/src/drivers/database_driver.js +510 -24
  70. package/build/src/drivers/database_driver.js.map +1 -1
  71. package/build/src/drivers/database_relations_driver.d.ts +113 -0
  72. package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
  73. package/build/src/drivers/database_relations_driver.js +679 -0
  74. package/build/src/drivers/database_relations_driver.js.map +1 -0
  75. package/build/src/drivers/openfga_driver.d.ts +729 -122
  76. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  77. package/build/src/drivers/openfga_driver.js +2083 -476
  78. package/build/src/drivers/openfga_driver.js.map +1 -1
  79. package/build/src/drivers/openfga_facts.d.ts +384 -0
  80. package/build/src/drivers/openfga_facts.d.ts.map +1 -0
  81. package/build/src/drivers/openfga_facts.js +836 -0
  82. package/build/src/drivers/openfga_facts.js.map +1 -0
  83. package/build/src/drivers/openfga_relations_driver.d.ts +141 -0
  84. package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
  85. package/build/src/drivers/openfga_relations_driver.js +590 -0
  86. package/build/src/drivers/openfga_relations_driver.js.map +1 -0
  87. package/build/src/errors.d.ts +290 -5
  88. package/build/src/errors.d.ts.map +1 -1
  89. package/build/src/errors.js +296 -7
  90. package/build/src/errors.js.map +1 -1
  91. package/build/src/freeze.d.ts +141 -0
  92. package/build/src/freeze.d.ts.map +1 -0
  93. package/build/src/freeze.js +217 -0
  94. package/build/src/freeze.js.map +1 -0
  95. package/build/src/http/app_access_middleware.d.ts.map +1 -0
  96. package/build/src/http/app_access_middleware.js.map +1 -0
  97. package/build/src/http/resource_access_middleware.d.ts +105 -0
  98. package/build/src/http/resource_access_middleware.d.ts.map +1 -0
  99. package/build/src/http/resource_access_middleware.js +81 -0
  100. package/build/src/http/resource_access_middleware.js.map +1 -0
  101. package/build/src/identity.d.ts +74 -1
  102. package/build/src/identity.d.ts.map +1 -1
  103. package/build/src/identity.js +100 -2
  104. package/build/src/identity.js.map +1 -1
  105. package/build/src/manager.d.ts +330 -4
  106. package/build/src/manager.d.ts.map +1 -1
  107. package/build/src/manager.js +1285 -188
  108. package/build/src/manager.js.map +1 -1
  109. package/build/src/models/authz_assignment.d.ts +7 -7
  110. package/build/src/models/authz_assignment.d.ts.map +1 -1
  111. package/build/src/models/authz_deny.d.ts +7 -7
  112. package/build/src/models/authz_deny.d.ts.map +1 -1
  113. package/build/src/models/authz_permission.d.ts +7 -7
  114. package/build/src/models/authz_permission.d.ts.map +1 -1
  115. package/build/src/models/authz_role.d.ts +7 -7
  116. package/build/src/models/authz_role.d.ts.map +1 -1
  117. package/build/src/models/authz_role_permission.d.ts +7 -7
  118. package/build/src/models/authz_role_permission.d.ts.map +1 -1
  119. package/build/src/openfga.d.ts +18 -2
  120. package/build/src/openfga.d.ts.map +1 -1
  121. package/build/src/openfga.js +15 -1
  122. package/build/src/openfga.js.map +1 -1
  123. package/build/src/reconcile.d.ts +37 -0
  124. package/build/src/reconcile.d.ts.map +1 -0
  125. package/build/src/reconcile.js +69 -0
  126. package/build/src/reconcile.js.map +1 -0
  127. package/build/src/relation_partition_trigger.d.ts +8 -0
  128. package/build/src/relation_partition_trigger.d.ts.map +1 -0
  129. package/build/src/relation_partition_trigger.js +93 -0
  130. package/build/src/relation_partition_trigger.js.map +1 -0
  131. package/build/src/relations/define_relations_config.d.ts +75 -0
  132. package/build/src/relations/define_relations_config.d.ts.map +1 -0
  133. package/build/src/relations/define_relations_config.js +173 -0
  134. package/build/src/relations/define_relations_config.js.map +1 -0
  135. package/build/src/relations/manager.d.ts +60 -0
  136. package/build/src/relations/manager.d.ts.map +1 -0
  137. package/build/src/relations/manager.js +213 -0
  138. package/build/src/relations/manager.js.map +1 -0
  139. package/build/src/relations/reconcile.d.ts +111 -0
  140. package/build/src/relations/reconcile.d.ts.map +1 -0
  141. package/build/src/relations/reconcile.js +200 -0
  142. package/build/src/relations/reconcile.js.map +1 -0
  143. package/build/src/relations_config_store.d.ts +22 -0
  144. package/build/src/relations_config_store.d.ts.map +1 -0
  145. package/build/src/relations_config_store.js +74 -0
  146. package/build/src/relations_config_store.js.map +1 -0
  147. package/build/src/scope_outbox.d.ts +69 -0
  148. package/build/src/scope_outbox.d.ts.map +1 -0
  149. package/build/src/scope_outbox.js +298 -0
  150. package/build/src/scope_outbox.js.map +1 -0
  151. package/build/src/{drivers → shared}/backend_guard.d.ts +42 -0
  152. package/build/src/shared/backend_guard.d.ts.map +1 -0
  153. package/build/src/{drivers → shared}/backend_guard.js +78 -1
  154. package/build/src/shared/backend_guard.js.map +1 -0
  155. package/build/src/shared/sql_expiry.d.ts.map +1 -0
  156. package/build/src/shared/sql_expiry.js.map +1 -0
  157. package/build/src/shared/transaction_guard.d.ts +50 -0
  158. package/build/src/shared/transaction_guard.d.ts.map +1 -0
  159. package/build/src/shared/transaction_guard.js +60 -0
  160. package/build/src/shared/transaction_guard.js.map +1 -0
  161. package/build/src/sql_descendants.d.ts +47 -1
  162. package/build/src/sql_descendants.d.ts.map +1 -1
  163. package/build/src/sql_descendants.js +75 -1
  164. package/build/src/sql_descendants.js.map +1 -1
  165. package/build/src/testing/contract.d.ts +129 -4
  166. package/build/src/testing/contract.d.ts.map +1 -1
  167. package/build/src/testing/contract.js +912 -177
  168. package/build/src/testing/contract.js.map +1 -1
  169. package/build/src/testing/main.d.ts +8 -2
  170. package/build/src/testing/main.d.ts.map +1 -1
  171. package/build/src/testing/main.js +4 -1
  172. package/build/src/testing/main.js.map +1 -1
  173. package/build/src/testing/migration_contract.d.ts +284 -0
  174. package/build/src/testing/migration_contract.d.ts.map +1 -0
  175. package/build/src/testing/migration_contract.js +586 -0
  176. package/build/src/testing/migration_contract.js.map +1 -0
  177. package/build/src/testing/relations_contract.d.ts +73 -0
  178. package/build/src/testing/relations_contract.d.ts.map +1 -0
  179. package/build/src/testing/relations_contract.js +1069 -0
  180. package/build/src/testing/relations_contract.js.map +1 -0
  181. package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
  182. package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
  183. package/build/src/testing/relations_reconcile_contract.js +220 -0
  184. package/build/src/testing/relations_reconcile_contract.js.map +1 -0
  185. package/build/src/traits/authz_scopes.js +1 -1
  186. package/build/src/traits/authz_scopes.js.map +1 -1
  187. package/build/src/traits/has_uuid.d.ts +8 -8
  188. package/build/src/traits/has_uuid.d.ts.map +1 -1
  189. package/build/src/types.d.ts +1053 -83
  190. package/build/src/types.d.ts.map +1 -1
  191. package/build/src/types.js +10 -0
  192. package/build/src/types.js.map +1 -1
  193. package/build/stubs/config/authorization.stub +104 -4
  194. package/build/stubs/migration.stub +136 -0
  195. package/build/stubs/scopes_outbox_migration.stub +57 -0
  196. package/package.json +4 -2
  197. package/build/commands/openfga_import.d.ts +0 -34
  198. package/build/commands/openfga_import.d.ts.map +0 -1
  199. package/build/commands/openfga_import.js +0 -97
  200. package/build/commands/openfga_import.js.map +0 -1
  201. package/build/src/catalog.d.ts.map +0 -1
  202. package/build/src/catalog.js.map +0 -1
  203. package/build/src/catalog_cache.d.ts.map +0 -1
  204. package/build/src/catalog_cache.js.map +0 -1
  205. package/build/src/drivers/backend_guard.d.ts.map +0 -1
  206. package/build/src/drivers/backend_guard.js.map +0 -1
  207. package/build/src/drivers/sql_expiry.d.ts.map +0 -1
  208. package/build/src/drivers/sql_expiry.js.map +0 -1
  209. package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
  210. package/build/src/middleware/app_access_middleware.js.map +0 -1
  211. /package/build/src/{middleware → http}/app_access_middleware.d.ts +0 -0
  212. /package/build/src/{middleware → http}/app_access_middleware.js +0 -0
  213. /package/build/src/{drivers → shared}/sql_expiry.d.ts +0 -0
  214. /package/build/src/{drivers → shared}/sql_expiry.js +0 -0
@@ -0,0 +1,590 @@
1
+ /**
2
+ * Driver `openfga` del puerto `RelationsDriver` — ReBAC sobre el MISMO store y
3
+ * `modelId` que el driver `facts` de roles (Fase 4, lote 4-4).
4
+ *
5
+ * Store COMPARTIDO (decisión del dueño / juez §2): las relaciones ReBAC viven
6
+ * en el modelo FUSIONADO (`facts` + `group` + los tipos de objeto del
7
+ * consumidor), así que `relate`/`unrelate` son `Write`/delete de tuplas del
8
+ * mismo store, `check` es UN solo `Check` (el modelo resuelve includes +
9
+ * usersets del lado del servidor) y `list*` van por `ListObjects`/`Read`.
10
+ *
11
+ * **La partición va en el ID del objeto y del userset**, no en el modelo:
12
+ * `document:<scopeKey(partition)>|<uuid>`, `group:<scopeKey(partition)>|<uuid>#member`.
13
+ * El cruce de particiones se corta por comparación de string —aquí NO hay
14
+ * trigger como en `database`, así que F-05 (en el manager) + la comparación de
15
+ * string son la ÚNICA defensa de tenant—. El id lleva DOS `|` cuando la
16
+ * partición es un scope no-raíz (`document:unit|<partUuid>|<objUuid>`), así que
17
+ * el parseo es CANÓNICO desde la DERECHA (⚪5, el mismo cuidado que
18
+ * `parseBindingId`): partición = todo menos el ÚLTIMO segmento; el id del
19
+ * objeto es el último y no contiene `|`.
20
+ *
21
+ * **La frontera del 🔴 (F-05) NO vive aquí**: la cierra el `RelationsManager`
22
+ * ANTES de tocar el driver (un `object.type` no declarado ⇒ 422) junto con ⚪4
23
+ * (un tipo reservado no se puede declarar). Si a este driver se le llama en
24
+ * DIRECTO con `object.type: 'role_binding'` (la salida `manager.driver()`, de
25
+ * plataforma), compondría el id de un binding real y escalaría — por eso el
26
+ * caso-exploit del auditor se cierra en el manager, y el runner publica el
27
+ * caso para que un driver de terceros que no lo cumpla NO pase el contrato.
28
+ *
29
+ * Pureza: vive detrás del subpath `@jantstack/adonis-authz/openfga`
30
+ * (`src/openfga.ts`), como el driver `facts` de roles: es lo único que puede
31
+ * tocar `@openfga/sdk` (peer opcional). La abstracción no filtra: ningún error
32
+ * del SDK escapa (todo va por `#guard`, que clasifica a 503/timeout).
33
+ */
34
+ import { OpenFgaClient, ConsistencyPreference, ClientWriteRequestOnMissingDeletes, ClientWriteRequestOnDuplicateWrites, } from '@openfga/sdk';
35
+ import { AuthorizationBackendError, AuthorizationBackendTimeoutError, AuthorizationConfigError, InvalidIdentityError, PurgeIncompleteError, UnsupportedOperationError, } from '../errors.js';
36
+ import { assertScope, assertSubject, assertRelationId, assertExpiresAt, scopeKey, scopeSpellings } from '../identity.js';
37
+ import { isClock, systemClock } from '../clock.js';
38
+ import { resolveGrantExpiry, sameInstant, toExpiryDate } from '../expiry.js';
39
+ import { isRelUserset } from '../types.js';
40
+ import { assertFgaObjectId, FACTS_EXPIRY_CONDITION, FACTS_GROUP_TYPE, } from './openfga_facts.js';
41
+ import { assertRelationDeclared } from '../relations/define_relations_config.js';
42
+ export const DEFAULT_TIMEOUT_MS = 5_000;
43
+ /** Tope de operaciones por `Write` en FGA (`exceeded_entity_limit` a partir de 100). */
44
+ const WRITE_BATCH_SIZE = 100;
45
+ /** Tamaño de página de `Read` (máximo del servidor). */
46
+ const READ_PAGE_SIZE = 100;
47
+ /**
48
+ * Cota de páginas de una enumeración por `Read`. Un `continuation_token` que
49
+ * no avanza (servidor roto, proxy, caché) sería un bucle que ningún deadline
50
+ * corta (el deadline es por llamada). Mismo patrón que el driver de roles.
51
+ */
52
+ const MAX_READ_PAGES = 10_000;
53
+ /**
54
+ * El tope de `ListObjects` del servidor por defecto (`OPENFGA_LIST_OBJECTS_MAX_RESULTS`).
55
+ * `ListObjects` NO devuelve señal de truncado ni `continuation_token`: corta al
56
+ * tope y calla. La única forma honesta de detectar el corte es comparar el
57
+ * número de resultados con el tope CONFIGURADO del servidor —de ahí la opción
58
+ * `listObjectsMaxResults`—: si vuelven `>= tope`, no se puede prometer que la
59
+ * lista esté completa ⇒ `truncated: true` (lección S16/L0.7: nunca una lista
60
+ * parcial MUDA). Ponerlo por debajo del tope real del servidor daría un
61
+ * truncado FALSO (el servidor devolvió todo); por encima, se perdería el corte.
62
+ */
63
+ const DEFAULT_LIST_OBJECTS_MAX = 1_000;
64
+ /**
65
+ * Ignora duplicados en el `Write` de una tupla que NO estaba (idempotencia de
66
+ * dos `relate` concurrentes idénticos). Cambiar la caducidad de una que SÍ
67
+ * está es delete+write (R-15): FGA no admite reescribir la condición de una
68
+ * tupla existente y un `Ignore` la dejaría con la caducidad vieja en silencio.
69
+ */
70
+ const IGNORE_DUPLICATE_WRITES = {
71
+ conflict: { onDuplicateWrites: ClientWriteRequestOnDuplicateWrites.Ignore },
72
+ };
73
+ /** Ignora deletes de tuplas ya ausentes (re-unrelate no-op seguro, invariante 6). */
74
+ const IGNORE_MISSING_DELETES = {
75
+ conflict: { onMissingDeletes: ClientWriteRequestOnMissingDeletes.Ignore },
76
+ };
77
+ export class OpenFgaRelationsDriver {
78
+ /**
79
+ * Lo que declara (cada valor tiene su cara en `runRelationsDriverContract`):
80
+ * - `singleCheckRelations: true`: `check` es UN solo `Check` (el modelo
81
+ * resuelve includes + usersets del lado del servidor).
82
+ * - `listObjectsInherited: false`: `list*` no abren el subárbol de
83
+ * particiones (invariante 7); `ListObjects` sí resuelve la derivación del
84
+ * modelo (includes/usersets), que es «directos + derivados», no herencia
85
+ * de scopes.
86
+ * - `usersetSubjects: true`: `listSubjects` (`Read`) trae los usersets
87
+ * directos (`group#member`) junto con los holders.
88
+ * - `membersOfNative: false`: la membresía TRANSITIVA sería `ListUsers`, que
89
+ * trunca al tope del servidor; se declara 500 `E_AUTHZ_UNSUPPORTED`, jamás
90
+ * un userset enumerado a medias (par de `purgeRole` de la 3b).
91
+ * - `enumerateRelations: true` (4-5): es ORIGEN de `authz:reconcile` de
92
+ * relaciones — lee el store ENTERO (`Read({})`, la única forma de ver todo
93
+ * sin filtro por user u objeto: un `Read` por tipo-solo sin user es un 400)
94
+ * y devuelve SOLO las tuplas de relación de la partición (tipo declarado o
95
+ * `group`), descartando las de `facts` (scope/role/role_binding).
96
+ * - `listObjectsTruncation: true`: `ListObjects` trunca al tope del servidor
97
+ * y este driver lo SEÑALA (medido contra el `:8103` de tope 3).
98
+ * - `injectableClock: true` (R-15): `withClock(now)` fija el reloj que viaja
99
+ * como `current_time` y filtra `listSubjects`, como el driver de roles.
100
+ */
101
+ capabilities = Object.freeze({
102
+ singleCheckRelations: true,
103
+ listObjectsInherited: false,
104
+ usersetSubjects: true,
105
+ membersOfNative: false,
106
+ enumerateRelations: true,
107
+ listObjectsTruncation: true,
108
+ injectableClock: true,
109
+ // L-2/L-5 (panel `{trx}`, (C)): `false` EXPLÍCITO, y no puede ser otra
110
+ // cosa — una tupla no entra en una transacción SQL: el store es otro
111
+ // servicio y no hay 2PC, así que «los dos o ninguno» con la transacción
112
+ // del consumidor es una promesa que este driver no puede hacer, y no la
113
+ // hace. `{ transaction }` es 500 `E_AUTHZ_UNSUPPORTED` por llamada, en el
114
+ // `RelationsManager` (puerta 1) Y en el driver (`#rejectTransaction`,
115
+ // para quien entre por `manager.driver()` o por `reconcileRelations`),
116
+ // con CERO llamadas al store (L-5 lo fija contra el `:8101` con espía
117
+ // sobre el cliente). La alternativa que SÍ existe es para el ÁRBOL de
118
+ // scopes: `scopes.outbox` encola en tu transacción y `authz:scopes:relay`
119
+ // aplica. Para las RELACIONES no hay outbox (el panel la descartó:
120
+ // fail-open medido durante el lag); el consumidor lee esta capacidad y
121
+ // ajusta (usa `database` para lo que tenga que ir en su transacción, o
122
+ // `requireTransactionalWrites` para fallar al arrancar).
123
+ transactionalWrites: false,
124
+ });
125
+ client;
126
+ #config;
127
+ #options;
128
+ #now;
129
+ #holderTypes;
130
+ #fgaToMorph;
131
+ #timeoutMs;
132
+ #consistency;
133
+ #listObjectsMax;
134
+ #logger;
135
+ diagnostics = { unparseableTuples: 0 };
136
+ constructor(config, options) {
137
+ this.#config = config;
138
+ this.#options = options;
139
+ this.#now = options.now ?? systemClock;
140
+ this.#holderTypes = options.holderTypes;
141
+ this.#fgaToMorph = Object.fromEntries(Object.entries(options.holderTypes).map(([morph, fga]) => [fga, morph]));
142
+ this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
143
+ this.#consistency =
144
+ options.consistency === 'minimize_latency'
145
+ ? ConsistencyPreference.MinimizeLatency
146
+ : ConsistencyPreference.HigherConsistency;
147
+ this.#listObjectsMax = options.listObjectsMaxResults ?? DEFAULT_LIST_OBJECTS_MAX;
148
+ this.#logger = options.logger ?? console;
149
+ this.client = new OpenFgaClient({
150
+ apiUrl: options.apiUrl,
151
+ storeId: options.storeId,
152
+ authorizationModelId: options.modelId,
153
+ baseOptions: { timeout: this.#timeoutMs },
154
+ retryParams: { maxRetry: 0 },
155
+ });
156
+ }
157
+ /**
158
+ * Vista de este driver con OTRO reloj de pared (R-15, paridad con
159
+ * `AuthorizationDriver.withClock`): MISMO cliente (store, modelo, deadline),
160
+ * solo cambia el `now` que decide la caducidad. Se construye una instancia
161
+ * nueva y se le presta el cliente (el espía de «1 Check» envuelve
162
+ * `client.check` de la instancia base y tiene que seguir viéndolo).
163
+ */
164
+ withClock(now) {
165
+ if (!isClock(now)) {
166
+ throw new AuthorizationConfigError(`withClock: now debe ser una función () => Date (llegó ${typeof now})`);
167
+ }
168
+ const view = new OpenFgaRelationsDriver(this.#config, { ...this.#options, now });
169
+ view.client = this.client;
170
+ return view;
171
+ }
172
+ /** El `context` de todo `Check`/`ListObjects`: la condición `not_expired` se evalúa contra este instante (un `now` por operación). */
173
+ #checkContext(at) {
174
+ return { current_time: at.toISOString() };
175
+ }
176
+ /* ── Clasificación de fallos (la abstracción no filtra) ─────────────────── */
177
+ async #guard(operation, fn) {
178
+ try {
179
+ return await fn();
180
+ }
181
+ catch (error) {
182
+ // Un error del paquete (422/500 ya clasificado) se propaga tal cual.
183
+ if (error instanceof InvalidIdentityError || error instanceof PurgeIncompleteError)
184
+ throw error;
185
+ if (isTimeoutLike(error)) {
186
+ throw new AuthorizationBackendTimeoutError('openfga-relations', operation, this.#timeoutMs, error);
187
+ }
188
+ throw new AuthorizationBackendError('openfga-relations', operation, error);
189
+ }
190
+ }
191
+ /* ── Composición y parseo de ids (⚪5: partición por string en el id) ────── */
192
+ /** `<type>:<scopeKey(partition)>|<objectUuid>`. */
193
+ #objectId(objectType, partitionKey, objectUuid) {
194
+ // R-16 (defensa en profundidad, paridad con `database`): el `object.id` con
195
+ // la gramática estricta ANTES de componer. Un `|`/`#`/`:`/espacio dentro se
196
+ // escribía (solo se medía la longitud) y luego se perdía en el parseo por
197
+ // el último `|` —invisible en enumeración y `reconcile`—. `manager.driver()`
198
+ // salta el manager, así que el driver aplica la MISMA regla que él.
199
+ assertRelationId(`el id del objeto '${objectType}'`, objectUuid);
200
+ const id = `${objectType}:${partitionKey}|${objectUuid}`;
201
+ assertFgaObjectId(objectType, id);
202
+ return id;
203
+ }
204
+ /**
205
+ * El `user` FGA de un sujeto: holder ⇒ `<fgaType>:<uuid>`; userset ⇒
206
+ * `<type>:<scopeKey(partition)>|<objUuid>#<relation>`. El userset comparte la
207
+ * partición de la tupla (el manager lo exige).
208
+ */
209
+ #subjectUser(subject, partitionKey) {
210
+ if (isRelUserset(subject)) {
211
+ const object = this.#objectId(subject.object.type, partitionKey, subject.object.id);
212
+ return `${object}#${subject.relation}`;
213
+ }
214
+ const fgaType = this.#holderTypes[subject.type];
215
+ if (!fgaType) {
216
+ throw new InvalidIdentityError(`Holder type '${subject.type}' no está en holderTypes del driver openfga de relaciones ` +
217
+ `(declarados: ${Object.keys(this.#holderTypes).join(', ') || 'ninguno'}).`);
218
+ }
219
+ return `${fgaType}:${subject.uuid}`;
220
+ }
221
+ /**
222
+ * **Parseo CANÓNICO del id de un objeto de relación** (⚪5): a partir de
223
+ * `<type>:<scopeKey>|<objUuid>`, separa `type` (antes del primer `:`),
224
+ * `partitionKey` (todo menos el ÚLTIMO segmento tras el `:`) y `objectUuid`
225
+ * (el último segmento, que no contiene `|`). Es el MISMO parseo-desde-la-
226
+ * derecha que `parseBindingId`: `lastIndexOf('|')` corta el objeto de la
227
+ * clave de partición (que tiene 1 parte `app` o 2 `<tipo>|<uuid>`). `null` si
228
+ * el id no tiene la forma que este driver escribe.
229
+ */
230
+ #parseObjectId(fullId) {
231
+ const colon = fullId.indexOf(':');
232
+ if (colon <= 0)
233
+ return null;
234
+ const type = fullId.slice(0, colon);
235
+ const rest = fullId.slice(colon + 1);
236
+ const cut = rest.lastIndexOf('|');
237
+ if (cut < 0)
238
+ return null;
239
+ const partitionKey = rest.slice(0, cut);
240
+ const objectUuid = rest.slice(cut + 1);
241
+ if (!partitionKey || !objectUuid)
242
+ return null;
243
+ return { type, partitionKey, objectUuid };
244
+ }
245
+ /** Un `user` del store de vuelta a `RelSubject`: userset (`…#rel`) o holder (`<fga>:<uuid>`). */
246
+ #userToSubject(user) {
247
+ const hash = user.indexOf('#');
248
+ if (hash >= 0) {
249
+ const parsed = this.#parseObjectId(user.slice(0, hash));
250
+ const relation = user.slice(hash + 1);
251
+ if (!parsed || !relation)
252
+ return null;
253
+ return { object: { type: parsed.type, id: parsed.objectUuid }, relation };
254
+ }
255
+ const colon = user.indexOf(':');
256
+ if (colon <= 0)
257
+ return null;
258
+ const morph = this.#fgaToMorph[user.slice(0, colon)];
259
+ const uuid = user.slice(colon + 1);
260
+ if (!morph || !uuid || uuid === '*' || uuid.includes('|'))
261
+ return null;
262
+ return { type: morph, uuid };
263
+ }
264
+ /* ── Escrituras ─────────────────────────────────────────────────────────── */
265
+ /**
266
+ * `relate` con los tres estados de `expiresAt` (R-15, invariante 10). Se LEE
267
+ * primero la tupla exacta (un `Read` por clave, como `grant` de roles):
268
+ * - ausente ⇒ un `Write` (con la condición `not_expired` si caduca);
269
+ * - presente con la caducidad que toca ⇒ no-op (idempotente, invariante 6);
270
+ * - presente con OTRA ⇒ delete + write en DOS llamadas (FGA no admite
271
+ * delete+write de la misma clave en un `Write`, ni reescribir su
272
+ * condición): entre ambas hay un instante en el que `check` responde
273
+ * `false` —fail-closed, la misma ventana que el `grant` de roles—.
274
+ */
275
+ /**
276
+ * **`{ transaction }` se rechaza también AQUÍ** (L-5, defensa en
277
+ * profundidad como F-05 en L-0): la puerta 1 vive en el `RelationsManager`,
278
+ * pero `manager.driver()` y `reconcileRelations` entran por el driver; sin
279
+ * esta guarda un `{ transaction }` por ahí escribiría la tupla en el store
280
+ * IGNORANDO la transacción — una escritura que finge ir en tu transacción y
281
+ * que tu rollback no deshace, que es exactamente el fail-open que
282
+ * `transactionalWrites: false` declara no poder evitar. Primera línea de
283
+ * las cuatro escrituras, antes de F-05, del `Read` y del `Write`: CERO
284
+ * llamadas al cliente.
285
+ */
286
+ #rejectTransaction(operation, options) {
287
+ if (options?.transaction === undefined || options.transaction === null)
288
+ return;
289
+ throw UnsupportedOperationError.transactionalDriver(`relations.${operation}`, 'openfga', 'relations');
290
+ }
291
+ async relate(subject, relation, object, partition, options) {
292
+ this.#rejectTransaction('relate', options);
293
+ // L-0 · F-05 en el DRIVER (defensa en profundidad, la MISMA función que el
294
+ // manager): `manager.driver()` y `reconcileRelations` entran por aquí, y en
295
+ // el store COMPARTIDO un tipo no declarado (`role_binding`) compondría el
296
+ // id exacto de un binding de roles. Corta ANTES del `Read` y del `Write`.
297
+ assertRelationDeclared(this.#config, object, relation);
298
+ assertScope(partition);
299
+ assertExpiresAt(options?.expiresAt);
300
+ const partitionKey = scopeKey(partition);
301
+ const objectId = this.#objectId(object.type, partitionKey, object.id);
302
+ const user = this.#subjectUser(subject, partitionKey);
303
+ const key = { user, relation, object: objectId };
304
+ const now = this.#now();
305
+ const current = await this.#readTuple('relate', key);
306
+ const previous = current ? current.validUntil : null;
307
+ const expiresAt = resolveGrantExpiry(previous, options?.expiresAt, now);
308
+ if (current && sameInstant(previous, expiresAt))
309
+ return;
310
+ const tuple = expiresAt
311
+ ? { ...key, condition: { name: FACTS_EXPIRY_CONDITION, context: { valid_until: expiresAt.toISOString() } } }
312
+ : key;
313
+ if (current) {
314
+ await this.#guard('relate', () => this.client.write({ deletes: [key] }, IGNORE_MISSING_DELETES));
315
+ }
316
+ await this.#guard('relate', () => this.client.write({ writes: [tuple] }, IGNORE_DUPLICATE_WRITES));
317
+ }
318
+ /** La tupla EXACTA de una clave (un `Read` por clave completa), con su caducidad si la lleva. */
319
+ async #readTuple(operation, key) {
320
+ const response = await this.#guard(operation, () => this.client.read(key, { consistency: this.#consistency }));
321
+ const found = (response.tuples ?? []).map((t) => t.key).find((k) => k?.user === key.user && k?.relation === key.relation && k?.object === key.object);
322
+ if (!found)
323
+ return null;
324
+ return { ...key, validUntil: toExpiryDate(found.condition?.context?.valid_until) };
325
+ }
326
+ async unrelate(subject, relation, object, partition, options) {
327
+ this.#rejectTransaction('unrelate', options);
328
+ // L-0 · F-05 también al RETIRAR: un `unrelate(alice, assignee, role_binding)`
329
+ // sería un revoke de roles por la puerta de relaciones.
330
+ assertRelationDeclared(this.#config, object, relation);
331
+ assertScope(partition);
332
+ const partitionKey = scopeKey(partition);
333
+ const objectId = this.#objectId(object.type, partitionKey, object.id);
334
+ const user = this.#subjectUser(subject, partitionKey);
335
+ await this.#guard('unrelate', () =>
336
+ // Re-unrelate no-op seguro: borrar una tupla ausente se ignora.
337
+ this.client.write({ deletes: [{ user, relation, object: objectId }] }, IGNORE_MISSING_DELETES));
338
+ }
339
+ /* ── Lecturas ───────────────────────────────────────────────────────────── */
340
+ /** `check` = UN solo `Check` (el modelo resuelve includes + usersets). */
341
+ async check(subject, relation, object, partition) {
342
+ assertScope(partition);
343
+ const partitionKey = scopeKey(partition);
344
+ const objectId = this.#objectId(object.type, partitionKey, object.id);
345
+ const user = this.#subjectUser(subject, partitionKey);
346
+ const context = this.#checkContext(this.#now());
347
+ const response = await this.#guard('check', () => this.client.check({ user, relation, object: objectId, context }, { consistency: this.#consistency }));
348
+ return response.allowed === true;
349
+ }
350
+ /**
351
+ * `listObjects` = `ListObjects` (resuelve includes + usersets del lado del
352
+ * servidor) + FILTRO por partición + señal de TRUNCADO. `ListObjects` corta
353
+ * al tope del servidor sin `continuation_token` ni bandera, así que el
354
+ * truncado se detecta comparando el número de resultados CRUDOS con el tope
355
+ * configurado (`listObjectsMaxResults`): `>= tope` ⇒ no se puede prometer la
356
+ * lista completa ⇒ `truncated: true`. El filtro por partición se aplica
357
+ * DESPUÉS (los ids llevan la partición), así que en un store con varias
358
+ * particiones el tope se consume entre todas — otra razón para señalar el
359
+ * truncado y no callar (documentado en el README).
360
+ */
361
+ async listObjects(subject, relation, objectType, partition, _page) {
362
+ assertScope(partition);
363
+ const partitionKey = scopeKey(partition);
364
+ const user = this.#subjectUser(subject, partitionKey);
365
+ const context = this.#checkContext(this.#now());
366
+ const response = await this.#guard('listObjects', () => this.client.listObjects({ user, relation, type: objectType, context }, { consistency: this.#consistency }));
367
+ const raw = response.objects ?? [];
368
+ const truncated = raw.length >= this.#listObjectsMax;
369
+ const objects = [];
370
+ for (const full of raw) {
371
+ const parsed = this.#parseObjectId(full);
372
+ if (!parsed || parsed.type !== objectType) {
373
+ this.#warnUnparseable('listObjects', full);
374
+ continue;
375
+ }
376
+ if (parsed.partitionKey !== partitionKey)
377
+ continue; // otra partición: no cruza
378
+ objects.push({ type: objectType, id: parsed.objectUuid });
379
+ }
380
+ objects.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
381
+ return truncated ? { objects, truncated: true } : { objects };
382
+ }
383
+ /**
384
+ * `listSubjects` = `Read` por `(object, relation)` — hechos DIRECTOS del
385
+ * relation EXACTO (invariante 7): ni transitivo (eso es `membersOf`) ni
386
+ * derivado por includes. `usersetSubjects: true` ⇒ los usersets
387
+ * (`group#member`) salen junto con los holders.
388
+ */
389
+ async listSubjects(relation, object, partition, _page) {
390
+ assertScope(partition);
391
+ const partitionKey = scopeKey(partition);
392
+ const objectId = this.#objectId(object.type, partitionKey, object.id);
393
+ // `Read` devuelve tuplas ESCRITAS, no evaluadas: la caducidad se filtra en
394
+ // cliente con el MISMO reloj del driver (R-15, estricta: la que vence en
395
+ // `now` ya no cuenta), como las enumeraciones del driver de roles.
396
+ const now = this.#now();
397
+ const tuples = await this.#readAll('listSubjects', { object: objectId, relation });
398
+ const subjects = [];
399
+ for (const t of tuples) {
400
+ if (t.validUntil && t.validUntil.getTime() <= now.getTime())
401
+ continue;
402
+ const subject = this.#userToSubject(t.user);
403
+ if (subject)
404
+ subjects.push(subject);
405
+ else
406
+ this.#warnUnparseable('listSubjects', t.user);
407
+ }
408
+ return { subjects };
409
+ }
410
+ /**
411
+ * **`membersOf` ⇒ 500 `E_AUTHZ_UNSUPPORTED`** (cara `whenFalse`): la
412
+ * membresía TRANSITIVA de un grupo sería `ListUsers`, que trunca al tope del
413
+ * servidor sin señal fiable. No hay userset transitivo enumerable aquí; se
414
+ * dice con 500 nombrándolo, jamás un userset a medias. Es el análogo del par
415
+ * `purgeRole` de la 3b. (El método existe en el prototipo para que el manager
416
+ * lo despache, pero la capacidad `membersOfNative: false` lo corta antes.)
417
+ */
418
+ async membersOf() {
419
+ throw new UnsupportedOperationError('membersOf', 'la membresía transitiva de un grupo', 'openfga', `En 'openfga' la transitiva sería 'ListUsers', que trunca al tope del servidor sin señal fiable. ` +
420
+ `Usa el driver 'database' (CTE recursiva) o 'listSubjects' para los hechos directos.`);
421
+ }
422
+ /* ── ORIGEN de reconcile (4-5): las tuplas de relación de la partición ──── */
423
+ /**
424
+ * **`enumerateRelations` — el ORIGEN de `authz:reconcile` de relaciones**
425
+ * (4-5). Lee el store ENTERO (`Read({})`) —la única forma de ver todo sin un
426
+ * filtro por `user` u `object`, que un `Read` por tipo-solo sin user
427
+ * rechazaría con 400— y devuelve SOLO las tuplas de relación de la partición
428
+ * pedida: tipo `group` o un tipo declarado en la config, DESCARTANDO las de
429
+ * `facts` (`scope`/`role`/`role_binding`, que no llevan la partición en el id
430
+ * con la forma `<key>|<uuid>` de relaciones —o cuyo tipo no está declarado—).
431
+ *
432
+ * `truncated`/paginación: `enumerateRelations` agota el `Read` (exhaustivo,
433
+ * como `listSubjects`/`purge*`), así que devuelve TODO en una página sin
434
+ * cursor —el reconcile itera hasta que no hay cursor—. Es el ORIGEN de una
435
+ * migración: una tupla que no llegara aquí desaparecería sin rastro — por eso
436
+ * la CADUCADA también llega, con su `expiresAt` (R-15), para que el destino
437
+ * la cuente en `skipped`.
438
+ */
439
+ async enumerateRelations(partition, _page) {
440
+ assertScope(partition);
441
+ const partitionKey = scopeKey(partition);
442
+ const relationTypes = new Set([FACTS_GROUP_TYPE, ...this.#config.objectTypes.map((t) => t.type)]);
443
+ const all = await this.#readAll('enumerateRelations', {});
444
+ const tuples = [];
445
+ for (const key of all) {
446
+ const parsed = this.#parseObjectId(key.object);
447
+ // No es una tupla de relación (facts: scope/role/role_binding, o un tipo
448
+ // no declarado): no la migra este puerto.
449
+ if (!parsed || !relationTypes.has(parsed.type))
450
+ continue;
451
+ if (parsed.partitionKey !== partitionKey)
452
+ continue; // otra partición: no cruza
453
+ const subject = this.#userToSubject(key.user);
454
+ if (!subject) {
455
+ this.#warnUnparseable('enumerateRelations', key.user);
456
+ continue;
457
+ }
458
+ tuples.push({
459
+ subject,
460
+ relation: key.relation,
461
+ object: { type: parsed.type, id: parsed.objectUuid },
462
+ partition,
463
+ expiresAt: key.validUntil,
464
+ });
465
+ }
466
+ return { tuples };
467
+ }
468
+ /* ── Purga (invariante 11): borra y DEMUESTRA cero, o lanza ─────────────── */
469
+ /**
470
+ * Borra TODAS las tuplas del objeto (cualquier relación) y demuestra cero.
471
+ * Barre las DOS ortografías del uuid de partición (🟡2, paridad con
472
+ * `database`): un motor que funda `aaa…` con `aaa-…` dejaría la fila del
473
+ * alias concediendo tras una purga «exitosa». Si tras borrar quedan tuplas
474
+ * ⇒ 500 `E_AUTHZ_PURGE_INCOMPLETE`.
475
+ */
476
+ async purgeObject(object, partition, options) {
477
+ this.#rejectTransaction('purgeObject', options);
478
+ assertScope(partition);
479
+ const objectIds = this.#partitionSpellings(partition).map((key) => this.#objectId(object.type, key, object.id));
480
+ for (const objectId of objectIds) {
481
+ await this.#purgeByFilter('purgeObject', { object: objectId }, `objeto ${objectId}`);
482
+ }
483
+ }
484
+ /**
485
+ * Borra TODAS las tuplas cuyo SUJETO es este subject en la partición, en
486
+ * cualquier tipo de objeto declarado, y demuestra cero. `Read` exige un
487
+ * filtro de objeto (un `Read` solo por `user` es un 400 del servidor), así
488
+ * que se recorre cada tipo declarado (`group` + los del consumidor) con
489
+ * `Read({ user, object: '<type>:' })`.
490
+ */
491
+ async purgeSubject(subject, partition, options) {
492
+ this.#rejectTransaction('purgeSubject', options);
493
+ assertScope(partition);
494
+ if (!isRelUserset(subject))
495
+ assertSubject(subject);
496
+ const partitionKeys = this.#partitionSpellings(partition);
497
+ const types = [FACTS_GROUP_TYPE, ...this.#config.objectTypes.map((t) => t.type)];
498
+ for (const partitionKey of partitionKeys) {
499
+ const user = this.#subjectUser(subject, partitionKey);
500
+ for (const type of types) {
501
+ await this.#purgeByFilter('purgeSubject', { user, object: `${type}:` }, `sujeto ${user} en '${type}'`);
502
+ }
503
+ }
504
+ }
505
+ /** Lee por filtro, borra en lotes, y RE-LEE para demostrar cero (o lanza). */
506
+ async #purgeByFilter(operation, filter, what) {
507
+ const keys = await this.#readAll(operation, filter);
508
+ for (let i = 0; i < keys.length; i += WRITE_BATCH_SIZE) {
509
+ await this.#guard(operation, () => this.client.deleteTuples(keys.slice(i, i + WRITE_BATCH_SIZE).map((k) => ({ user: k.user, relation: k.relation, object: k.object })), IGNORE_MISSING_DELETES));
510
+ }
511
+ if (keys.length === 0)
512
+ return;
513
+ // Demostración de cero: re-lee tras borrar (invariante 11).
514
+ const residue = await this.#readAll(operation, filter);
515
+ if (residue.length > 0) {
516
+ throw new PurgeIncompleteError(`${operation}: quedan ${residue.length} tuplas de ${what} tras el borrado ` +
517
+ `(${residue.slice(0, 3).map((k) => `${k.user}#${k.relation}@${k.object}`).join('; ')}). ` +
518
+ `No se confirma la purga.`);
519
+ }
520
+ }
521
+ /* ── Helpers ────────────────────────────────────────────────────────────── */
522
+ /** Las dos ortografías del uuid de partición, como claves de scope (🟡2). */
523
+ #partitionSpellings(partition) {
524
+ return [...new Set(scopeSpellings(partition).map((s) => scopeKey(s)))];
525
+ }
526
+ /**
527
+ * TODAS las tuplas que casan con el filtro, paginando `Read` hasta agotar el
528
+ * `continuation_token`. `Read` no tiene tope de resultados (a diferencia de
529
+ * `ListObjects`), así que es exhaustivo — por eso las purgas y `listSubjects`
530
+ * van por aquí, no por `ListObjects`.
531
+ */
532
+ async #readAll(operation, filter) {
533
+ const keys = [];
534
+ let continuationToken;
535
+ const seenTokens = new Set();
536
+ let pages = 0;
537
+ do {
538
+ const response = await this.#guard(operation, () => this.client.read(filter, {
539
+ pageSize: READ_PAGE_SIZE,
540
+ continuationToken,
541
+ consistency: this.#consistency,
542
+ }));
543
+ pages += 1;
544
+ for (const tuple of response.tuples ?? []) {
545
+ const key = tuple?.key;
546
+ if (!key?.user || !key?.relation || !key?.object) {
547
+ this.#warnUnparseable(operation, JSON.stringify(key ?? null));
548
+ continue;
549
+ }
550
+ // Con su caducidad (R-15): quien la lee decide si filtra (`listSubjects`),
551
+ // la emite (`enumerateRelations`) o la ignora (`purge*` borra TODO).
552
+ keys.push({
553
+ user: key.user,
554
+ relation: key.relation,
555
+ object: key.object,
556
+ validUntil: toExpiryDate(key.condition?.context?.valid_until),
557
+ });
558
+ }
559
+ continuationToken = response.continuation_token || undefined;
560
+ if (continuationToken) {
561
+ if (seenTokens.has(continuationToken)) {
562
+ throw new AuthorizationBackendError('openfga-relations', operation, new Error(`el continuation_token se repite (página ${pages}); el servidor no avanza`));
563
+ }
564
+ if (pages >= MAX_READ_PAGES) {
565
+ throw new AuthorizationBackendError('openfga-relations', operation, new Error(`más de ${MAX_READ_PAGES} páginas sin agotar el Read`));
566
+ }
567
+ seenTokens.add(continuationToken);
568
+ }
569
+ } while (continuationToken);
570
+ return keys;
571
+ }
572
+ #warnUnparseable(operation, detail) {
573
+ this.diagnostics.unparseableTuples += 1;
574
+ this.#logger.warn(`authz(openfga-relations): tupla no parseable en ${operation} (${detail}); ` +
575
+ `se ignora en la enumeración (total: ${this.diagnostics.unparseableTuples})`);
576
+ }
577
+ }
578
+ /** ¿El error huele a timeout de red/axios? (mismo criterio que el driver de roles). */
579
+ function isTimeoutLike(error) {
580
+ let current = error;
581
+ for (let depth = 0; current && depth < 6; depth++) {
582
+ const code = String(current.code ?? '');
583
+ if (code === 'ECONNABORTED' || code === 'ETIMEDOUT' || /timeout/i.test(String(current.message ?? ''))) {
584
+ return true;
585
+ }
586
+ current = current.cause;
587
+ }
588
+ return false;
589
+ }
590
+ //# sourceMappingURL=openfga_relations_driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfga_relations_driver.js","sourceRoot":"","sources":["../../../src/drivers/openfga_relations_driver.ts"],"names":[],"mappings":"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"}