@jantstack/adonis-authz 2.4.0-alpha.9 → 2.5.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 (128) hide show
  1. package/README.md +468 -30
  2. package/build/commands/authz_freeze.js +1 -1
  3. package/build/commands/authz_freeze.js.map +1 -1
  4. package/build/commands/authz_reconcile.d.ts +6 -2
  5. package/build/commands/authz_reconcile.d.ts.map +1 -1
  6. package/build/commands/authz_reconcile.js +129 -13
  7. package/build/commands/authz_reconcile.js.map +1 -1
  8. package/build/commands/authz_relations_reconcile.d.ts +16 -24
  9. package/build/commands/authz_relations_reconcile.d.ts.map +1 -1
  10. package/build/commands/authz_relations_reconcile.js +198 -49
  11. package/build/commands/authz_relations_reconcile.js.map +1 -1
  12. package/build/commands/authz_scopes_relay.d.ts.map +1 -1
  13. package/build/commands/authz_scopes_relay.js +81 -1
  14. package/build/commands/authz_scopes_relay.js.map +1 -1
  15. package/build/commands/authz_unfreeze.d.ts +12 -4
  16. package/build/commands/authz_unfreeze.d.ts.map +1 -1
  17. package/build/commands/authz_unfreeze.js +74 -9
  18. package/build/commands/authz_unfreeze.js.map +1 -1
  19. package/build/index.d.ts +6 -4
  20. package/build/index.d.ts.map +1 -1
  21. package/build/index.js +5 -3
  22. package/build/index.js.map +1 -1
  23. package/build/providers/authz_provider.d.ts +1 -1
  24. package/build/providers/authz_provider.d.ts.map +1 -1
  25. package/build/providers/authz_provider.js +5 -1
  26. package/build/providers/authz_provider.js.map +1 -1
  27. package/build/src/define_config.d.ts +41 -0
  28. package/build/src/define_config.d.ts.map +1 -1
  29. package/build/src/define_config.js +120 -0
  30. package/build/src/define_config.js.map +1 -1
  31. package/build/src/drivers/database_driver.d.ts.map +1 -1
  32. package/build/src/drivers/database_driver.js +1 -0
  33. package/build/src/drivers/database_driver.js.map +1 -1
  34. package/build/src/drivers/database_relations_driver.d.ts +18 -6
  35. package/build/src/drivers/database_relations_driver.d.ts.map +1 -1
  36. package/build/src/drivers/database_relations_driver.js +94 -46
  37. package/build/src/drivers/database_relations_driver.js.map +1 -1
  38. package/build/src/drivers/openfga_driver.d.ts +46 -5
  39. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  40. package/build/src/drivers/openfga_driver.js +115 -29
  41. package/build/src/drivers/openfga_driver.js.map +1 -1
  42. package/build/src/drivers/openfga_relations_driver.d.ts +82 -13
  43. package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -1
  44. package/build/src/drivers/openfga_relations_driver.js +216 -55
  45. package/build/src/drivers/openfga_relations_driver.js.map +1 -1
  46. package/build/src/errors.d.ts +86 -0
  47. package/build/src/errors.d.ts.map +1 -1
  48. package/build/src/errors.js +86 -0
  49. package/build/src/errors.js.map +1 -1
  50. package/build/src/freeze.d.ts +63 -4
  51. package/build/src/freeze.d.ts.map +1 -1
  52. package/build/src/freeze.js +107 -18
  53. package/build/src/freeze.js.map +1 -1
  54. package/build/src/identity.d.ts +120 -9
  55. package/build/src/identity.d.ts.map +1 -1
  56. package/build/src/identity.js +164 -12
  57. package/build/src/identity.js.map +1 -1
  58. package/build/src/manager.d.ts +64 -2
  59. package/build/src/manager.d.ts.map +1 -1
  60. package/build/src/manager.js +267 -35
  61. package/build/src/manager.js.map +1 -1
  62. package/build/src/openfga.d.ts +2 -2
  63. package/build/src/openfga.d.ts.map +1 -1
  64. package/build/src/openfga.js +2 -2
  65. package/build/src/openfga.js.map +1 -1
  66. package/build/src/relations/check_many.d.ts +17 -0
  67. package/build/src/relations/check_many.d.ts.map +1 -0
  68. package/build/src/relations/check_many.js +57 -0
  69. package/build/src/relations/check_many.js.map +1 -0
  70. package/build/src/relations/define_relations_config.d.ts +74 -1
  71. package/build/src/relations/define_relations_config.d.ts.map +1 -1
  72. package/build/src/relations/define_relations_config.js +201 -7
  73. package/build/src/relations/define_relations_config.js.map +1 -1
  74. package/build/src/relations/manager.d.ts +20 -0
  75. package/build/src/relations/manager.d.ts.map +1 -1
  76. package/build/src/relations/manager.js +88 -15
  77. package/build/src/relations/manager.js.map +1 -1
  78. package/build/src/relations/reconcile.d.ts +134 -3
  79. package/build/src/relations/reconcile.d.ts.map +1 -1
  80. package/build/src/relations/reconcile.js +340 -36
  81. package/build/src/relations/reconcile.js.map +1 -1
  82. package/build/src/relations/tuple_key.d.ts +25 -0
  83. package/build/src/relations/tuple_key.d.ts.map +1 -0
  84. package/build/src/relations/tuple_key.js +60 -0
  85. package/build/src/relations/tuple_key.js.map +1 -0
  86. package/build/src/relations_config_store.d.ts.map +1 -1
  87. package/build/src/relations_config_store.js +29 -7
  88. package/build/src/relations_config_store.js.map +1 -1
  89. package/build/src/relations_reconcile.d.ts +79 -0
  90. package/build/src/relations_reconcile.d.ts.map +1 -0
  91. package/build/src/relations_reconcile.js +85 -0
  92. package/build/src/relations_reconcile.js.map +1 -0
  93. package/build/src/scope_outbox.d.ts +9 -5
  94. package/build/src/scope_outbox.d.ts.map +1 -1
  95. package/build/src/scope_outbox.js +7 -4
  96. package/build/src/scope_outbox.js.map +1 -1
  97. package/build/src/shared/backend_guard.d.ts +30 -11
  98. package/build/src/shared/backend_guard.d.ts.map +1 -1
  99. package/build/src/shared/backend_guard.js +45 -15
  100. package/build/src/shared/backend_guard.js.map +1 -1
  101. package/build/src/shared/sql_expiry.d.ts +2 -0
  102. package/build/src/shared/sql_expiry.d.ts.map +1 -1
  103. package/build/src/shared/sql_expiry.js +4 -0
  104. package/build/src/shared/sql_expiry.js.map +1 -1
  105. package/build/src/testing/main.d.ts +3 -1
  106. package/build/src/testing/main.d.ts.map +1 -1
  107. package/build/src/testing/main.js +2 -1
  108. package/build/src/testing/main.js.map +1 -1
  109. package/build/src/testing/migration_contract.d.ts +9 -0
  110. package/build/src/testing/migration_contract.d.ts.map +1 -1
  111. package/build/src/testing/migration_contract.js +5 -2
  112. package/build/src/testing/migration_contract.js.map +1 -1
  113. package/build/src/testing/relations_contract.d.ts +14 -0
  114. package/build/src/testing/relations_contract.d.ts.map +1 -1
  115. package/build/src/testing/relations_contract.js +367 -21
  116. package/build/src/testing/relations_contract.js.map +1 -1
  117. package/build/src/testing/scope_outbox_contract.d.ts +14 -1
  118. package/build/src/testing/scope_outbox_contract.d.ts.map +1 -1
  119. package/build/src/testing/scope_outbox_contract.js +126 -48
  120. package/build/src/testing/scope_outbox_contract.js.map +1 -1
  121. package/build/src/testing/test_clock.d.ts +15 -0
  122. package/build/src/testing/test_clock.d.ts.map +1 -0
  123. package/build/src/testing/test_clock.js +65 -0
  124. package/build/src/testing/test_clock.js.map +1 -0
  125. package/build/src/types.d.ts +115 -12
  126. package/build/src/types.d.ts.map +1 -1
  127. package/build/src/types.js.map +1 -1
  128. package/package.json +6 -1
