@jantstack/adonis-authz 2.0.0-alpha.1 → 2.4.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +462 -35
- package/build/commands/authz_catalog_diff.js +1 -1
- package/build/commands/authz_catalog_diff.js.map +1 -1
- package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
- package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
- package/build/commands/authz_catalog_prune_orphans.js +136 -0
- package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
- package/build/commands/authz_catalog_sync.d.ts +17 -0
- package/build/commands/authz_catalog_sync.d.ts.map +1 -1
- package/build/commands/authz_catalog_sync.js +27 -4
- package/build/commands/authz_catalog_sync.js.map +1 -1
- package/build/commands/authz_freeze.d.ts +44 -0
- package/build/commands/authz_freeze.d.ts.map +1 -0
- package/build/commands/authz_freeze.js +95 -0
- package/build/commands/authz_freeze.js.map +1 -0
- package/build/commands/authz_reconcile.d.ts +102 -0
- package/build/commands/authz_reconcile.d.ts.map +1 -0
- package/build/commands/authz_reconcile.js +294 -0
- package/build/commands/authz_reconcile.js.map +1 -0
- package/build/commands/authz_relations_reconcile.d.ts +73 -0
- package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
- package/build/commands/authz_relations_reconcile.js +225 -0
- package/build/commands/authz_relations_reconcile.js.map +1 -0
- package/build/commands/authz_scopes_relay.d.ts +47 -0
- package/build/commands/authz_scopes_relay.d.ts.map +1 -0
- package/build/commands/authz_scopes_relay.js +141 -0
- package/build/commands/authz_scopes_relay.js.map +1 -0
- package/build/commands/authz_unfreeze.d.ts +37 -0
- package/build/commands/authz_unfreeze.d.ts.map +1 -0
- package/build/commands/authz_unfreeze.js +92 -0
- package/build/commands/authz_unfreeze.js.map +1 -0
- package/build/commands/main.d.ts +6 -1
- package/build/commands/main.d.ts.map +1 -1
- package/build/commands/main.js +6 -1
- package/build/commands/main.js.map +1 -1
- package/build/commands/openfga_provision.d.ts +46 -4
- package/build/commands/openfga_provision.d.ts.map +1 -1
- package/build/commands/openfga_provision.js +90 -7
- package/build/commands/openfga_provision.js.map +1 -1
- package/build/configure.d.ts +11 -0
- package/build/configure.d.ts.map +1 -1
- package/build/configure.js +37 -1
- package/build/configure.js.map +1 -1
- package/build/index.d.ts +39 -10
- package/build/index.d.ts.map +1 -1
- package/build/index.js +35 -6
- package/build/index.js.map +1 -1
- package/build/providers/authz_provider.d.ts +26 -2
- package/build/providers/authz_provider.d.ts.map +1 -1
- package/build/providers/authz_provider.js +48 -2
- package/build/providers/authz_provider.js.map +1 -1
- package/build/services/relations.d.ts +14 -0
- package/build/services/relations.d.ts.map +1 -0
- package/build/services/relations.js +17 -0
- package/build/services/relations.js.map +1 -0
- package/build/src/{catalog.d.ts → catalog/catalog.d.ts} +41 -2
- package/build/src/catalog/catalog.d.ts.map +1 -0
- package/build/src/{catalog.js → catalog/catalog.js} +120 -14
- package/build/src/catalog/catalog.js.map +1 -0
- package/build/src/{catalog_cache.d.ts → catalog/catalog_cache.d.ts} +46 -22
- package/build/src/catalog/catalog_cache.d.ts.map +1 -0
- package/build/src/{catalog_cache.js → catalog/catalog_cache.js} +53 -43
- package/build/src/catalog/catalog_cache.js.map +1 -0
- package/build/src/define_config.d.ts +101 -3
- package/build/src/define_config.d.ts.map +1 -1
- package/build/src/define_config.js.map +1 -1
- package/build/src/drivers/database_driver.d.ts +86 -4
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +425 -11
- package/build/src/drivers/database_driver.js.map +1 -1
- package/build/src/drivers/database_relations_driver.d.ts +75 -0
- package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
- package/build/src/drivers/database_relations_driver.js +450 -0
- package/build/src/drivers/database_relations_driver.js.map +1 -0
- package/build/src/drivers/openfga_driver.d.ts +713 -119
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +2048 -476
- package/build/src/drivers/openfga_driver.js.map +1 -1
- package/build/src/drivers/openfga_facts.d.ts +369 -0
- package/build/src/drivers/openfga_facts.d.ts.map +1 -0
- package/build/src/drivers/openfga_facts.js +813 -0
- package/build/src/drivers/openfga_facts.js.map +1 -0
- package/build/src/drivers/openfga_relations_driver.d.ts +120 -0
- package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
- package/build/src/drivers/openfga_relations_driver.js +466 -0
- package/build/src/drivers/openfga_relations_driver.js.map +1 -0
- package/build/src/errors.d.ts +258 -5
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +238 -7
- package/build/src/errors.js.map +1 -1
- package/build/src/freeze.d.ts +120 -0
- package/build/src/freeze.d.ts.map +1 -0
- package/build/src/freeze.js +172 -0
- package/build/src/freeze.js.map +1 -0
- package/build/src/http/app_access_middleware.d.ts.map +1 -0
- package/build/src/http/app_access_middleware.js.map +1 -0
- package/build/src/http/resource_access_middleware.d.ts +105 -0
- package/build/src/http/resource_access_middleware.d.ts.map +1 -0
- package/build/src/http/resource_access_middleware.js +81 -0
- package/build/src/http/resource_access_middleware.js.map +1 -0
- package/build/src/identity.d.ts +74 -1
- package/build/src/identity.d.ts.map +1 -1
- package/build/src/identity.js +100 -2
- package/build/src/identity.js.map +1 -1
- package/build/src/manager.d.ts +315 -4
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +1187 -181
- package/build/src/manager.js.map +1 -1
- package/build/src/models/authz_assignment.d.ts +6 -6
- package/build/src/models/authz_assignment.d.ts.map +1 -1
- package/build/src/models/authz_deny.d.ts +6 -6
- package/build/src/models/authz_deny.d.ts.map +1 -1
- package/build/src/models/authz_permission.d.ts +6 -6
- package/build/src/models/authz_permission.d.ts.map +1 -1
- package/build/src/models/authz_role.d.ts +6 -6
- package/build/src/models/authz_role.d.ts.map +1 -1
- package/build/src/models/authz_role_permission.d.ts +6 -6
- package/build/src/models/authz_role_permission.d.ts.map +1 -1
- package/build/src/openfga.d.ts +18 -2
- package/build/src/openfga.d.ts.map +1 -1
- package/build/src/openfga.js +15 -1
- package/build/src/openfga.js.map +1 -1
- package/build/src/reconcile.d.ts +37 -0
- package/build/src/reconcile.d.ts.map +1 -0
- package/build/src/reconcile.js +69 -0
- package/build/src/reconcile.js.map +1 -0
- package/build/src/relation_partition_trigger.d.ts +8 -0
- package/build/src/relation_partition_trigger.d.ts.map +1 -0
- package/build/src/relation_partition_trigger.js +85 -0
- package/build/src/relation_partition_trigger.js.map +1 -0
- package/build/src/relations/define_relations_config.d.ts +58 -0
- package/build/src/relations/define_relations_config.d.ts.map +1 -0
- package/build/src/relations/define_relations_config.js +144 -0
- package/build/src/relations/define_relations_config.js.map +1 -0
- package/build/src/relations/manager.d.ts +38 -0
- package/build/src/relations/manager.d.ts.map +1 -0
- package/build/src/relations/manager.js +156 -0
- package/build/src/relations/manager.js.map +1 -0
- package/build/src/relations/reconcile.d.ts +62 -0
- package/build/src/relations/reconcile.d.ts.map +1 -0
- package/build/src/relations/reconcile.js +138 -0
- package/build/src/relations/reconcile.js.map +1 -0
- package/build/src/relations_config_store.d.ts +22 -0
- package/build/src/relations_config_store.d.ts.map +1 -0
- package/build/src/relations_config_store.js +74 -0
- package/build/src/relations_config_store.js.map +1 -0
- package/build/src/scope_outbox.d.ts +69 -0
- package/build/src/scope_outbox.d.ts.map +1 -0
- package/build/src/scope_outbox.js +291 -0
- package/build/src/scope_outbox.js.map +1 -0
- package/build/src/{drivers → shared}/backend_guard.d.ts +14 -0
- package/build/src/shared/backend_guard.d.ts.map +1 -0
- package/build/src/{drivers → shared}/backend_guard.js +26 -1
- package/build/src/shared/backend_guard.js.map +1 -0
- package/build/src/shared/sql_expiry.d.ts.map +1 -0
- package/build/src/shared/sql_expiry.js.map +1 -0
- package/build/src/sql_descendants.d.ts +47 -1
- package/build/src/sql_descendants.d.ts.map +1 -1
- package/build/src/sql_descendants.js +75 -1
- package/build/src/sql_descendants.js.map +1 -1
- package/build/src/testing/contract.d.ts +74 -0
- package/build/src/testing/contract.d.ts.map +1 -1
- package/build/src/testing/contract.js +672 -169
- package/build/src/testing/contract.js.map +1 -1
- package/build/src/testing/main.d.ts +6 -0
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +3 -0
- package/build/src/testing/main.js.map +1 -1
- package/build/src/testing/migration_contract.d.ts +284 -0
- package/build/src/testing/migration_contract.d.ts.map +1 -0
- package/build/src/testing/migration_contract.js +586 -0
- package/build/src/testing/migration_contract.js.map +1 -0
- package/build/src/testing/relations_contract.d.ts +51 -0
- package/build/src/testing/relations_contract.d.ts.map +1 -0
- package/build/src/testing/relations_contract.js +654 -0
- package/build/src/testing/relations_contract.js.map +1 -0
- package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
- package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
- package/build/src/testing/relations_reconcile_contract.js +172 -0
- package/build/src/testing/relations_reconcile_contract.js.map +1 -0
- package/build/src/traits/authz_scopes.js +1 -1
- package/build/src/traits/authz_scopes.js.map +1 -1
- package/build/src/traits/has_uuid.d.ts +7 -7
- package/build/src/traits/has_uuid.d.ts.map +1 -1
- package/build/src/types.d.ts +865 -82
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js +10 -0
- package/build/src/types.js.map +1 -1
- package/build/stubs/config/authorization.stub +104 -4
- package/build/stubs/migration.stub +126 -0
- package/build/stubs/scopes_outbox_migration.stub +57 -0
- package/package.json +4 -2
- package/build/commands/openfga_import.d.ts +0 -34
- package/build/commands/openfga_import.d.ts.map +0 -1
- package/build/commands/openfga_import.js +0 -97
- package/build/commands/openfga_import.js.map +0 -1
- package/build/src/catalog.d.ts.map +0 -1
- package/build/src/catalog.js.map +0 -1
- package/build/src/catalog_cache.d.ts.map +0 -1
- package/build/src/catalog_cache.js.map +0 -1
- package/build/src/drivers/backend_guard.d.ts.map +0 -1
- package/build/src/drivers/backend_guard.js.map +0 -1
- package/build/src/drivers/sql_expiry.d.ts.map +0 -1
- package/build/src/drivers/sql_expiry.js.map +0 -1
- package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
- package/build/src/middleware/app_access_middleware.js.map +0 -1
- /package/build/src/{middleware → http}/app_access_middleware.d.ts +0 -0
- /package/build/src/{middleware → http}/app_access_middleware.js +0 -0
- /package/build/src/{drivers → shared}/sql_expiry.d.ts +0 -0
- /package/build/src/{drivers → shared}/sql_expiry.js +0 -0
|
@@ -9,5 +9,11 @@
|
|
|
9
9
|
export { runAuthorizationDriverContract } from './contract.js';
|
|
10
10
|
export type { DriverContractHarness, DriverCapabilities, ContractLevel } from './contract.js';
|
|
11
11
|
export { memoryScopeTree, resolveChainFrom, descendantsFrom } from './scope_tree.js';
|
|
12
|
+
export { runMigrationContract, registerMigrationContract, runMigrationDirection, makeMigrationSeed, migrationQuestions, plantMigrationFacts, plantMigrationTree, MIGRATION_CATALOG, MIGRATION_PERMISSIONS, MIGRATION_ROLES, MIGRATION_QUESTION_COUNT, } from './migration_contract.js';
|
|
13
|
+
export type { MigrationContractHarness, MigrationDirection, MigrationQuestion, MigrationSeed, MigrationVerdict, ExpectedLoss, } from './migration_contract.js';
|
|
12
14
|
export type { ContractScopeTree } from './scope_tree.js';
|
|
15
|
+
export { runRelationsDriverContract, registerRelationsDriverContract, makeRelationsDriver, contractRelationsConfig, RELATIONS_HOLDER_TYPES, } from './relations_contract.js';
|
|
16
|
+
export type { RelationsDriverContractHarness, MakeRelationsDriverOptions, } from './relations_contract.js';
|
|
17
|
+
export { runRelationsReconcileContract, registerRelationsReconcileContract, } from './relations_reconcile_contract.js';
|
|
18
|
+
export type { RelationsReconcileHarness } from './relations_reconcile_contract.js';
|
|
13
19
|
//# sourceMappingURL=main.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/testing/main.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAA;AAC9D,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACpF,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/testing/main.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAA;AAC9D,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACpF,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,wBAAwB,GACzB,MAAM,yBAAyB,CAAA;AAChC,YAAY,EACV,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,YAAY,GACb,MAAM,yBAAyB,CAAA;AAChC,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,yBAAyB,CAAA;AAChC,YAAY,EACV,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,6BAA6B,EAC7B,kCAAkC,GACnC,MAAM,mCAAmC,CAAA;AAC1C,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA"}
|
|
@@ -8,4 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export { runAuthorizationDriverContract } from './contract.js';
|
|
10
10
|
export { memoryScopeTree, resolveChainFrom, descendantsFrom } from './scope_tree.js';
|
|
11
|
+
export { runMigrationContract, registerMigrationContract, runMigrationDirection, makeMigrationSeed, migrationQuestions, plantMigrationFacts, plantMigrationTree, MIGRATION_CATALOG, MIGRATION_PERMISSIONS, MIGRATION_ROLES, MIGRATION_QUESTION_COUNT, } from './migration_contract.js';
|
|
12
|
+
export { runRelationsDriverContract, registerRelationsDriverContract, makeRelationsDriver, contractRelationsConfig, RELATIONS_HOLDER_TYPES, } from './relations_contract.js';
|
|
13
|
+
export { runRelationsReconcileContract, registerRelationsReconcileContract, } from './relations_reconcile_contract.js';
|
|
11
14
|
//# sourceMappingURL=main.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/testing/main.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAA;AAE9D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/testing/main.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAA;AAE9D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACpF,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,wBAAwB,GACzB,MAAM,yBAAyB,CAAA;AAUhC,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,yBAAyB,CAAA;AAKhC,OAAO,EACL,6BAA6B,EAC7B,kCAAkC,GACnC,MAAM,mCAAmC,CAAA"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **El contrato de MIGRACIÓN** (3b-3b · B3) — la pieza que convierte «migra»
|
|
3
|
+
* en «migra sin perder nada que no esté declarado».
|
|
4
|
+
*
|
|
5
|
+
* import { runMigrationContract } from '@jantstack/adonis-authz/testing'
|
|
6
|
+
*
|
|
7
|
+
* Se publica junto al resto de la suite de contrato porque un driver de
|
|
8
|
+
* TERCEROS tiene que poder correrlo: el paquete promete migración idempotente
|
|
9
|
+
* y bidireccional entre drivers, y esa promesa no la puede sostener un test
|
|
10
|
+
* privado del paquete.
|
|
11
|
+
*
|
|
12
|
+
* Cómo funciona, y por qué así:
|
|
13
|
+
*
|
|
14
|
+
* 1. **Siembra FIJA** — 7 nodos, 6 holders, 4 roles, 14 grants, 5
|
|
15
|
+
* caducidades y 6 denies, escritos siempre con la API del driver. Fija a
|
|
16
|
+
* propósito: un fixture que cambia con cada corrida no permite comparar
|
|
17
|
+
* dos versiones del paquete, y el juez del panel 2 pedía «un set fijo de
|
|
18
|
+
* preguntas».
|
|
19
|
+
* 2. **448 preguntas idénticas** en origen y destino: 168 `authorize`
|
|
20
|
+
* (6 holders × 7 scopes × 4 permisos), 168 `hasRole` (× 4 roles), 42
|
|
21
|
+
* `listRoles`, 24 `listScopes`, 28 `listSubjects` y 18 `listRoleScopes`.
|
|
22
|
+
* Se preguntan ANTES de migrar sobre el origen y DESPUÉS sobre el
|
|
23
|
+
* destino, y las respuestas tienen que coincidir.
|
|
24
|
+
* 3. **`expectedLosses`** — la migración **no es sin pérdida** (panel 2,
|
|
25
|
+
* requisito 3 del dueño: *«posible con pérdidas declaradas y con
|
|
26
|
+
* ventana»*), así que las pérdidas se declaran DE ANTEMANO y el contrato
|
|
27
|
+
* las cruza en las dos direcciones:
|
|
28
|
+
* - una pérdida declarada tiene que aparecer **contada en
|
|
29
|
+
* `report.skipped`**; si no aparece, el contrato FALLA (una pérdida
|
|
30
|
+
* que nunca ocurre es una línea falsa en el README);
|
|
31
|
+
* - una respuesta que cambia y que NINGUNA pérdida declarada explica
|
|
32
|
+
* hace FALLAR el contrato. Ese es todo el punto: **nunca se ignora
|
|
33
|
+
* ninguna**.
|
|
34
|
+
* 4. **El CENSO de la siembra** (lote 3b-4 · C1) — y esto es lo que hace
|
|
35
|
+
* que el punto 3 sea una garantía y no un formulario. Las dos caras de
|
|
36
|
+
* `expectedLosses` cruzan `Object.keys(report.skipped)`, o sea **lo que
|
|
37
|
+
* el driver se auto-declara**: cierran las omisiones DESCUIDADAS, no las
|
|
38
|
+
* silenciosas. Un driver que tira un hecho sin contarlo no puebla
|
|
39
|
+
* `skipped` y, si esa pérdida no mueve ninguna de las 448, pasaba.
|
|
40
|
+
* Medido, y no es teórico: los denies solo se observan por `authorize`,
|
|
41
|
+
* que no distingue un deny en su sitio de uno reubicado a otro scope de
|
|
42
|
+
* la misma cadena.
|
|
43
|
+
* El censo no le pregunta al driver qué se dejó: mira el destino **hecho
|
|
44
|
+
* a hecho** (los 20 de la siembra: 14 asignaciones + 6 denies) por el
|
|
45
|
+
* camino DIRECTO del puerto —`listRoles`/`listDenies`, invariante 7— y
|
|
46
|
+
* una ausencia sin motivo declarado **y contado** hace FALLAR el
|
|
47
|
+
* contrato. `listDenies` es opcional en el puerto: un driver que no lo
|
|
48
|
+
* traiga deja sus denies observados solo por `authorize`, y el veredicto
|
|
49
|
+
* lo dice en `censusLimits` en vez de callárselo.
|
|
50
|
+
* 5. **El CRUCE DE CADUCIDADES** — ninguna de las 448 devuelve un
|
|
51
|
+
* `expiresAt` y el contrato no adelanta ningún reloj, así que perder la
|
|
52
|
+
* caducidad de un grant VIVO (convertirlo en permanente: fail-OPEN) era
|
|
53
|
+
* invisible. Se cruza por el único camino de solo-lectura-efectiva que
|
|
54
|
+
* hay en el puerto: `grant` con `expiresAt` OMITIDO devuelve
|
|
55
|
+
* `previousExpiresAt` (invariante 10).
|
|
56
|
+
* 6. **Tres combinaciones**: ida, vuelta e ida-y-vuelta (con `--prune`, que
|
|
57
|
+
* es la que demuestra que el viaje redondo no inventa ni pierde).
|
|
58
|
+
*
|
|
59
|
+
* **El límite de `a→b→a`, dicho en voz alta** (tester Fase 3b · M3): las 448
|
|
60
|
+
* de la vuelta se le preguntan al ORIGEN, y **nadie lo vacía** entre los dos
|
|
61
|
+
* tramos. Así que esa combinación observa lo que el tramo de vuelta DESTRUYE
|
|
62
|
+
* (un `--prune` que se lleva de más) y **no** lo que deja de escribir: con el
|
|
63
|
+
* origen ya lleno, «todo `unchanged`» es la respuesta correcta y un tramo
|
|
64
|
+
* omisivo es indistinguible de uno bueno. Quien migra de verdad (vacía el
|
|
65
|
+
* origen y lo reconstruye) está cubierto por las combinaciones `a→b` y `b→a`,
|
|
66
|
+
* que sí preguntan al destino recién llenado. Cerrar el hueco pide un gancho
|
|
67
|
+
* nuevo en el harness («vacía los hechos de este extremo»), que es una
|
|
68
|
+
* decisión del dueño y no se toma aquí.
|
|
69
|
+
*
|
|
70
|
+
* El motor está separado del registro de casos (`runMigrationDirection` /
|
|
71
|
+
* `runMigrationContract`) para que el propio paquete pueda comprobar que el
|
|
72
|
+
* contrato **sabe fallar**: un contrato que no falla no es una garantía.
|
|
73
|
+
*/
|
|
74
|
+
import type { AuthorizationDriver, CatalogSpec, ReconcileReport, ScopeRef, SubjectRef } from '../types.js';
|
|
75
|
+
import type { ContractScopeTree } from './scope_tree.js';
|
|
76
|
+
import type { ContractTestApi } from './contract.js';
|
|
77
|
+
/** Las tres combinaciones que el plan exige. */
|
|
78
|
+
export type MigrationDirection = 'a→b' | 'b→a' | 'a→b→a';
|
|
79
|
+
/** Una pregunta del set fijo, ya identificada por su texto. */
|
|
80
|
+
export interface MigrationQuestion {
|
|
81
|
+
id: string;
|
|
82
|
+
kind: 'authorize' | 'hasRole' | 'listRoles' | 'listScopes' | 'listSubjects' | 'listRoleScopes';
|
|
83
|
+
ask(driver: AuthorizationDriver): Promise<string>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Una pérdida DECLARADA de la migración. Declararla es un compromiso en las
|
|
87
|
+
* dos direcciones: tiene que ocurrir (salir contada en `skipped`) y solo
|
|
88
|
+
* puede explicar las respuestas que diga `changesAnswer`.
|
|
89
|
+
*/
|
|
90
|
+
export interface ExpectedLoss {
|
|
91
|
+
/** El motivo, tal y como sale en `report.skipped` (`expired`, `unknown-scope`, `folded-scope`…). */
|
|
92
|
+
reason: string;
|
|
93
|
+
/** Por qué se pierde y **dónde se mide**. Va al informe y al README; no es decorativo. */
|
|
94
|
+
why: string;
|
|
95
|
+
/** En qué combinaciones se espera. Default: las tres. */
|
|
96
|
+
directions?: MigrationDirection[];
|
|
97
|
+
/**
|
|
98
|
+
* Qué preguntas puede cambiar de respuesta. **Default: ninguna** — lo
|
|
99
|
+
* normal es que una pérdida no cambie ninguna (una asignación ya caducada
|
|
100
|
+
* no concedía nada), y decir «cambia cualquiera» sería una declaración sin
|
|
101
|
+
* contenido: taparía cualquier bug.
|
|
102
|
+
*/
|
|
103
|
+
changesAnswer?(question: MigrationQuestion): boolean;
|
|
104
|
+
}
|
|
105
|
+
export interface MigrationContractHarness {
|
|
106
|
+
name: string;
|
|
107
|
+
/** Los dos extremos, por su clave en `drivers` del manager que devuelve `setup`. */
|
|
108
|
+
a: string;
|
|
109
|
+
b: string;
|
|
110
|
+
/** El árbol del CONSUMIDOR. Es compartido y **no se migra**. Default: `memoryScopeTree()`. */
|
|
111
|
+
makeTree?(): Promise<ContractScopeTree>;
|
|
112
|
+
/** Materializa el catálogo del contrato (siempre local, en `authz_*`). */
|
|
113
|
+
seedCatalog(catalog: CatalogSpec): Promise<unknown>;
|
|
114
|
+
/**
|
|
115
|
+
* Construye los dos drivers sobre ese árbol y devuelve el manager que los
|
|
116
|
+
* conoce por `a`/`b` (es quien congela, resuelve el origen y llama a
|
|
117
|
+
* `reconcile`). `drivers` son las MISMAS instancias, para preguntarles.
|
|
118
|
+
*/
|
|
119
|
+
setup(tree: ContractScopeTree): Promise<{
|
|
120
|
+
reconcile(options: {
|
|
121
|
+
to: string;
|
|
122
|
+
from?: string;
|
|
123
|
+
prune?: boolean;
|
|
124
|
+
}): Promise<ReconcileReport>;
|
|
125
|
+
drivers: Record<string, AuthorizationDriver>;
|
|
126
|
+
}>;
|
|
127
|
+
/** Borra hechos y catálogo entre combinaciones. */
|
|
128
|
+
cleanup(): Promise<void>;
|
|
129
|
+
/** Las pérdidas, declaradas de antemano. Una lista vacía es un compromiso fuerte. */
|
|
130
|
+
expectedLosses: ExpectedLoss[];
|
|
131
|
+
}
|
|
132
|
+
/** Los 4 permisos del contrato de migración. `admin:all` no lo lleva ningún rol: hay preguntas que son `false` en todas partes. */
|
|
133
|
+
export declare const MIGRATION_PERMISSIONS: readonly ["docs:read", "docs:write", "billing:read", "admin:all"];
|
|
134
|
+
/** Los 4 roles, uno por nivel útil (dos a `app`, para que el nivel no sea la única variable). */
|
|
135
|
+
export declare const MIGRATION_ROLES: readonly ["mig-editor", "mig-viewer", "mig-lead", "mig-auditor"];
|
|
136
|
+
export declare const MIGRATION_CATALOG: CatalogSpec;
|
|
137
|
+
/** Los 7 nodos y los 6 holders de una corrida (uuids nuevos por corrida; la FORMA es la fija). */
|
|
138
|
+
export interface MigrationSeed {
|
|
139
|
+
scopes: {
|
|
140
|
+
app: ScopeRef;
|
|
141
|
+
org1: ScopeRef;
|
|
142
|
+
org2: ScopeRef;
|
|
143
|
+
unit1: ScopeRef;
|
|
144
|
+
unit2: ScopeRef;
|
|
145
|
+
unit3: ScopeRef;
|
|
146
|
+
unit4: ScopeRef;
|
|
147
|
+
};
|
|
148
|
+
holders: SubjectRef[];
|
|
149
|
+
/** El instante de la corrida: las caducidades se colocan alrededor. */
|
|
150
|
+
now: Date;
|
|
151
|
+
}
|
|
152
|
+
export declare function makeMigrationSeed(now?: Date): MigrationSeed;
|
|
153
|
+
/** El árbol: 7 nodos con profundidad 4 (`app → org1 → unit1 → unit4`). */
|
|
154
|
+
export declare function plantMigrationTree(tree: ContractScopeTree, seed: MigrationSeed): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Los 14 grants (5 con caducidad: 4 vivas y **1 ya pasada**, que es la
|
|
157
|
+
* pérdida declarada `expired`) y los 6 denies, escritos con la API del
|
|
158
|
+
* driver — nunca a mano: lo que se migra tiene que ser lo que el motor
|
|
159
|
+
* escribe.
|
|
160
|
+
*/
|
|
161
|
+
export interface MigrationGrant {
|
|
162
|
+
holder: SubjectRef;
|
|
163
|
+
role: string;
|
|
164
|
+
scope: ScopeRef;
|
|
165
|
+
/** Omitido = sin caducidad; una `Date` = la caducidad exacta sembrada. */
|
|
166
|
+
expiresAt?: Date;
|
|
167
|
+
/** La única ya vencida: es la pérdida declarada `expired`. */
|
|
168
|
+
expired?: true;
|
|
169
|
+
}
|
|
170
|
+
/** Un deny de la siembra. Tabla, y no una lista suelta, por lo mismo que los grants. */
|
|
171
|
+
export interface MigrationDeny {
|
|
172
|
+
holder: SubjectRef;
|
|
173
|
+
permission: string;
|
|
174
|
+
scope: ScopeRef;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* **Los 14 grants, en una tabla** — para que la siembra y el CRUCE DE
|
|
178
|
+
* CADUCIDADES salgan del mismo sitio: dos listas paralelas se separan al
|
|
179
|
+
* primer cambio y el cruce dejaría de comprobar lo que se sembró.
|
|
180
|
+
*/
|
|
181
|
+
export declare function migrationGrants(seed: MigrationSeed): MigrationGrant[];
|
|
182
|
+
/**
|
|
183
|
+
* **Los 6 denies, en una tabla** — misma razón que los grants: el CENSO
|
|
184
|
+
* (abajo) tiene que preguntar por lo que se sembró, y dos listas paralelas se
|
|
185
|
+
* separan al primer cambio.
|
|
186
|
+
*/
|
|
187
|
+
export declare function migrationDenies(seed: MigrationSeed): MigrationDeny[];
|
|
188
|
+
export declare function plantMigrationFacts(driver: AuthorizationDriver, seed: MigrationSeed): Promise<void>;
|
|
189
|
+
/**
|
|
190
|
+
* Un hecho de la siembra tal como el CENSO lo busca en el destino. Es la
|
|
191
|
+
* lista contra la que se comprueba que la migración no perdió nada: no
|
|
192
|
+
* depende de que alguna de las 448 respuestas se mueva, ni de que el driver
|
|
193
|
+
* se auto-declare nada.
|
|
194
|
+
*/
|
|
195
|
+
export interface MigrationFact {
|
|
196
|
+
kind: 'assignment' | 'deny';
|
|
197
|
+
holder: SubjectRef;
|
|
198
|
+
scope: ScopeRef;
|
|
199
|
+
/** `assignment`: el slug del rol. `deny`: el slug del permiso. */
|
|
200
|
+
name: string;
|
|
201
|
+
/**
|
|
202
|
+
* El motivo DECLARADO que justifica que este hecho NO llegue al destino.
|
|
203
|
+
* Sin él, que falte es una pérdida **silenciosa** y el contrato falla —
|
|
204
|
+
* cuente el driver lo que cuente en `report.skipped`.
|
|
205
|
+
*/
|
|
206
|
+
expectedLoss?: string;
|
|
207
|
+
}
|
|
208
|
+
/** Los 20 hechos de la siembra (14 asignaciones + 6 denies), en un solo sitio. */
|
|
209
|
+
export declare function migrationFacts(seed: MigrationSeed): MigrationFact[];
|
|
210
|
+
/** Cómo se nombra un hecho en el informe del contrato. */
|
|
211
|
+
export declare function describeMigrationFact(fact: MigrationFact): string;
|
|
212
|
+
export interface MigrationCensus {
|
|
213
|
+
present: MigrationFact[];
|
|
214
|
+
missing: MigrationFact[];
|
|
215
|
+
/** Lo que ESTE driver no deja censar, dicho en voz alta (nunca un hueco callado). */
|
|
216
|
+
limits: string[];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* **El censo** (lote 3b-4 · C1): pregunta al destino, hecho a hecho, si lo
|
|
220
|
+
* que se sembró está. Se lee por el camino DIRECTO del puerto —invariante 7,
|
|
221
|
+
* hechos directos del scope exacto—: `listRoles` para las asignaciones y
|
|
222
|
+
* `listDenies` para los denies. No mira `report.skipped`, no compara
|
|
223
|
+
* respuestas y no depende de que la pérdida cambie ninguna de las 448.
|
|
224
|
+
*
|
|
225
|
+
* `listDenies` es OPCIONAL en el puerto: un driver que no lo trae deja sus
|
|
226
|
+
* denies censados solo por `authorize` (lo dice `limits`, y está escrito en
|
|
227
|
+
* el README). Los dos drivers del paquete lo implementan.
|
|
228
|
+
*/
|
|
229
|
+
export declare function censusMigrationFacts(driver: AuthorizationDriver, seed: MigrationSeed): Promise<MigrationCensus>;
|
|
230
|
+
/**
|
|
231
|
+
* Las 448: **168 + 168 + 42 + 24 + 28 + 18**. No es un número redondo por
|
|
232
|
+
* casualidad — es el producto de la siembra fija, y por eso el contrato
|
|
233
|
+
* puede afirmar «448 preguntas idénticas» y no «unas cuantas».
|
|
234
|
+
*/
|
|
235
|
+
export declare function migrationQuestions(seed: MigrationSeed): MigrationQuestion[];
|
|
236
|
+
/** Cuántas preguntas tiene el set fijo. Es una CIFRA del contrato, no un detalle. */
|
|
237
|
+
export declare const MIGRATION_QUESTION_COUNT = 448;
|
|
238
|
+
export interface MigrationVerdict {
|
|
239
|
+
direction: MigrationDirection;
|
|
240
|
+
/** Los reportes de cada tramo (dos en `a→b→a`). */
|
|
241
|
+
reports: ReconcileReport[];
|
|
242
|
+
questions: number;
|
|
243
|
+
/** Respuestas que cambiaron, con la pérdida declarada que las explica (o `null`). */
|
|
244
|
+
mismatches: Array<{
|
|
245
|
+
question: string;
|
|
246
|
+
before: string;
|
|
247
|
+
after: string;
|
|
248
|
+
explainedBy: string | null;
|
|
249
|
+
}>;
|
|
250
|
+
/** Motivos declarados que NO aparecieron contados en `skipped`. */
|
|
251
|
+
declaredButAbsent: string[];
|
|
252
|
+
/** Caducidades que el destino no conservó (tester Fase 3b · M1). */
|
|
253
|
+
expiryMismatches: Array<{
|
|
254
|
+
grant: string;
|
|
255
|
+
before: string;
|
|
256
|
+
after: string;
|
|
257
|
+
}>;
|
|
258
|
+
/**
|
|
259
|
+
* Hechos de la SIEMBRA que el destino no tiene y que NADIE declaró (lote
|
|
260
|
+
* 3b-4 · C1). Es el censo, no `report.skipped`: aquí caen las pérdidas que
|
|
261
|
+
* el driver no cuenta.
|
|
262
|
+
*/
|
|
263
|
+
silentLosses: Array<{
|
|
264
|
+
fact: string;
|
|
265
|
+
at: string;
|
|
266
|
+
}>;
|
|
267
|
+
/** Lo que el driver no deja censar, dicho en voz alta (nunca un hueco callado). */
|
|
268
|
+
censusLimits: string[];
|
|
269
|
+
/** Todo lo que hace fallar el contrato, en texto. Vacío = verde. */
|
|
270
|
+
failures: string[];
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Corre UNA combinación de punta a punta y devuelve el veredicto. Es el
|
|
274
|
+
* motor: `runMigrationContract` solo lo envuelve en tres casos de Japa, y el
|
|
275
|
+
* paquete lo usa directamente para demostrar que el contrato **sabe fallar**.
|
|
276
|
+
*/
|
|
277
|
+
export declare function runMigrationDirection(harness: MigrationContractHarness, direction: MigrationDirection): Promise<MigrationVerdict>;
|
|
278
|
+
/**
|
|
279
|
+
* Registra las tres combinaciones como casos de Japa. Llámala en el TOP LEVEL
|
|
280
|
+
* del spec (Japa descarta los grupos registrados tarde).
|
|
281
|
+
*/
|
|
282
|
+
export declare function runMigrationContract(harness: MigrationContractHarness): void;
|
|
283
|
+
export declare function registerMigrationContract(harness: MigrationContractHarness, api: ContractTestApi): void;
|
|
284
|
+
//# sourceMappingURL=migration_contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration_contract.d.ts","sourceRoot":"","sources":["../../../src/testing/migration_contract.ts"],"names":[],"mappings":"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"}
|