@@ -19,23 +19,31 @@
19
19
  * puerto (`../types.js`), los errores y la config de relaciones. NO importa
20
20
  * `manager` ni `drivers/*`: los drivers concretos los inyecta el llamante (la
21
21
  * plataforma), como `manager.reconcile` recibe el destino por su clave.
22
+ *
23
+ * **Es un PRIMITIVO PRIVADO** (cierre del auditor de alpha.10 · R1): no sabe
24
+ * cuál es el driver activo ni toma la ventana durable, así que ya no sale de la
25
+ * raíz del paquete. La vía pública es `runRelationsReconcile`
26
+ * (`commands/authz_relations_reconcile.ts`), que resuelve origen y destino por
27
+ * clave, niega la dirección rancia y congela; la guardia de superficie de
28
+ * `command_flags.spec.ts` impide re-exportarlo por ningún subpath.
22
29
  */
23
- import { AuthorizationConfigError, MassReconcileRefusedError, RelationTypeUnknownError, RelationUnknownError, UnsupportedOperationError, } from '../errors.js';
30
+ import { AuthorizationConfigError, InvalidIdentityError, MassReconcileRefusedError, RelationTypeUnknownError, RelationUnknownError, RelationUsersetUnsupportedError, UnsupportedOperationError, } from '../errors.js';
24
31
  import { systemClock } from '../clock.js';
25
32
  import { isActiveExpiry, sameInstant } from '../expiry.js';
33
+ import { assertPartition, scopeKey } from '../identity.js';
26
34
  import { isRelUserset } from '../types.js';
27
- /** La clave estable de una tupla de relación (partición + objeto + relación + sujeto). */
28
- function subjectKey(subject) {
29
- if (isRelUserset(subject))
30
- return `${subject.object.type}:${subject.object.id}#${subject.relation}`;
31
- return `${subject.type}:${subject.uuid}`;
32
- }
33
- function scopeKeyOf(scope) {
34
- return scope.type === 'app' ? 'app' : `${scope.type}|${scope.uuid}`;
35
- }
36
- function tupleKey(tuple) {
37
- return `${scopeKeyOf(tuple.partition)}|${tuple.object.type}:${tuple.object.id}#${tuple.relation}@${subjectKey(tuple.subject)}`;
38
- }
35
+ import { assertRelationDeclared, assertSupportedUserset } from './define_relations_config.js';
36
+ import { relationTupleKey } from './tuple_key.js';
37
+ /**
38
+ * La clave con la que se casan origen y destino es `relationTupleKey` (plan
39
+ * 2.5 · lote A, P3-4): la MISMA función pura y exportada que un consumidor
40
+ * usa para indexar sus metadatos, con `kind` desde el primer día (hoy todo
41
+ * lo que un driver enumera es `allow`; el lote D lo trae en `RelationTuple`
42
+ * y el `kind` explícito de aquí desaparece). Este módulo no define clave
43
+ * propia ni copia `scopeKey`
44
+ * (`tests/relation_tuple_key.spec.ts` lo vigila por fuente).
45
+ */
46
+ const tupleKey = relationTupleKey;
39
47
  /**
40
48
  * Enumera TODAS las tuplas de las particiones pedidas, repartidas por clave de
41
49
  * partición. UNA pasada con `enumerateRelationsMany` si el driver lo trae
@@ -51,10 +59,10 @@ async function enumerateAllMany(driver, partitions, role) {
51
59
  }
52
60
  const out = new Map();
53
61
  for (const partition of partitions)
54
- out.set(scopeKeyOf(partition), []);
62
+ out.set(scopeKey(partition), []);
55
63
  const collect = (tuples) => {
56
64
  for (const tuple of tuples) {
57
- const bucket = out.get(scopeKeyOf(tuple.partition));
65
+ const bucket = out.get(scopeKey(tuple.partition));
58
66
  // Una tupla de una partición que no se pidió no es de esta pasada: el
59
67
  // puerto promete «solo las pedidas», y si un driver de terceros trae de
60
68
  // más, no se migra lo ajeno.
@@ -101,12 +109,13 @@ export async function reconcileRelations(options) {
101
109
  // seguro que salte en la partición 3 no deja las dos primeras a medias.
102
110
  const plans = [];
103
111
  for (const partition of partitions) {
104
- const enumerated = enumeratedByKey.get(scopeKeyOf(partition)) ?? [];
105
- const destTuples = destByKeyAll.get(scopeKeyOf(partition)) ?? [];
112
+ const enumerated = enumeratedByKey.get(scopeKey(partition)) ?? [];
113
+ const destTuples = destByKeyAll.get(scopeKey(partition)) ?? [];
106
114
  plans.push(planPartition(partition, enumerated, destTuples, { now, prune, toConfig }));
107
115
  }
108
116
  const report = {
109
117
  dryRun,
118
+ prune,
110
119
  written: 0,
111
120
  updated: 0,
112
121
  deleted: 0,
@@ -114,7 +123,9 @@ export async function reconcileRelations(options) {
114
123
  extra: 0,
115
124
  modelDrift: [],
116
125
  massDelete: false,
117
- skipped: { expired: 0, undeclared: 0 },
126
+ allowMassDelete,
127
+ skipped: { expired: 0, undeclared: 0, invalid: 0, usersetUnsupported: 0 },
128
+ details: [],
118
129
  };
119
130
  for (const plan of plans) {
120
131
  // **El seguro de borrado masivo** (R-17, paridad con `authz:reconcile` de
@@ -126,10 +137,8 @@ export async function reconcileRelations(options) {
126
137
  // recoge no migran, así que no cuentan como respaldo).
127
138
  if (plan.massDelete && !dryRun && !allowMassDelete) {
128
139
  throw new MassReconcileRefusedError(`authz:relations:reconcile --prune borraría ${plan.toDelete.length} tupla(s) de relación del destino` +
129
- `${partitions.length > 1 ? ` (partición ${scopeKeyOf(plan.partition)})` : ''} y el ` +
130
- `ORIGEN no ha aportado NI UNA utilizable (${plan.enumerated} leídas` +
131
- `${toConfig ? ', todas de tipos que el destino no declara' : ''}` +
132
- `${plan.skipped.expired ? `, ${plan.skipped.expired} caducada(s)` : ''}). Eso es la firma de un --from ` +
140
+ `${partitions.length > 1 ? ` (partición ${scopeKey(plan.partition)})` : ''} y el ` +
141
+ `ORIGEN no ha aportado NI UNA utilizable (${plan.enumerated} leídas${describeSkipped(plan.skipped)}). Eso es la firma de un --from ` +
133
142
  `equivocado o de un store vacío, no de un destino que sobra: esta pasada dejaría la partición sin ` +
134
143
  `una sola relación. Comprueba el --from y el store; si de verdad quieres vaciarlo, --allow-mass-delete.` +
135
144
  `${partitions.length > 1 ? ' No se ha escrito nada en ninguna partición.' : ''}`);
@@ -137,6 +146,8 @@ export async function reconcileRelations(options) {
137
146
  report.massDelete ||= plan.massDelete;
138
147
  report.skipped.expired += plan.skipped.expired;
139
148
  report.skipped.undeclared += plan.skipped.undeclared;
149
+ report.skipped.invalid += plan.skipped.invalid;
150
+ report.skipped.usersetUnsupported += plan.skipped.usersetUnsupported;
140
151
  for (const type of plan.modelDrift)
141
152
  if (!report.modelDrift.includes(type))
142
153
  report.modelDrift.push(type);
@@ -164,26 +175,170 @@ export async function reconcileRelations(options) {
164
175
  report.skipped.undeclared += 1;
165
176
  updated -= 1;
166
177
  }
167
- if (prune) {
168
- for (const tuple of plan.toDelete) {
169
- await to.unrelate(tuple.subject, tuple.relation, tuple.object, tuple.partition);
170
- }
178
+ }
179
+ // ⚪ R2 + cierre 1 y cierre 2 del lote B (🟡 N3, una regla, no dos): lo
180
+ // enumerado fuera de la gramática (`invalid-identity`) y el residuo pre-2.5
181
+ // de B3 (`userset-unsupported`) se LISTAN siempre, en los dos lados; con
182
+ // `prune` el del destino lleva `pruned: false` desde el plan — también en
183
+ // `--dry-run`—, porque NADIE lo borra: ni `toDelete` lo contiene ni el driver
184
+ // lo ve (hasta el cierre 2 `invalid-identity` se le pedía al driver y los dos
185
+ // del paquete lo rechazaban por el puerto, R-16). Cuenta en `extra` (abajo)
186
+ // y es deriva en los cuatro modos.
187
+ for (const invalid of plan.invalid) {
188
+ const detail = {
189
+ side: invalid.side,
190
+ reason: 'invalid-identity',
191
+ tuple: invalid.tuple,
192
+ message: invalid.message,
193
+ };
194
+ if (invalid.side === 'destino' && prune)
195
+ detail.pruned = false;
196
+ report.details.push(detail);
197
+ }
198
+ for (const residue of plan.usersetResidue) {
199
+ const detail = {
200
+ side: residue.side,
201
+ reason: 'userset-unsupported',
202
+ tuple: residue.tuple,
203
+ message: residue.message,
204
+ };
205
+ if (residue.side === 'destino' && prune)
206
+ detail.pruned = false;
207
+ report.details.push(detail);
208
+ }
209
+ // Cierre 3 del lote B · 🟠 N9, capa 1: la fila del DESTINO cuya relación o
210
+ // tipo `toConfig` no declara (una relación RETIRADA con filas vivas) se
211
+ // clasifica en el PLAN con la MISMA regla que los otros dos motivos: `extra`
212
+ // + `details`, `pruned: false` bajo `prune` (también en `--dry-run`), nunca
213
+ // en `toDelete` — `unrelate` la rechazaría por F-05 y hasta el cierre 3 ese
214
+ // 422 tumbaba la pasada a mitad, después de escribir.
215
+ for (const residue of plan.undeclaredResidue) {
216
+ const detail = { side: 'destino', reason: 'undeclared', tuple: residue.tuple, message: residue.message };
217
+ if (prune)
218
+ detail.pruned = false;
219
+ report.details.push(detail);
220
+ }
221
+ let deleted = prune ? plan.toDelete.length : 0;
222
+ let refused = 0;
223
+ if (!dryRun && prune) {
224
+ // Todo lo que hay en `toDelete` pasó la gramática Y, con `toConfig`, F-05
225
+ // del destino: un 422 del driver aquí es el driver diciendo otra cosa que
226
+ // el plan — o el plan sin `toConfig`, que no pudo anticipar F-05 (🟠 N9,
227
+ // capa 2). **La poda NUNCA lanza por un 422 de la familia de relaciones**:
228
+ // se clasifica por `code` con la MISMA regla (`extra` + `details`,
229
+ // `pruned: false`, deriva), se sigue con las demás filas y el comando sale
230
+ // ≠ 0 con la línea «sobra (<motivo>) destino:». Un 422 de OTRA familia o
231
+ // cualquier otro error sigue propagándose: eso sí es una contradicción que
232
+ // el reporte no sabe contar (R2-5: el plan clasifica, el driver no absorbe
233
+ // lo que no es suyo).
234
+ for (const tuple of plan.toDelete) {
235
+ const refusal = await unrelateOrClassify(to, tuple);
236
+ if (refusal === null)
237
+ continue;
238
+ report.details.push({ side: 'destino', reason: refusal.reason, tuple: describeTuple(tuple), message: refusal.message, pruned: false });
239
+ refused += 1;
240
+ deleted -= 1;
171
241
  }
172
242
  }
173
243
  report.written += written;
174
244
  report.updated += updated;
175
- report.deleted += prune ? plan.toDelete.length : 0;
245
+ report.deleted += deleted;
176
246
  report.unchanged += plan.unchanged;
177
- report.extra += prune ? 0 : plan.toDelete.length;
247
+ // El residuo del destino (los tres motivos) sobra SIEMPRE, con o sin `prune`:
248
+ // no está en `toDelete`, así que se suma aparte — más lo que el driver
249
+ // rechazó con un 422 de la familia en la pasada real (capa 2 de N9).
250
+ report.extra += (prune ? 0 : plan.toDelete.length) + plan.destResidue + refused;
178
251
  }
179
252
  return report;
180
253
  }
254
+ /**
255
+ * ⚪ N8 (cierre 2 del lote B): el desglose del seguro R-17, cada motivo POR SU
256
+ * NOMBRE y solo si cuenta (> 0). Hasta el cierre decía «todas de tipos que el
257
+ * destino no declara» siempre que había `toConfig`, también cuando el único
258
+ * aporte era residuo B3 — y sin `toConfig` no nombraba nada.
259
+ */
260
+ function describeSkipped(skipped) {
261
+ const parts = [];
262
+ if (skipped.undeclared)
263
+ parts.push(`${skipped.undeclared} de tipo o relación que el destino no declara (skipped.undeclared)`);
264
+ if (skipped.usersetUnsupported)
265
+ parts.push(`${skipped.usersetUnsupported} con sujeto userset no admitido (B3, skipped.usersetUnsupported)`);
266
+ if (skipped.invalid)
267
+ parts.push(`${skipped.invalid} con identidad fuera de la gramática (skipped.invalid)`);
268
+ if (skipped.expired)
269
+ parts.push(`${skipped.expired} caducada(s)`);
270
+ return parts.length ? `: ${parts.join(', ')}` : '';
271
+ }
272
+ /** Una tupla enumerada, legible, para la línea del reporte (sin validar nada: puede estar fuera de la gramática). */
273
+ function describeTuple(tuple) {
274
+ const s = tuple?.subject;
275
+ const subject = isRelUserset(s) ? `${s.object?.type}:${s.object?.id}#${s.relation}` : `${s?.type}:${s?.uuid}`;
276
+ const p = tuple?.partition;
277
+ const partition = p?.type === 'app' ? 'app' : `${p?.type}|${p?.uuid}`;
278
+ return `${partition} ${tuple?.object?.type}:${tuple?.object?.id}#${tuple?.relation}@${subject}`;
279
+ }
280
+ /** `tupleKey` de una tupla ENUMERADA: la clave, o el motivo por el que su identidad no entra en la gramática (⚪ R2). */
281
+ function enumeratedKey(tuple) {
282
+ try {
283
+ return { key: tupleKey({ ...tuple, kind: 'allow' }) };
284
+ }
285
+ catch (error) {
286
+ if (error instanceof InvalidIdentityError)
287
+ return { message: error.message };
288
+ throw error;
289
+ }
290
+ }
291
+ /**
292
+ * **El sujeto de una tupla ENUMERADA, clasificado** (cierre 1 del lote B · 🟠 2;
293
+ * cierre 2 · 🟡 N2): `ok`, `userset-unsupported` (B3: userset ≠ `group#member`,
294
+ * con o sin config — `assertSupportedUserset` no necesita F-05), o `undeclared`
295
+ * (solo con `toConfig`: un `group#member` cuyo tipo/relación el destino no
296
+ * declara — F-05 del par; sin config esa cara la embuda el 422 del driver, como
297
+ * la del objeto). **La FORMA se juzga ANTES que F-05** (N2; decisión 3 del
298
+ * cierre 1 rechazada): un residuo B3 es inadmisible con cualquier config, así
299
+ * que un userset `folder#viewer` o `document#reader` que `toConfig` no declara
300
+ * es residuo con receta, nunca `undeclared` con el consejo falso «decláralo en
301
+ * el destino» (declarado, la pasada siguiente lo reclasificaba como residuo).
302
+ * Mutante «F-05 primero» ⇒ rojo. Nunca lanza por un dato del store
303
+ * (invariante 5).
304
+ */
305
+ function classifySubject(tuple, toConfig) {
306
+ const subject = tuple?.subject;
307
+ if (!isRelUserset(subject))
308
+ return { kind: 'ok' };
309
+ try {
310
+ assertSupportedUserset(subject);
311
+ if (toConfig)
312
+ assertRelationDeclared(toConfig, subject.object, subject.relation);
313
+ return { kind: 'ok' };
314
+ }
315
+ catch (error) {
316
+ if (error instanceof RelationUsersetUnsupportedError)
317
+ return { kind: 'userset-unsupported', message: error.message };
318
+ if (error instanceof RelationTypeUnknownError || error instanceof RelationUnknownError)
319
+ return { kind: 'undeclared' };
320
+ throw error;
321
+ }
322
+ }
181
323
  /** Exactamente uno de `partition` / `partitions` (y `partitions` no vacío): lo demás es 500 antes de leer nada. */
182
324
  function partitionsOf(options) {
183
325
  const { partition, partitions } = options;
184
326
  if (partition !== undefined && partitions !== undefined) {
185
327
  throw new AuthorizationConfigError('reconcileRelations: pasa `partition` O `partitions`, no los dos.');
186
328
  }
329
+ // alpha.10 · 5, gemelo en la API: `{ type: 'app', uuid: 'x' }` reconciliaba la
330
+ // RAÍZ en silencio (la clave de `app` ignora el uuid), igual que la pareja
331
+ // `--partition-type=app --partition-uuid=x` del comando.
332
+ for (const p of partition !== undefined ? [partition] : Array.isArray(partitions) ? partitions : []) {
333
+ if (p?.type === 'app' && p.uuid !== null && p.uuid !== undefined) {
334
+ throw new AuthorizationConfigError(`reconcileRelations: la partición raíz no lleva uuid (llegó { type: 'app', uuid: ${JSON.stringify(p.uuid)} }). ` +
335
+ 'O la raíz ({ type: app, uuid: null }) o el tipo del tenant.');
336
+ }
337
+ // D4 (plan 2.5 · lote A): la pasada recibe partición, así que la misma
338
+ // regla que toda operación del puerto — un uuid sin guiones es 422 antes
339
+ // de leer nada.
340
+ assertPartition(p);
341
+ }
187
342
  if (partition !== undefined)
188
343
  return [partition];
189
344
  if (!Array.isArray(partitions) || partitions.length === 0) {
@@ -193,7 +348,7 @@ function partitionsOf(options) {
193
348
  // Dos referencias con la misma clave son la misma partición: se migra una vez.
194
349
  const seen = new Set();
195
350
  return partitions.filter((p) => {
196
- const key = scopeKeyOf(p);
351
+ const key = scopeKey(p);
197
352
  if (seen.has(key))
198
353
  return false;
199
354
  seen.add(key);
@@ -210,14 +365,40 @@ function planPartition(partition, enumerated, destTuples, context) {
210
365
  // pasada real dan los mismos números— y tampoco respalda nada en el destino
211
366
  // (una que ya estuviera allí es `extra`, y `--prune` la barre). El tipo se
212
367
  // reporta además en `modelDrift` (deriva del modelo fusionado).
213
- const skipped = { expired: 0, undeclared: 0 };
368
+ const skipped = { expired: 0, undeclared: 0, invalid: 0, usersetUnsupported: 0 };
214
369
  const modelDrift = [];
215
370
  const sourceTuples = [];
371
+ const invalid = [];
372
+ const usersetResidue = [];
216
373
  for (const tuple of enumerated) {
217
374
  if (!isActiveExpiry(tuple.expiresAt ?? null, now)) {
218
375
  skipped.expired += 1;
219
376
  continue;
220
377
  }
378
+ // ⚪ R2: una identidad fuera de la gramática en el ORIGEN no es una pregunta
379
+ // del llamante (invariante 5): no se migra —la API del destino no podría
380
+ // escribirla—, se lista y se cuenta. Nunca un 422 por un dato del store.
381
+ const keyed = enumeratedKey(tuple);
382
+ if ('message' in keyed) {
383
+ skipped.invalid += 1;
384
+ invalid.push({ side: 'origen', tuple: describeTuple(tuple), message: keyed.message });
385
+ continue;
386
+ }
387
+ // Cierre 1 del lote B · 🟠 2: el residuo pre-2.5 de B3 en el ORIGEN se
388
+ // clasifica AQUÍ, con o sin `toConfig` — no se migra (ninguna puerta del
389
+ // destino lo admite), se lista con su receta y se cuenta aparte. Hasta el
390
+ // cierre llegaba al driver, que lo rechazaba con 422, y `relateOrSkip` lo
391
+ // tragaba como `undeclared` (consejo falso; `--dry-run` decía `written`).
392
+ const subject = classifySubject(tuple, toConfig);
393
+ if (subject.kind === 'userset-unsupported') {
394
+ skipped.usersetUnsupported += 1;
395
+ usersetResidue.push({ side: 'origen', tuple: describeTuple(tuple), message: subject.message });
396
+ continue;
397
+ }
398
+ if (subject.kind === 'undeclared') {
399
+ skipped.undeclared += 1;
400
+ continue;
401
+ }
221
402
  if (toConfig && !declaredIn(toConfig, tuple.object.type)) {
222
403
  skipped.undeclared += 1;
223
404
  if (!modelDrift.includes(tuple.object.type))
@@ -232,10 +413,54 @@ function planPartition(partition, enumerated, destTuples, context) {
232
413
  }
233
414
  const sourceByKey = new Map();
234
415
  for (const tuple of sourceTuples)
235
- sourceByKey.set(tupleKey(tuple), tuple);
416
+ sourceByKey.set(tupleKey({ ...tuple, kind: 'allow' }), tuple);
417
+ // ⚪ R2 + cierre 2 · N3: una tupla del DESTINO fuera de la gramática es
418
+ // `extra` con motivo (`invalid-identity`): nadie del origen puede respaldarla
419
+ // (la clave no se puede ni componer) y NADIE la borra — ni `toDelete` (los dos
420
+ // drivers del paquete la rechazan por el puerto, R-16; hasta el cierre 2 se les
421
+ // pedía igual) ni un DELETE de plataforma—: se lista con `pruned: false` y es
422
+ // deriva en los cuatro modos, exactamente como el residuo de B3 de abajo.
236
423
  const destByKey = new Map();
237
- for (const tuple of destTuples)
238
- destByKey.set(tupleKey(tuple), tuple);
424
+ const destInvalid = new Set();
425
+ const destResidue = new Set();
426
+ const undeclaredResidue = [];
427
+ for (const tuple of destTuples) {
428
+ const keyed = enumeratedKey(tuple);
429
+ if ('message' in keyed) {
430
+ destInvalid.add(tuple);
431
+ invalid.push({ side: 'destino', tuple: describeTuple(tuple), message: keyed.message });
432
+ continue;
433
+ }
434
+ // Cierre 1 del lote B · 🟠 1: el residuo pre-2.5 de B3 en el DESTINO sobra
435
+ // (nadie del origen puede respaldarlo: el origen lo descarta arriba) pero
436
+ // NO entra en `toDelete`: la pasada no se lo pide al driver ni con `--prune`
437
+ // —`unrelate` lo rechazaría con 422 y hasta el cierre eso ABORTABA la pasada
438
+ // a mitad, con los `toWrite` ya escritos—. Se lista con `pruned: false` y
439
+ // la receta, cuenta en `extra` y es deriva. Solo la forma del userset: la
440
+ // F-05 del par del SUJETO no decide aquí (un userset que pasa la forma es
441
+ // `group#member`, declarado en toda config).
442
+ const subject = classifySubject(tuple, undefined);
443
+ if (subject.kind === 'userset-unsupported') {
444
+ destResidue.add(tuple);
445
+ usersetResidue.push({ side: 'destino', tuple: describeTuple(tuple), message: subject.message });
446
+ continue;
447
+ }
448
+ // Cierre 3 del lote B · 🟠 N9 (capa 1): la fila cuya RELACIÓN o TIPO el
449
+ // destino (`toConfig`) ya no declara — una relación retirada de la config con
450
+ // filas vivas (`#enumerateRows`/`#sweep` filtran por tipo, no por relación) o
451
+ // un driver con la config vieja — es la tercera fila que la API no admite:
452
+ // `unrelate` la rechaza por F-05, así que lleva la MISMA regla que las dos de
453
+ // arriba (nunca en `toDelete`, `pruned: false`, deriva, receta). La regla es
454
+ // por la FILA, no por el driver (N3): hasta el cierre 3 un driver viejo la
455
+ // borraba y el driver nuevo tumbaba la pasada a mitad con un stack crudo.
456
+ const undeclared = toConfig ? classifyDestinationRow(toConfig, tuple) : null;
457
+ if (undeclared !== null) {
458
+ destResidue.add(tuple);
459
+ undeclaredResidue.push({ tuple: describeTuple(tuple), message: undeclared });
460
+ continue;
461
+ }
462
+ destByKey.set(keyed.key, tuple);
463
+ }
239
464
  const toWrite = [];
240
465
  const toUpdate = [];
241
466
  let unchanged = 0;
@@ -249,9 +474,81 @@ function planPartition(partition, enumerated, destTuples, context) {
249
474
  else
250
475
  unchanged += 1;
251
476
  }
252
- const toDelete = destTuples.filter((tuple) => !sourceByKey.has(tupleKey(tuple)));
477
+ const toDelete = destTuples.filter((tuple) => !destResidue.has(tuple) && !destInvalid.has(tuple) && !sourceByKey.has(tupleKey({ ...tuple, kind: 'allow' })));
253
478
  const massDelete = prune && toDelete.length > 0 && sourceTuples.length === 0;
254
- return { partition, enumerated: enumerated.length, toWrite, toUpdate, toDelete, unchanged, skipped, modelDrift, massDelete };
479
+ return {
480
+ partition,
481
+ enumerated: enumerated.length,
482
+ toWrite,
483
+ toUpdate,
484
+ toDelete,
485
+ unchanged,
486
+ skipped,
487
+ modelDrift,
488
+ massDelete,
489
+ invalid,
490
+ usersetResidue,
491
+ undeclaredResidue,
492
+ destResidue: destResidue.size + destInvalid.size,
493
+ };
494
+ }
495
+ /**
496
+ * **F-05 del destino sobre una fila ENUMERADA del destino** (cierre 3 del lote B ·
497
+ * 🟠 N9, capa 1): la MISMA `assertRelationDeclared` que corre en la primera línea
498
+ * de `unrelate` de los dos drivers, aplicada en el plan para que `--dry-run` y la
499
+ * pasada real den los mismos números y la fila nunca llegue a un `unrelate` que
500
+ * la rechazaría. Devuelve el porqué (el mensaje de F-05: tipo o relación) o
501
+ * `null` si el destino la declara. Nunca lanza por un dato del store
502
+ * (invariante 5): cualquier otra excepción se propaga tal cual.
503
+ */
504
+ function classifyDestinationRow(toConfig, tuple) {
505
+ try {
506
+ assertRelationDeclared(toConfig, tuple.object, tuple.relation);
507
+ return null;
508
+ }
509
+ catch (error) {
510
+ if (error instanceof RelationTypeUnknownError || error instanceof RelationUnknownError)
511
+ return error.message;
512
+ throw error;
513
+ }
514
+ }
515
+ /**
516
+ * **Los 422 de la FAMILIA de relaciones, clasificados por `code`** (cierre 3 del
517
+ * lote B · 🟠 N9, capa 2): lo que el bucle de poda absorbe cuando el driver del
518
+ * destino rechaza un `unrelate` que el plan dio por bueno — sin `toConfig` el plan
519
+ * no puede anticipar F-05, y un driver de terceros puede decir cualquiera de los
520
+ * cuatro—. Por `code` y `status`, no por clase: un driver de terceros lanza su
521
+ * propia clase con el mismo código. Fuera de esta tabla NADA se absorbe.
522
+ */
523
+ const RELATION_422_REASONS = Object.freeze({
524
+ [RelationTypeUnknownError.code]: 'undeclared',
525
+ [RelationUnknownError.code]: 'undeclared',
526
+ [RelationUsersetUnsupportedError.code]: 'userset-unsupported',
527
+ [InvalidIdentityError.code]: 'invalid-identity',
528
+ });
529
+ /**
530
+ * Borra la tupla del destino; devuelve `null` si se borró (o ya no estaba) y el
531
+ * motivo + porqué si el DRIVER la rechazó con un 422 de la familia de relaciones
532
+ * (`RELATION_422_REASONS`): la pasada lo clasifica como residuo del destino con
533
+ * `pruned: false` y SIGUE con las demás filas (🟠 N9: nunca un throw a mitad de
534
+ * pasada por una fila que el reporte puede contar). Cualquier otro error —otro
535
+ * 422, un 503, un `Error`— se propaga tal cual: eso sí es el driver
536
+ * contradiciendo al plan por algo que la pasada no sabe contar.
537
+ */
538
+ async function unrelateOrClassify(to, tuple) {
539
+ try {
540
+ await to.unrelate(tuple.subject, tuple.relation, tuple.object, tuple.partition);
541
+ return null;
542
+ }
543
+ catch (error) {
544
+ // Por `status` Y por `code` PROPIO de la tabla (`Object.hasOwn`, repaso del cierre 3 · ⚪ N13): un 422 con un
545
+ // `code` heredado del prototipo (`constructor`, `toString`, `__proto__`) no es de la familia y se propaga.
546
+ const code = String(error?.code);
547
+ const reason = error?.status === 422 && Object.hasOwn(RELATION_422_REASONS, code) ? RELATION_422_REASONS[code] : undefined;
548
+ if (reason === undefined)
549
+ throw error;
550
+ return { reason, message: String(error?.message ?? error) };
551
+ }
255
552
  }
256
553
  /** ¿El tipo de objeto cabe en el modelo fusionado del destino? (`group` es built-in: `hasType` lo incluye.) */
257
554
  function declaredIn(config, objectType) {
@@ -260,7 +557,12 @@ function declaredIn(config, objectType) {
260
557
  /**
261
558
  * Escribe la tupla en el destino; `false` si el DRIVER la rechazó por F-05
262
559
  * (tipo o relación no declarados: 422 `E_AUTHZ_RELATION_TYPE_UNKNOWN` /
263
- * `E_AUTHZ_RELATION_UNKNOWN`). Cualquier otro error se propaga tal cual.
560
+ * `E_AUTHZ_RELATION_UNKNOWN`). Cualquier otro error se propaga tal cual —
561
+ * **también `E_AUTHZ_RELATION_USERSET_UNSUPPORTED`** (cierre 1 del lote B,
562
+ * decisión 4 rechazada): esa clase ya no hereda de F-05 y aquí no se absorbe;
563
+ * el residuo de B3 se clasifica en el PLAN y nunca llega a este `relate`. Un
564
+ * driver que lo lanzara por una tupla que el plan dio por buena está diciendo
565
+ * otra cosa, y eso se propaga (R2-5: el plan clasifica, el driver no absorbe).
264
566
  */
265
567
  async function relateOrSkip(to, tuple) {
266
568
  try {
@@ -270,6 +572,8 @@ async function relateOrSkip(to, tuple) {
270
572
  return true;
271
573
  }
272
574
  catch (error) {
575
+ if (error instanceof RelationUsersetUnsupportedError)
576
+ throw error;
273
577
  if (error instanceof RelationTypeUnknownError || error instanceof RelationUnknownError)
274
578
  return false;
275
579
  throw error;
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../../src/relations/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI1C,0FAA0F;AAC1F,SAAS,UAAU,CAAC,OAAmB;IACrC,IAAI,YAAY,CAAC,OAAO,CAAC;QAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAA;IACnG,OAAO,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAA;AAC1C,CAAC;AAED,SAAS,UAAU,CAAC,KAAe;IACjC,OAAO,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAA;AACrE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAoB;IACpC,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,KAAK,CAAC,QAAQ,IAAI,UAAU,CAC3G,KAAK,CAAC,OAAO,CACd,EAAE,CAAA;AACL,CAAC;AA6GD;;;;;;;GAOG;AACH,KAAK,UAAU,gBAAgB,CAC7B,MAAuB,EACvB,UAAsB,EACtB,IAA0B;IAE1B,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,kBAAkB,EAAE,CAAC;QAC3E,MAAM,IAAI,yBAAyB,CACjC,oBAAoB,EACpB,OAAO,IAAI,mCAAmC,EAC9C,WAAW,EACX,aAAa,IAAI,wEAAwE;YACvF,kBAAkB,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,kCAAkC,GAAG,CACjH,CAAA;IACH,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,EAA2B,CAAA;IAC9C,KAAK,MAAM,SAAS,IAAI,UAAU;QAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAA;IACtE,MAAM,OAAO,GAAG,CAAC,MAAuB,EAAE,EAAE;QAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;YACnD,sEAAsE;YACtE,wEAAwE;YACxE,6BAA6B;YAC7B,IAAI,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChC,CAAC;IACH,CAAC,CAAA;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,sBAAsB,CAAA;IAC1C,MAAM,KAAK,GACT,OAAO,IAAI,KAAK,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QACjD,CAAC,CAAC,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACpF,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,kBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;IAC7H,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,IAAI,KAAyB,CAAA;QAC7B,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,GAAG,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAA;YAChC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACpB,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,CAAA;YAChC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,iBAAiB,KAAK,wBAAwB,CAAC,CAAA;gBAC/G,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;gBACf,IAAI,EAAE,KAAK,GAAG,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,qCAAqC,CAAC,CAAA;YAC1G,CAAC;QACH,CAAC,QAAQ,KAAK,EAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAkC;IACzE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,eAAe,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAA;IAC9F,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,EAAE,CAAA;IAC1C,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IAExC,4EAA4E;IAC5E,MAAM,eAAe,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;IAC1E,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,EAAE,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;IAEtE,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,KAAK,GAAoB,EAAE,CAAA;IACjC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAA;QACnE,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAA;QAChE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAA;IACxF,CAAC;IAED,MAAM,MAAM,GAA6B;QACvC,MAAM;QACN,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,CAAC;QACZ,KAAK,EAAE,CAAC;QACR,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;KACvC,CAAA;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,0EAA0E;QAC1E,+EAA+E;QAC/E,4EAA4E;QAC5E,0EAA0E;QAC1E,6EAA6E;QAC7E,sEAAsE;QACtE,uDAAuD;QACvD,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACnD,MAAM,IAAI,yBAAyB,CACjC,8CAA8C,IAAI,CAAC,QAAQ,CAAC,MAAM,mCAAmC;gBACnG,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ;gBACpF,4CAA4C,IAAI,CAAC,UAAU,SAAS;gBACpE,GAAG,QAAQ,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC,CAAC,EAAE,EAAE;gBACjE,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,EAAE,kCAAkC;gBACxG,mGAAmG;gBACnG,wGAAwG;gBACxG,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAC,EAAE,EAAE,CACnF,CAAA;QACH,CAAC;QACD,MAAM,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,CAAA;QACrC,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAA;QAC9C,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAA;QACpD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzG,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA;QACjC,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAA;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,qEAAqE;YACrE,oEAAoE;YACpE,6EAA6E;YAC7E,4EAA4E;YAC5E,2EAA2E;YAC3E,yEAAyE;YACzE,8DAA8D;YAC9D,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjC,IAAI,MAAM,YAAY,CAAC,EAAE,EAAE,KAAK,CAAC;oBAAE,SAAQ;gBAC3C,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;gBAC9B,OAAO,IAAI,CAAC,CAAA;YACd,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClC,IAAI,MAAM,YAAY,CAAC,EAAE,EAAE,KAAK,CAAC;oBAAE,SAAQ;gBAC3C,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;gBAC9B,OAAO,IAAI,CAAC,CAAA;YACd,CAAC;YACD,IAAI,KAAK,EAAE,CAAC;gBACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAClC,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;gBACjF,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,CAAC,OAAO,IAAI,OAAO,CAAA;QACzB,MAAM,CAAC,OAAO,IAAI,OAAO,CAAA;QACzB,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QAClD,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAA;QAClC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAA;IAClD,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,mHAAmH;AACnH,SAAS,YAAY,CAAC,OAAkC;IACtD,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAA;IACzC,IAAI,SAAS,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QACxD,MAAM,IAAI,wBAAwB,CAAC,kEAAkE,CAAC,CAAA;IACxG,CAAC;IACD,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,wBAAwB,CAChC,0HAA0H;YACxH,8CAA8C,CACjD,CAAA;IACH,CAAC;IACD,+EAA+E;IAC/E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;QACzB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAA;QAC/B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACb,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC;AAeD,SAAS,aAAa,CACpB,SAAmB,EACnB,UAA2B,EAC3B,UAA2B,EAC3B,OAAkE;IAElE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAA;IACxC,6EAA6E;IAC7E,0EAA0E;IAC1E,6BAA6B;IAC7B,qEAAqE;IACrE,8EAA8E;IAC9E,4EAA4E;IAC5E,2EAA2E;IAC3E,gEAAgE;IAChE,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAA;IAC7C,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,MAAM,YAAY,GAAoB,EAAE,CAAA;IACxC,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YAClD,OAAO,CAAC,OAAO,IAAI,CAAC,CAAA;YACpB,SAAQ;QACV,CAAC;QACD,IAAI,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;YACvB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAC/E,SAAQ;QACV,CAAC;QACD,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxE,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;YACvB,SAAQ;QACV,CAAC;QACD,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1B,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyB,CAAA;IACpD,KAAK,MAAM,KAAK,IAAI,YAAY;QAAE,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;IACzE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAA;IAClD,KAAK,MAAM,KAAK,IAAI,UAAU;QAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;IAErE,MAAM,OAAO,GAAoB,EAAE,CAAA;IACnC,MAAM,QAAQ,GAAoB,EAAE,CAAA;IACpC,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjC,uEAAuE;aAClE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;;YAC1F,SAAS,IAAI,CAAC,CAAA;IACrB,CAAC;IACD,MAAM,QAAQ,GAAoB,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACjG,MAAM,UAAU,GAAG,KAAK,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,CAAA;IAC5E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAA;AAC9H,CAAC;AAED,+GAA+G;AAC/G,SAAS,UAAU,CAAC,MAAuB,EAAE,UAAkB;IAC7D,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;AACnC,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,YAAY,CAAC,EAAmB,EAAE,KAAoB;IACnE,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE;YAC5E,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;SACnC,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,wBAAwB,IAAI,KAAK,YAAY,oBAAoB;YAAE,OAAO,KAAK,CAAA;QACpG,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../../src/relations/reconcile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { RelObject, RelSubject, ScopeRef } from '../types.js';
2
+ export type RelationTupleKind = 'allow' | 'deny';
3
+ /**
4
+ * Lo que identifica una tupla: la forma de `RelationTuple` más el `kind`,
5
+ * **obligatorio y sin default** (⚪ A9 del auditor del lote A): `allow` por
6
+ * omisión era el modo de fallo peligroso —un deny enumerado por un driver que
7
+ * no pusiera `kind` casaría con el allow en `reconcileRelations`—. Quien
8
+ * casa tuplas dice de qué clase son.
9
+ */
10
+ export interface RelationTupleIdentity {
11
+ partition: ScopeRef;
12
+ object: RelObject;
13
+ relation: string;
14
+ subject: RelSubject;
15
+ kind: RelationTupleKind;
16
+ }
17
+ /**
18
+ * La clave de un SUJETO: holder `<type>:<uuid>`, userset `<type>:<id>#<relation>`.
19
+ * Valida sus componentes con la gramática de identidad (⚪ A9): sin ella
20
+ * `{ relation: 'b@user:c#d' }` y un userset legítimo daban la MISMA clave y
21
+ * el «parseo unívoco» del docblock era falso.
22
+ */
23
+ export declare function relationSubjectKey(subject: RelSubject): string;
24
+ export declare function relationTupleKey(tuple: RelationTupleIdentity): string;
25
+ //# sourceMappingURL=tuple_key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tuple_key.d.ts","sourceRoot":"","sources":["../../../src/relations/tuple_key.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAElE,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,CAAA;AAEhD;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,QAAQ,CAAA;IACnB,MAAM,EAAE,SAAS,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,iBAAiB,CAAA;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAS9D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAcrE"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * **`relationTupleKey` — la clave PURA y estable de una tupla de relación**
3
+ * (plan 2.5 · lote A, P3 del 7.º informe de COGNITIV; `panel-tenencia-juez.md`
4
+ * §P3: «sin `meta` en el paquete; clave pura sí»).
5
+ *
6
+ * Determinista e inyectiva sobre los cinco componentes que identifican una
7
+ * tupla —`kind`, partición, objeto (tipo + id), relación y sujeto (holder o
8
+ * userset)— y SOLO sobre ellos: la caducidad no entra (renovarla no cambia la
9
+ * identidad; en `database` sí cambia el uuid de fila, que por eso tampoco
10
+ * sirve de clave), y el `uuid` de fila o el id del store tampoco. Es la clave
11
+ * que `reconcileRelations` usa para casar origen y destino, y la que un
12
+ * consumidor puede usar para indexar sus propios metadatos sobre una tupla
13
+ * sin que el paquete los guarde.
14
+ *
15
+ * **`kind` desde el primer día, con literal de oro**: el lote D trae el deny
16
+ * como tuplas `kind: 'deny'`. Para que un deny y un allow sobre la misma
17
+ * terna nunca colapsen en una clave —y para que la clave de un allow que ya
18
+ * está en un índice del consumidor NO cambie cuando llegue el deny—, el
19
+ * `kind` va en la clave desde ahora (OBLIGATORIO, sin default: ⚪ A9) y
20
+ * `tests/relation_tuple_key.spec.ts` fija el literal exacto de un allow.
21
+ *
22
+ * Forma: `<kind>|<scopeKey(partition)>|<object.type>:<object.id>#<relation>@<subject>`,
23
+ * con `<subject>` = `<type>:<uuid>` (holder) o `<type>:<id>#<relation>`
24
+ * (userset). Ningún componente admite `|`, `#`, `:` ni `@` —la gramática de
25
+ * identidad se APLICA aquí a cada componente (⚪ A9), no se presupone—, así
26
+ * que el parseo es unívoco.
27
+ *
28
+ * Pureza (regla 2): solo el puerto y la gramática de identidad.
29
+ */
30
+ import { InvalidIdentityError } from '../errors.js';
31
+ import { assertRelationId, assertSubject, scopeKey } from '../identity.js';
32
+ import { isRelUserset } from '../types.js';
33
+ /**
34
+ * La clave de un SUJETO: holder `<type>:<uuid>`, userset `<type>:<id>#<relation>`.
35
+ * Valida sus componentes con la gramática de identidad (⚪ A9): sin ella
36
+ * `{ relation: 'b@user:c#d' }` y un userset legítimo daban la MISMA clave y
37
+ * el «parseo unívoco» del docblock era falso.
38
+ */
39
+ export function relationSubjectKey(subject) {
40
+ if (isRelUserset(subject)) {
41
+ assertRelationId('el tipo del objeto del userset', subject.object?.type);
42
+ assertRelationId(`el id del objeto '${subject.object?.type}' del userset`, subject.object?.id);
43
+ assertRelationId('la relación del userset', subject.relation);
44
+ return `${subject.object.type}:${subject.object.id}#${subject.relation}`;
45
+ }
46
+ assertSubject(subject);
47
+ return `${subject.type}:${subject.uuid}`;
48
+ }
49
+ export function relationTupleKey(tuple) {
50
+ const kind = tuple?.kind;
51
+ if (kind !== 'allow' && kind !== 'deny') {
52
+ throw new InvalidIdentityError(`relationTupleKey: kind inválido ${kind === undefined ? 'ausente' : `'${String(kind)}'`} ` +
53
+ `(se exige 'allow' o 'deny', sin default: un deny sin kind casaría con el allow)`);
54
+ }
55
+ assertRelationId('el tipo del objeto', tuple.object?.type);
56
+ assertRelationId(`el id del objeto '${tuple.object?.type}'`, tuple.object?.id);
57
+ assertRelationId('la relación', tuple.relation);
58
+ return `${kind}|${scopeKey(tuple.partition)}|${tuple.object.type}:${tuple.object.id}#${tuple.relation}@${relationSubjectKey(tuple.subject)}`;
59
+ }
60
+ //# sourceMappingURL=tuple_key.js.map