@jantstack/adonis-authz 1.1.0 → 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.
Files changed (236) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +837 -51
  3. package/build/commands/authz_catalog_diff.d.ts +28 -0
  4. package/build/commands/authz_catalog_diff.d.ts.map +1 -0
  5. package/build/commands/authz_catalog_diff.js +67 -0
  6. package/build/commands/authz_catalog_diff.js.map +1 -0
  7. package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
  8. package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
  9. package/build/commands/authz_catalog_prune_orphans.js +136 -0
  10. package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
  11. package/build/commands/authz_catalog_sync.d.ts +37 -0
  12. package/build/commands/authz_catalog_sync.d.ts.map +1 -0
  13. package/build/commands/authz_catalog_sync.js +81 -0
  14. package/build/commands/authz_catalog_sync.js.map +1 -0
  15. package/build/commands/authz_freeze.d.ts +44 -0
  16. package/build/commands/authz_freeze.d.ts.map +1 -0
  17. package/build/commands/authz_freeze.js +95 -0
  18. package/build/commands/authz_freeze.js.map +1 -0
  19. package/build/commands/authz_reconcile.d.ts +102 -0
  20. package/build/commands/authz_reconcile.d.ts.map +1 -0
  21. package/build/commands/authz_reconcile.js +294 -0
  22. package/build/commands/authz_reconcile.js.map +1 -0
  23. package/build/commands/authz_relations_reconcile.d.ts +73 -0
  24. package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
  25. package/build/commands/authz_relations_reconcile.js +225 -0
  26. package/build/commands/authz_relations_reconcile.js.map +1 -0
  27. package/build/commands/authz_scopes_relay.d.ts +47 -0
  28. package/build/commands/authz_scopes_relay.d.ts.map +1 -0
  29. package/build/commands/authz_scopes_relay.js +141 -0
  30. package/build/commands/authz_scopes_relay.js.map +1 -0
  31. package/build/commands/authz_unfreeze.d.ts +37 -0
  32. package/build/commands/authz_unfreeze.d.ts.map +1 -0
  33. package/build/commands/authz_unfreeze.js +92 -0
  34. package/build/commands/authz_unfreeze.js.map +1 -0
  35. package/build/commands/main.d.ts +8 -1
  36. package/build/commands/main.d.ts.map +1 -1
  37. package/build/commands/main.js +8 -1
  38. package/build/commands/main.js.map +1 -1
  39. package/build/commands/openfga_provision.d.ts +46 -4
  40. package/build/commands/openfga_provision.d.ts.map +1 -1
  41. package/build/commands/openfga_provision.js +91 -7
  42. package/build/commands/openfga_provision.js.map +1 -1
  43. package/build/configure.d.ts +11 -0
  44. package/build/configure.d.ts.map +1 -1
  45. package/build/configure.js +37 -1
  46. package/build/configure.js.map +1 -1
  47. package/build/index.d.ts +75 -7
  48. package/build/index.d.ts.map +1 -1
  49. package/build/index.js +67 -5
  50. package/build/index.js.map +1 -1
  51. package/build/providers/authz_provider.d.ts +26 -2
  52. package/build/providers/authz_provider.d.ts.map +1 -1
  53. package/build/providers/authz_provider.js +48 -2
  54. package/build/providers/authz_provider.js.map +1 -1
  55. package/build/services/relations.d.ts +14 -0
  56. package/build/services/relations.d.ts.map +1 -0
  57. package/build/services/relations.js +17 -0
  58. package/build/services/relations.js.map +1 -0
  59. package/build/src/catalog/catalog.d.ts +289 -0
  60. package/build/src/catalog/catalog.d.ts.map +1 -0
  61. package/build/src/catalog/catalog.js +859 -0
  62. package/build/src/catalog/catalog.js.map +1 -0
  63. package/build/src/catalog/catalog_cache.d.ts +324 -0
  64. package/build/src/catalog/catalog_cache.d.ts.map +1 -0
  65. package/build/src/catalog/catalog_cache.js +666 -0
  66. package/build/src/catalog/catalog_cache.js.map +1 -0
  67. package/build/src/clock.d.ts +24 -0
  68. package/build/src/clock.d.ts.map +1 -0
  69. package/build/src/clock.js +7 -0
  70. package/build/src/clock.js.map +1 -0
  71. package/build/src/define_config.d.ts +201 -7
  72. package/build/src/define_config.d.ts.map +1 -1
  73. package/build/src/define_config.js.map +1 -1
  74. package/build/src/drivers/database_driver.d.ts +324 -15
  75. package/build/src/drivers/database_driver.d.ts.map +1 -1
  76. package/build/src/drivers/database_driver.js +1107 -128
  77. package/build/src/drivers/database_driver.js.map +1 -1
  78. package/build/src/drivers/database_relations_driver.d.ts +75 -0
  79. package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
  80. package/build/src/drivers/database_relations_driver.js +450 -0
  81. package/build/src/drivers/database_relations_driver.js.map +1 -0
  82. package/build/src/drivers/openfga_driver.d.ts +963 -55
  83. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  84. package/build/src/drivers/openfga_driver.js +2693 -372
  85. package/build/src/drivers/openfga_driver.js.map +1 -1
  86. package/build/src/drivers/openfga_facts.d.ts +369 -0
  87. package/build/src/drivers/openfga_facts.d.ts.map +1 -0
  88. package/build/src/drivers/openfga_facts.js +813 -0
  89. package/build/src/drivers/openfga_facts.js.map +1 -0
  90. package/build/src/drivers/openfga_relations_driver.d.ts +120 -0
  91. package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
  92. package/build/src/drivers/openfga_relations_driver.js +466 -0
  93. package/build/src/drivers/openfga_relations_driver.js.map +1 -0
  94. package/build/src/errors.d.ts +586 -0
  95. package/build/src/errors.d.ts.map +1 -1
  96. package/build/src/errors.js +583 -0
  97. package/build/src/errors.js.map +1 -1
  98. package/build/src/expiry.d.ts +27 -0
  99. package/build/src/expiry.d.ts.map +1 -0
  100. package/build/src/expiry.js +50 -0
  101. package/build/src/expiry.js.map +1 -0
  102. package/build/src/freeze.d.ts +120 -0
  103. package/build/src/freeze.d.ts.map +1 -0
  104. package/build/src/freeze.js +172 -0
  105. package/build/src/freeze.js.map +1 -0
  106. package/build/src/hierarchical_resolver.d.ts +56 -0
  107. package/build/src/hierarchical_resolver.d.ts.map +1 -0
  108. package/build/src/hierarchical_resolver.js +87 -0
  109. package/build/src/hierarchical_resolver.js.map +1 -0
  110. package/build/src/{middleware → http}/app_access_middleware.d.ts +8 -6
  111. package/build/src/http/app_access_middleware.d.ts.map +1 -0
  112. package/build/src/{middleware → http}/app_access_middleware.js +10 -26
  113. package/build/src/http/app_access_middleware.js.map +1 -0
  114. package/build/src/http/resource_access_middleware.d.ts +105 -0
  115. package/build/src/http/resource_access_middleware.d.ts.map +1 -0
  116. package/build/src/http/resource_access_middleware.js +81 -0
  117. package/build/src/http/resource_access_middleware.js.map +1 -0
  118. package/build/src/identity.d.ts +228 -0
  119. package/build/src/identity.d.ts.map +1 -0
  120. package/build/src/identity.js +457 -0
  121. package/build/src/identity.js.map +1 -0
  122. package/build/src/manager.d.ts +536 -7
  123. package/build/src/manager.d.ts.map +1 -1
  124. package/build/src/manager.js +2676 -23
  125. package/build/src/manager.js.map +1 -1
  126. package/build/src/memoize_ancestors.d.ts +23 -0
  127. package/build/src/memoize_ancestors.d.ts.map +1 -0
  128. package/build/src/memoize_ancestors.js +42 -0
  129. package/build/src/memoize_ancestors.js.map +1 -0
  130. package/build/src/models/authz_assignment.d.ts +11 -11
  131. package/build/src/models/authz_assignment.d.ts.map +1 -1
  132. package/build/src/models/authz_deny.d.ts +11 -11
  133. package/build/src/models/authz_deny.d.ts.map +1 -1
  134. package/build/src/models/authz_permission.d.ts +17 -11
  135. package/build/src/models/authz_permission.d.ts.map +1 -1
  136. package/build/src/models/authz_permission.js +4 -0
  137. package/build/src/models/authz_permission.js.map +1 -1
  138. package/build/src/models/authz_role.d.ts +19 -12
  139. package/build/src/models/authz_role.d.ts.map +1 -1
  140. package/build/src/models/authz_role.js +6 -1
  141. package/build/src/models/authz_role.js.map +1 -1
  142. package/build/src/models/authz_role_permission.d.ts +11 -11
  143. package/build/src/models/authz_role_permission.d.ts.map +1 -1
  144. package/build/src/openfga.d.ts +29 -0
  145. package/build/src/openfga.d.ts.map +1 -0
  146. package/build/src/openfga.js +26 -0
  147. package/build/src/openfga.js.map +1 -0
  148. package/build/src/reconcile.d.ts +37 -0
  149. package/build/src/reconcile.d.ts.map +1 -0
  150. package/build/src/reconcile.js +69 -0
  151. package/build/src/reconcile.js.map +1 -0
  152. package/build/src/relation_partition_trigger.d.ts +8 -0
  153. package/build/src/relation_partition_trigger.d.ts.map +1 -0
  154. package/build/src/relation_partition_trigger.js +85 -0
  155. package/build/src/relation_partition_trigger.js.map +1 -0
  156. package/build/src/relations/define_relations_config.d.ts +58 -0
  157. package/build/src/relations/define_relations_config.d.ts.map +1 -0
  158. package/build/src/relations/define_relations_config.js +144 -0
  159. package/build/src/relations/define_relations_config.js.map +1 -0
  160. package/build/src/relations/manager.d.ts +38 -0
  161. package/build/src/relations/manager.d.ts.map +1 -0
  162. package/build/src/relations/manager.js +156 -0
  163. package/build/src/relations/manager.js.map +1 -0
  164. package/build/src/relations/reconcile.d.ts +62 -0
  165. package/build/src/relations/reconcile.d.ts.map +1 -0
  166. package/build/src/relations/reconcile.js +138 -0
  167. package/build/src/relations/reconcile.js.map +1 -0
  168. package/build/src/relations_config_store.d.ts +22 -0
  169. package/build/src/relations_config_store.d.ts.map +1 -0
  170. package/build/src/relations_config_store.js +74 -0
  171. package/build/src/relations_config_store.js.map +1 -0
  172. package/build/src/scope_outbox.d.ts +69 -0
  173. package/build/src/scope_outbox.d.ts.map +1 -0
  174. package/build/src/scope_outbox.js +291 -0
  175. package/build/src/scope_outbox.js.map +1 -0
  176. package/build/src/shared/backend_guard.d.ts +106 -0
  177. package/build/src/shared/backend_guard.d.ts.map +1 -0
  178. package/build/src/shared/backend_guard.js +246 -0
  179. package/build/src/shared/backend_guard.js.map +1 -0
  180. package/build/src/shared/sql_expiry.d.ts +53 -0
  181. package/build/src/shared/sql_expiry.d.ts.map +1 -0
  182. package/build/src/shared/sql_expiry.js +66 -0
  183. package/build/src/shared/sql_expiry.js.map +1 -0
  184. package/build/src/sql_descendants.d.ts +97 -0
  185. package/build/src/sql_descendants.d.ts.map +1 -0
  186. package/build/src/sql_descendants.js +203 -0
  187. package/build/src/sql_descendants.js.map +1 -0
  188. package/build/src/testing/contract.d.ts +212 -7
  189. package/build/src/testing/contract.d.ts.map +1 -1
  190. package/build/src/testing/contract.js +3449 -24
  191. package/build/src/testing/contract.js.map +1 -1
  192. package/build/src/testing/main.d.ts +10 -2
  193. package/build/src/testing/main.d.ts.map +1 -1
  194. package/build/src/testing/main.js +5 -1
  195. package/build/src/testing/main.js.map +1 -1
  196. package/build/src/testing/migration_contract.d.ts +284 -0
  197. package/build/src/testing/migration_contract.d.ts.map +1 -0
  198. package/build/src/testing/migration_contract.js +586 -0
  199. package/build/src/testing/migration_contract.js.map +1 -0
  200. package/build/src/testing/relations_contract.d.ts +51 -0
  201. package/build/src/testing/relations_contract.d.ts.map +1 -0
  202. package/build/src/testing/relations_contract.js +654 -0
  203. package/build/src/testing/relations_contract.js.map +1 -0
  204. package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
  205. package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
  206. package/build/src/testing/relations_reconcile_contract.js +172 -0
  207. package/build/src/testing/relations_reconcile_contract.js.map +1 -0
  208. package/build/src/testing/scope_tree.d.ts +65 -0
  209. package/build/src/testing/scope_tree.d.ts.map +1 -0
  210. package/build/src/testing/scope_tree.js +145 -0
  211. package/build/src/testing/scope_tree.js.map +1 -0
  212. package/build/src/traits/authz_scopes.d.ts +30 -6
  213. package/build/src/traits/authz_scopes.d.ts.map +1 -1
  214. package/build/src/traits/authz_scopes.js +30 -18
  215. package/build/src/traits/authz_scopes.js.map +1 -1
  216. package/build/src/traits/has_uuid.d.ts +12 -12
  217. package/build/src/traits/has_uuid.d.ts.map +1 -1
  218. package/build/src/types.d.ts +1313 -28
  219. package/build/src/types.d.ts.map +1 -1
  220. package/build/src/types.js +20 -4
  221. package/build/src/types.js.map +1 -1
  222. package/build/stubs/config/app_acl.stub +4 -2
  223. package/build/stubs/config/authorization.stub +168 -14
  224. package/build/stubs/migration.stub +183 -13
  225. package/build/stubs/scopes_outbox_migration.stub +57 -0
  226. package/package.json +14 -7
  227. package/build/commands/openfga_import.d.ts +0 -28
  228. package/build/commands/openfga_import.d.ts.map +0 -1
  229. package/build/commands/openfga_import.js +0 -74
  230. package/build/commands/openfga_import.js.map +0 -1
  231. package/build/src/catalog.d.ts +0 -3
  232. package/build/src/catalog.d.ts.map +0 -1
  233. package/build/src/catalog.js +0 -103
  234. package/build/src/catalog.js.map +0 -1
  235. package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
  236. package/build/src/middleware/app_access_middleware.js.map +0 -1
@@ -64,15 +64,24 @@ declare const AuthzRole_base: {
64
64
  selfAssignPrimaryKey: boolean;
65
65
  generateUuid(model: any): void;
66
66
  nextUuid(): string;
67
+ transaction: import("@adonisjs/lucid/types/database").TransactionFn;
68
+ all: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<InstanceType<T>[]>;
67
69
  find: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, value: any, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<null | InstanceType<T>>;
70
+ table: string;
71
+ connection?: string | undefined;
72
+ first: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<null | InstanceType<T>>;
73
+ truncate: (cascade?: boolean) => Promise<void>;
74
+ after: {
75
+ <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "fetch", handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>[], "fetch">): void;
76
+ <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "paginate", handler: import("@adonisjs/lucid/types/model").HooksHandler<import("@adonisjs/lucid/types/model").ModelPaginatorContract<InstanceType<Model>>, "paginate">): void;
77
+ <Model extends import("@adonisjs/lucid/types/model").LucidModel, Event extends import("@adonisjs/lucid/types/model").EventsList>(this: Model, event: Event, handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>, Event>): void;
78
+ };
68
79
  readonly booted: boolean;
69
80
  $columnsDefinitions: Map<string, import("@adonisjs/lucid/types/model").ModelColumnOptions>;
70
81
  $relationsDefinitions: Map<string, import("@adonisjs/lucid/types/relations").RelationshipsContract>;
71
82
  $computedDefinitions: Map<string, import("@adonisjs/lucid/types/model").ComputedOptions>;
72
83
  primaryKey: string;
73
- connection?: string | undefined;
74
84
  namingStrategy: import("@adonisjs/lucid/types/model").NamingStrategyContract;
75
- table: string;
76
85
  $adapter: import("@adonisjs/lucid/types/model").AdapterContract;
77
86
  useAdapter: (adapter: import("@adonisjs/lucid/types/model").AdapterContract) => void;
78
87
  $hooks: import("@poppinss/hooks").default<any>;
@@ -108,11 +117,6 @@ declare const AuthzRole_base: {
108
117
  <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "paginate", handler: import("@adonisjs/lucid/types/model").HooksHandler<[import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<Model>, import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<Model>], "paginate">): void;
109
118
  <Model extends import("@adonisjs/lucid/types/model").LucidModel, Event extends import("@adonisjs/lucid/types/model").EventsList>(this: Model, event: Event, handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>, Event>): void;
110
119
  };
111
- after: {
112
- <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "fetch", handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>[], "fetch">): void;
113
- <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "paginate", handler: import("@adonisjs/lucid/types/model").HooksHandler<import("@adonisjs/lucid/types/model").ModelPaginatorContract<InstanceType<Model>>, "paginate">): void;
114
- <Model extends import("@adonisjs/lucid/types/model").LucidModel, Event extends import("@adonisjs/lucid/types/model").EventsList>(this: Model, event: Event, handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>, Event>): void;
115
- };
116
120
  create: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, values: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>, options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>>;
117
121
  createQuietly: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, values: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>, options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>>;
118
122
  createMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, values: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>[], options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>[]>;
@@ -130,7 +134,6 @@ declare const AuthzRole_base: {
130
134
  <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, clause: Record<string, unknown>, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions): Promise<InstanceType<T>[]>;
131
135
  <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, key: string, value: any, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions): Promise<InstanceType<T>[]>;
132
136
  };
133
- first: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<null | InstanceType<T>>;
134
137
  firstOrFail: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<InstanceType<T>>;
135
138
  findMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, value: any[], options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<InstanceType<T>[]>;
136
139
  firstOrNew: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, searchPayload: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>, savePayload?: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>, options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>>;
@@ -139,14 +142,12 @@ declare const AuthzRole_base: {
139
142
  fetchOrNewUpMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, predicate: keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>> | (keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>)[], payload: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>[], options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>[]>;
140
143
  fetchOrCreateMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, predicate: keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>> | (keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>)[], payload: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>[], options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>[]>;
141
144
  updateOrCreateMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, predicate: keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>> | (keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>)[], payload: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>[], options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>[]>;
142
- all: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<InstanceType<T>[]>;
143
145
  query: <Model extends import("@adonisjs/lucid/types/model").LucidModel, Result = InstanceType<Model>>(this: Model, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<Model, Result>;
144
- transaction: import("@adonisjs/lucid/types/database").TransactionFn;
145
- truncate: (cascade?: boolean) => Promise<void>;
146
146
  } & import("@adonisjs/lucid/types/model").LucidModel;
147
147
  /**
148
148
  * Rol del motor de autorización propio. `scopeType` indica a qué nivel es
149
- * asignable ('app' | 'organization' | 'unit'); el slug es único por nivel.
149
+ * asignable ('app' | 'organization' | 'unit'); el slug es único por nivel y
150
+ * owner (`ownerScopeKey`, 3B): dos tenants pueden definir `lead@unit`.
150
151
  */
151
152
  export default class AuthzRole extends AuthzRole_base {
152
153
  static table: string;
@@ -158,6 +159,12 @@ export default class AuthzRole extends AuthzRole_base {
158
159
  scopeType: string;
159
160
  /** Rango de privilegio (mayor = más poder) — lo consume la policy de asignación. */
160
161
  rank: number;
162
+ /**
163
+ * Quién define el rol (3B): `'global'` (el catálogo del config) o la clave
164
+ * del scope que lo definió con `defineScopedRole` (`<tipo>|<uuid>`). Un
165
+ * rol local solo es visible dentro de su owner.
166
+ */
167
+ ownerScopeKey: string;
161
168
  permissions: ManyToMany<typeof AuthzPermission>;
162
169
  createdAt: DateTime;
163
170
  updatedAt: DateTime;
@@ -1 +1 @@
1
- {"version":3,"file":"authz_role.d.ts","sourceRoot":"","sources":["../../../src/models/authz_role.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE,OAAO,eAAe,MAAM,uBAAuB,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oZA8Ck8rB,gDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA3CtisB;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,cAA2B;IAChE,OAAc,KAAK,SAAgB;IACnC,OAAc,UAAU,SAAS;IAGzB,IAAI,EAAE,MAAM,CAAA;IAGZ,IAAI,EAAE,MAAM,CAAA;IAGZ,IAAI,EAAE,MAAM,CAAA;IAGZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAG1B,SAAS,EAAE,MAAM,CAAA;IAEzB,oFAAoF;IAE5E,IAAI,EAAE,MAAM,CAAA;IAUZ,WAAW,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA;IAG/C,SAAS,EAAE,QAAQ,CAAA;IAGnB,SAAS,EAAE,QAAQ,CAAA;CAC5B"}
1
+ {"version":3,"file":"authz_role.d.ts","sourceRoot":"","sources":["../../../src/models/authz_role.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE,OAAO,eAAe,MAAM,uBAAuB,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oZAuDmlrB,gDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AApDvrrB;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,cAA2B;IAChE,OAAc,KAAK,SAAgB;IACnC,OAAc,UAAU,SAAS;IAGzB,IAAI,EAAE,MAAM,CAAA;IAGZ,IAAI,EAAE,MAAM,CAAA;IAGZ,IAAI,EAAE,MAAM,CAAA;IAGZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAG1B,SAAS,EAAE,MAAM,CAAA;IAEzB,oFAAoF;IAE5E,IAAI,EAAE,MAAM,CAAA;IAEpB;;;;OAIG;IAEK,aAAa,EAAE,MAAM,CAAA;IAUrB,WAAW,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA;IAG/C,SAAS,EAAE,QAAQ,CAAA;IAGnB,SAAS,EAAE,QAAQ,CAAA;CAC5B"}
@@ -14,7 +14,8 @@ import AuthzPermission from './authz_permission.js';
14
14
  import { hasUuid } from '../traits/has_uuid.js';
15
15
  /**
16
16
  * Rol del motor de autorización propio. `scopeType` indica a qué nivel es
17
- * asignable ('app' | 'organization' | 'unit'); el slug es único por nivel.
17
+ * asignable ('app' | 'organization' | 'unit'); el slug es único por nivel y
18
+ * owner (`ownerScopeKey`, 3B): dos tenants pueden definir `lead@unit`.
18
19
  */
19
20
  export default class AuthzRole extends compose(BaseModel, hasUuid) {
20
21
  static table = 'authz_roles';
@@ -44,6 +45,10 @@ __decorate([
44
45
  column(),
45
46
  __metadata("design:type", Number)
46
47
  ], AuthzRole.prototype, "rank", void 0);
48
+ __decorate([
49
+ column({ columnName: 'owner_scope_key' }),
50
+ __metadata("design:type", String)
51
+ ], AuthzRole.prototype, "ownerScopeKey", void 0);
47
52
  __decorate([
48
53
  manyToMany(() => AuthzPermission, {
49
54
  pivotTable: 'authz_role_permissions',
@@ -1 +1 @@
1
- {"version":3,"file":"authz_role.js","sourceRoot":"","sources":["../../../src/models/authz_role.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEnE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,eAAe,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAE/C;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC;IACzD,MAAM,CAAC,KAAK,GAAG,aAAa,CAAA;IAC5B,MAAM,CAAC,UAAU,GAAG,MAAM,CAAA;;AAGzB;IADP,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;;uCACR;AAGZ;IADP,MAAM,EAAE;;uCACW;AAGZ;IADP,MAAM,EAAE;;uCACW;AAGZ;IADP,MAAM,EAAE;;8CACyB;AAG1B;IADP,MAAM,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;;4CACZ;AAIjB;IADP,MAAM,EAAE;;uCACW;AAUZ;IARP,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE;QACjC,UAAU,EAAE,wBAAwB;QACpC,QAAQ,EAAE,MAAM;QAChB,eAAe,EAAE,WAAW;QAC5B,UAAU,EAAE,MAAM;QAClB,sBAAsB,EAAE,iBAAiB;QACzC,eAAe,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE;KAC/D,CAAC;;8CACqD;AAG/C;IADP,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;8BAC7C,QAAQ;4CAAA;AAGnB;IADP,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;8BAC/D,QAAQ;4CAAA"}
1
+ {"version":3,"file":"authz_role.js","sourceRoot":"","sources":["../../../src/models/authz_role.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEnE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,eAAe,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAE/C;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC;IACzD,MAAM,CAAC,KAAK,GAAG,aAAa,CAAA;IAC5B,MAAM,CAAC,UAAU,GAAG,MAAM,CAAA;;AAGzB;IADP,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;;uCACR;AAGZ;IADP,MAAM,EAAE;;uCACW;AAGZ;IADP,MAAM,EAAE;;uCACW;AAGZ;IADP,MAAM,EAAE;;8CACyB;AAG1B;IADP,MAAM,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;;4CACZ;AAIjB;IADP,MAAM,EAAE;;uCACW;AAQZ;IADP,MAAM,CAAC,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC;;gDACb;AAUrB;IARP,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE;QACjC,UAAU,EAAE,wBAAwB;QACpC,QAAQ,EAAE,MAAM;QAChB,eAAe,EAAE,WAAW;QAC5B,UAAU,EAAE,MAAM;QAClB,sBAAsB,EAAE,iBAAiB;QACzC,eAAe,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE;KAC/D,CAAC;;8CACqD;AAG/C;IADP,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;8BAC7C,QAAQ;4CAAA;AAGnB;IADP,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;8BAC/D,QAAQ;4CAAA"}
@@ -62,15 +62,24 @@ declare const AuthzRolePermission_base: {
62
62
  selfAssignPrimaryKey: boolean;
63
63
  generateUuid(model: any): void;
64
64
  nextUuid(): string;
65
+ transaction: import("@adonisjs/lucid/types/database").TransactionFn;
66
+ all: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<InstanceType<T>[]>;
65
67
  find: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, value: any, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<null | InstanceType<T>>;
68
+ table: string;
69
+ connection?: string | undefined;
70
+ first: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<null | InstanceType<T>>;
71
+ truncate: (cascade?: boolean) => Promise<void>;
72
+ after: {
73
+ <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "fetch", handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>[], "fetch">): void;
74
+ <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "paginate", handler: import("@adonisjs/lucid/types/model").HooksHandler<import("@adonisjs/lucid/types/model").ModelPaginatorContract<InstanceType<Model>>, "paginate">): void;
75
+ <Model extends import("@adonisjs/lucid/types/model").LucidModel, Event extends import("@adonisjs/lucid/types/model").EventsList>(this: Model, event: Event, handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>, Event>): void;
76
+ };
66
77
  readonly booted: boolean;
67
78
  $columnsDefinitions: Map<string, import("@adonisjs/lucid/types/model").ModelColumnOptions>;
68
79
  $relationsDefinitions: Map<string, import("@adonisjs/lucid/types/relations").RelationshipsContract>;
69
80
  $computedDefinitions: Map<string, import("@adonisjs/lucid/types/model").ComputedOptions>;
70
81
  primaryKey: string;
71
- connection?: string | undefined;
72
82
  namingStrategy: import("@adonisjs/lucid/types/model").NamingStrategyContract;
73
- table: string;
74
83
  $adapter: import("@adonisjs/lucid/types/model").AdapterContract;
75
84
  useAdapter: (adapter: import("@adonisjs/lucid/types/model").AdapterContract) => void;
76
85
  $hooks: import("@poppinss/hooks").default<any>;
@@ -106,11 +115,6 @@ declare const AuthzRolePermission_base: {
106
115
  <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "paginate", handler: import("@adonisjs/lucid/types/model").HooksHandler<[import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<Model>, import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<Model>], "paginate">): void;
107
116
  <Model extends import("@adonisjs/lucid/types/model").LucidModel, Event extends import("@adonisjs/lucid/types/model").EventsList>(this: Model, event: Event, handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>, Event>): void;
108
117
  };
109
- after: {
110
- <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "fetch", handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>[], "fetch">): void;
111
- <Model extends import("@adonisjs/lucid/types/model").LucidModel>(this: Model, event: "paginate", handler: import("@adonisjs/lucid/types/model").HooksHandler<import("@adonisjs/lucid/types/model").ModelPaginatorContract<InstanceType<Model>>, "paginate">): void;
112
- <Model extends import("@adonisjs/lucid/types/model").LucidModel, Event extends import("@adonisjs/lucid/types/model").EventsList>(this: Model, event: Event, handler: import("@adonisjs/lucid/types/model").HooksHandler<InstanceType<Model>, Event>): void;
113
- };
114
118
  create: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, values: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>, options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>>;
115
119
  createQuietly: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, values: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>, options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>>;
116
120
  createMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, values: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>[], options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>[]>;
@@ -128,7 +132,6 @@ declare const AuthzRolePermission_base: {
128
132
  <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, clause: Record<string, unknown>, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions): Promise<InstanceType<T>[]>;
129
133
  <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, key: string, value: any, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions): Promise<InstanceType<T>[]>;
130
134
  };
131
- first: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<null | InstanceType<T>>;
132
135
  firstOrFail: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<InstanceType<T>>;
133
136
  findMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, value: any[], options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<InstanceType<T>[]>;
134
137
  firstOrNew: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, searchPayload: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>, savePayload?: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>, options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>>;
@@ -137,10 +140,7 @@ declare const AuthzRolePermission_base: {
137
140
  fetchOrNewUpMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, predicate: keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>> | (keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>)[], payload: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>[], options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>[]>;
138
141
  fetchOrCreateMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, predicate: keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>> | (keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>)[], payload: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>[], options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>[]>;
139
142
  updateOrCreateMany: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, predicate: keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>> | (keyof import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>)[], payload: Partial<import("@adonisjs/lucid/types/model").ModelAttributes<InstanceType<T>>>[], options?: import("@adonisjs/lucid/types/model").ModelAssignOptions) => Promise<InstanceType<T>[]>;
140
- all: <T extends import("@adonisjs/lucid/types/model").LucidModel>(this: T, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => Promise<InstanceType<T>[]>;
141
143
  query: <Model extends import("@adonisjs/lucid/types/model").LucidModel, Result = InstanceType<Model>>(this: Model, options?: import("@adonisjs/lucid/types/model").ModelAdapterOptions) => import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<Model, Result>;
142
- transaction: import("@adonisjs/lucid/types/database").TransactionFn;
143
- truncate: (cascade?: boolean) => Promise<void>;
144
144
  } & import("@adonisjs/lucid/types/model").LucidModel;
145
145
  /** Pivot rol ↔ permiso del motor de autorización propio. */
146
146
  export default class AuthzRolePermission extends AuthzRolePermission_base {
@@ -1 +1 @@
1
- {"version":3,"file":"authz_role_permission.d.ts","sourceRoot":"","sources":["../../../src/models/authz_role_permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oZAsBoxtB,gDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAjBr2tB,4DAA4D;AAC5D,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,wBAA2B;IAC1E,OAAc,KAAK,SAA2B;IAC9C,OAAc,UAAU,SAAS;IAGzB,IAAI,EAAE,MAAM,CAAA;IAGZ,QAAQ,EAAE,MAAM,CAAA;IAGhB,cAAc,EAAE,MAAM,CAAA;IAGtB,SAAS,EAAE,QAAQ,CAAA;CAC5B"}
1
+ {"version":3,"file":"authz_role_permission.d.ts","sourceRoot":"","sources":["../../../src/models/authz_role_permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oZAsBoxtB,gDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAjBr2tB,4DAA4D;AAC5D,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,wBAA2B;IAC1E,OAAc,KAAK,SAA2B;IAC9C,OAAc,UAAU,SAAS;IAGzB,IAAI,EAAE,MAAM,CAAA;IAGZ,QAAQ,EAAE,MAAM,CAAA;IAGhB,cAAc,EAAE,MAAM,CAAA;IAGtB,SAAS,EAAE,QAAQ,CAAA;CAC5B"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Entrada del subpath `@jantstack/adonis-authz/openfga` — TODO lo que tira de
3
+ * `@openfga/sdk` (peer opcional) vive detrás de esta puerta (D9):
4
+ *
5
+ * const { OpenFgaAuthorizationDriver } = await import('@jantstack/adonis-authz/openfga')
6
+ *
7
+ * La entrada principal (`@jantstack/adonis-authz`) no importa este módulo ni
8
+ * el driver: un consumidor solo-database arranca sin el SDK instalado, y
9
+ * `scripts/check_purity.mjs` (regla 3) lo vigila en cada build.
10
+ */
11
+ export { OpenFgaAuthorizationDriver, provisionOpenFgaStore, assertHolderTypes, parseBindingId, correlateBatchResults, isDuplicateWrite, DEFAULT_TIMEOUT_MS, } from './drivers/openfga_driver.js';
12
+ export type { HolderTypeMap, OpenFgaDriverOptions } from './drivers/openfga_driver.js';
13
+ /**
14
+ * El driver `openfga` del puerto `RelationsDriver` (Fase 4, lote 4-4): ReBAC
15
+ * sobre el MISMO store y `modelId` que el driver `facts` de roles. Vive detrás
16
+ * de esta puerta como el resto de lo que toca `@openfga/sdk`.
17
+ */
18
+ export { OpenFgaRelationsDriver } from './drivers/openfga_relations_driver.js';
19
+ export type { OpenFgaRelationsDriverOptions } from './drivers/openfga_relations_driver.js';
20
+ /**
21
+ * El modelo (c2r) y la proyección del catálogo (3b-2a; desde 3b-2k · K2 es
22
+ * el ÚNICO modelo: `openFgaAuthorizationModel` —el del modo `resolver`— y
23
+ * `importAuthzFactsToOpenFga` se borraron con él). Sin `@openfga/sdk` —es
24
+ * JSON y cadenas—, pero se publica por esta misma puerta: es material de
25
+ * OpenFGA y solo lo usa quien lo elige.
26
+ */
27
+ export { openFgaFactsModel, factsRelationsOf, factsRelationMap, factsCatalogTuples, factsTupleId, factsModelBytes, assertFactsModelPublishable, assertFgaObjectId, FACTS_MODEL_MAX_BYTES, FACTS_MODEL_WARN_RATIO, FGA_MAX_RELATION_NAME, FGA_MAX_OBJECT_ID, FACTS_MAX_RESOLVE_DEPTH, FGA_MAX_BATCH_CHECK, factsScopeObject, factsParentTuple, FACTS_SCOPE_TYPE, FACTS_PARENT_RELATION, factsRootTuples, FACTS_ROOTED_RELATION, factsRelationTypeDefinitions, assertRelationsConfigPublishable, RESERVED_FACTS_TYPES, FACTS_GROUP_TYPE, FACTS_GROUP_MEMBER_RELATION, } from './drivers/openfga_facts.js';
28
+ export type { FactsRelations, FactsCatalogTuple, FactsTuple, FactsRelationsConfig, RelationObjectType, RelationObjectRelation, } from './drivers/openfga_facts.js';
29
+ //# sourceMappingURL=openfga.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfga.d.ts","sourceRoot":"","sources":["../../src/openfga.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,6BAA6B,CAAA;AACpC,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAEtF;;;;GAIG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAA;AAC9E,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAA;AAE1F;;;;;;GAMG;AACH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,2BAA2B,EAC3B,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,4BAA4B,EAC5B,gCAAgC,EAChC,oBAAoB,EACpB,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,4BAA4B,CAAA;AACnC,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,4BAA4B,CAAA"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Entrada del subpath `@jantstack/adonis-authz/openfga` — TODO lo que tira de
3
+ * `@openfga/sdk` (peer opcional) vive detrás de esta puerta (D9):
4
+ *
5
+ * const { OpenFgaAuthorizationDriver } = await import('@jantstack/adonis-authz/openfga')
6
+ *
7
+ * La entrada principal (`@jantstack/adonis-authz`) no importa este módulo ni
8
+ * el driver: un consumidor solo-database arranca sin el SDK instalado, y
9
+ * `scripts/check_purity.mjs` (regla 3) lo vigila en cada build.
10
+ */
11
+ export { OpenFgaAuthorizationDriver, provisionOpenFgaStore, assertHolderTypes, parseBindingId, correlateBatchResults, isDuplicateWrite, DEFAULT_TIMEOUT_MS, } from './drivers/openfga_driver.js';
12
+ /**
13
+ * El driver `openfga` del puerto `RelationsDriver` (Fase 4, lote 4-4): ReBAC
14
+ * sobre el MISMO store y `modelId` que el driver `facts` de roles. Vive detrás
15
+ * de esta puerta como el resto de lo que toca `@openfga/sdk`.
16
+ */
17
+ export { OpenFgaRelationsDriver } from './drivers/openfga_relations_driver.js';
18
+ /**
19
+ * El modelo (c2r) y la proyección del catálogo (3b-2a; desde 3b-2k · K2 es
20
+ * el ÚNICO modelo: `openFgaAuthorizationModel` —el del modo `resolver`— y
21
+ * `importAuthzFactsToOpenFga` se borraron con él). Sin `@openfga/sdk` —es
22
+ * JSON y cadenas—, pero se publica por esta misma puerta: es material de
23
+ * OpenFGA y solo lo usa quien lo elige.
24
+ */
25
+ export { openFgaFactsModel, factsRelationsOf, factsRelationMap, factsCatalogTuples, factsTupleId, factsModelBytes, assertFactsModelPublishable, assertFgaObjectId, FACTS_MODEL_MAX_BYTES, FACTS_MODEL_WARN_RATIO, FGA_MAX_RELATION_NAME, FGA_MAX_OBJECT_ID, FACTS_MAX_RESOLVE_DEPTH, FGA_MAX_BATCH_CHECK, factsScopeObject, factsParentTuple, FACTS_SCOPE_TYPE, FACTS_PARENT_RELATION, factsRootTuples, FACTS_ROOTED_RELATION, factsRelationTypeDefinitions, assertRelationsConfigPublishable, RESERVED_FACTS_TYPES, FACTS_GROUP_TYPE, FACTS_GROUP_MEMBER_RELATION, } from './drivers/openfga_facts.js';
26
+ //# sourceMappingURL=openfga.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfga.js","sourceRoot":"","sources":["../../src/openfga.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,6BAA6B,CAAA;AAGpC;;;;GAIG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAA;AAG9E;;;;;;GAMG;AACH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,2BAA2B,EAC3B,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,4BAA4B,EAC5B,gCAAgC,EAChC,oBAAoB,EACpB,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,4BAA4B,CAAA"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Piezas COMPARTIDAS de `authz:reconcile` (3b-3b): lo que las dos
3
+ * direcciones —`--to=openfga` (3b-3a) y `--to=database`— tienen que decidir
4
+ * igual o el reporte deja de significar lo mismo según hacia dónde se migre.
5
+ *
6
+ * Vive aquí y no en un driver porque el driver `database` no puede importar
7
+ * del `openfga` (arrastraría el SDK, que es una peer dependency opcional) y
8
+ * porque duplicar la normalización de `batchSize`, la cota del volcado o la
9
+ * suma de fases es la forma más barata de que las dos direcciones cuenten
10
+ * distinto. Módulo puro: sin base de datos, sin red y sin `#aliases` del
11
+ * consumidor (`check:purity`).
12
+ */
13
+ import type { ReconcileCounts } from './types.js';
14
+ /** Filas por lote en el ORIGEN y operaciones por escritura en el destino. */
15
+ export declare const RECONCILE_BATCH = 100;
16
+ /**
17
+ * Cómo se NOMBRA el origen cuando los hechos son las tablas del paquete
18
+ * (3b-5). No es un driver: es el esquema PUBLICADO, y por eso tiene nombre
19
+ * propio en el reporte —«de dónde salieron los hechos» es la diferencia
20
+ * entre una migración y una pasada contra el driver activo—.
21
+ */
22
+ export declare const AUTHZ_TABLES_ORIGIN = "authz_assignments/authz_denies";
23
+ /** Tope de filas del reporte que se nombran una a una (el resto solo se cuenta). */
24
+ export declare const RECONCILE_MAX_DETAILS = 200;
25
+ /** Las cuatro fases de una pasada; en `--to=database` las tres primeras son cero. */
26
+ export type ReconcileFamily = 'root' | 'catalog' | 'tree' | 'facts';
27
+ export declare function reconcileBatchSize(value: number | undefined): number;
28
+ /**
29
+ * La cota DECLARADA del volcado (3b-3b · B5). No es una promesa de memoria:
30
+ * es el número por encima del cual la pasada se niega con
31
+ * `E_AUTHZ_RECONCILE_TOO_LARGE` en vez de intentarlo y morir a medias.
32
+ */
33
+ export declare function reconcileMaxTuples(value: number | undefined): number;
34
+ export declare function emptyReconcileCounts(): ReconcileCounts;
35
+ export declare function emptyReconcilePhases(): Record<ReconcileFamily, ReconcileCounts>;
36
+ export declare function sumReconcilePhases(phases: Record<ReconcileFamily, ReconcileCounts>): ReconcileCounts;
37
+ //# sourceMappingURL=reconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,6EAA6E;AAC7E,eAAO,MAAM,eAAe,MAAM,CAAA;AAElC;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,mCAAmC,CAAA;AAEnE,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,MAAM,CAAA;AAExC,qFAAqF;AACrF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAA;AAEnE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMpE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMpE;AAED,wBAAgB,oBAAoB,IAAI,eAAe,CAEtD;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,CAO/E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,GAAG,eAAe,CAUpG"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Piezas COMPARTIDAS de `authz:reconcile` (3b-3b): lo que las dos
3
+ * direcciones —`--to=openfga` (3b-3a) y `--to=database`— tienen que decidir
4
+ * igual o el reporte deja de significar lo mismo según hacia dónde se migre.
5
+ *
6
+ * Vive aquí y no en un driver porque el driver `database` no puede importar
7
+ * del `openfga` (arrastraría el SDK, que es una peer dependency opcional) y
8
+ * porque duplicar la normalización de `batchSize`, la cota del volcado o la
9
+ * suma de fases es la forma más barata de que las dos direcciones cuenten
10
+ * distinto. Módulo puro: sin base de datos, sin red y sin `#aliases` del
11
+ * consumidor (`check:purity`).
12
+ */
13
+ import { AuthorizationConfigError } from './errors.js';
14
+ import { DEFAULT_RECONCILE_MAX_TUPLES } from './types.js';
15
+ /** Filas por lote en el ORIGEN y operaciones por escritura en el destino. */
16
+ export const RECONCILE_BATCH = 100;
17
+ /**
18
+ * Cómo se NOMBRA el origen cuando los hechos son las tablas del paquete
19
+ * (3b-5). No es un driver: es el esquema PUBLICADO, y por eso tiene nombre
20
+ * propio en el reporte —«de dónde salieron los hechos» es la diferencia
21
+ * entre una migración y una pasada contra el driver activo—.
22
+ */
23
+ export const AUTHZ_TABLES_ORIGIN = 'authz_assignments/authz_denies';
24
+ /** Tope de filas del reporte que se nombran una a una (el resto solo se cuenta). */
25
+ export const RECONCILE_MAX_DETAILS = 200;
26
+ export function reconcileBatchSize(value) {
27
+ if (value === undefined)
28
+ return RECONCILE_BATCH;
29
+ if (!Number.isInteger(value) || value < 1) {
30
+ throw new AuthorizationConfigError(`authz:reconcile: batchSize debe ser un entero >= 1 (llegó ${String(value)})`);
31
+ }
32
+ return value;
33
+ }
34
+ /**
35
+ * La cota DECLARADA del volcado (3b-3b · B5). No es una promesa de memoria:
36
+ * es el número por encima del cual la pasada se niega con
37
+ * `E_AUTHZ_RECONCILE_TOO_LARGE` en vez de intentarlo y morir a medias.
38
+ */
39
+ export function reconcileMaxTuples(value) {
40
+ if (value === undefined)
41
+ return DEFAULT_RECONCILE_MAX_TUPLES;
42
+ if (!Number.isInteger(value) || value < 1) {
43
+ throw new AuthorizationConfigError(`authz:reconcile: maxTuples debe ser un entero >= 1 (llegó ${String(value)})`);
44
+ }
45
+ return value;
46
+ }
47
+ export function emptyReconcileCounts() {
48
+ return { written: 0, updated: 0, unchanged: 0, extra: 0, deleted: 0 };
49
+ }
50
+ export function emptyReconcilePhases() {
51
+ return {
52
+ root: emptyReconcileCounts(),
53
+ catalog: emptyReconcileCounts(),
54
+ tree: emptyReconcileCounts(),
55
+ facts: emptyReconcileCounts(),
56
+ };
57
+ }
58
+ export function sumReconcilePhases(phases) {
59
+ const total = emptyReconcileCounts();
60
+ for (const counts of Object.values(phases)) {
61
+ total.written += counts.written;
62
+ total.updated += counts.updated;
63
+ total.unchanged += counts.unchanged;
64
+ total.extra += counts.extra;
65
+ total.deleted += counts.deleted;
66
+ }
67
+ return total;
68
+ }
69
+ //# sourceMappingURL=reconcile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAA;AAGzD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;AAElC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,gCAAgC,CAAA;AAEnE,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;AAKxC,MAAM,UAAU,kBAAkB,CAAC,KAAyB;IAC1D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,eAAe,CAAA;IAC/C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,wBAAwB,CAAC,6DAA6D,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAyB;IAC1D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,4BAA4B,CAAA;IAC5D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,wBAAwB,CAAC,6DAA6D,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;AACvE,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,IAAI,EAAE,oBAAoB,EAAE;QAC5B,OAAO,EAAE,oBAAoB,EAAE;QAC/B,IAAI,EAAE,oBAAoB,EAAE;QAC5B,KAAK,EAAE,oBAAoB,EAAE;KAC9B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAgD;IACjF,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAA;IACpC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3C,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAA;QAC/B,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAA;QAC/B,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAA;QACnC,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAA;QAC3B,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAA;IACjC,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,8 @@
1
+ type TriggerDialect = 'sqlite' | 'postgres' | 'mysql';
2
+ export declare function triggerDialectOf(dialect: string): TriggerDialect;
3
+ /** Las sentencias a EJECUTAR (enteras) para crear el trigger de partición. */
4
+ export declare function relationPartitionTrigger(dialect: string): string[];
5
+ /** Las sentencias para soltar el trigger (y, en PG, su función) en el `down()`. */
6
+ export declare function relationPartitionTriggerDrops(dialect: string): string[];
7
+ export {};
8
+ //# sourceMappingURL=relation_partition_trigger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation_partition_trigger.d.ts","sourceRoot":"","sources":["../../src/relation_partition_trigger.ts"],"names":[],"mappings":"AA+BA,KAAK,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAA;AAErD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAShE;AAED,8EAA8E;AAC9E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA8BlE;AAED,mFAAmF;AACnF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAYvE"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * **La DDL del trigger de partición de `authz_relations` por dialecto** (Fase 4,
3
+ * lote 4-3) — módulo PURO, sin dependencia del servicio `db` de Lucid, para que
4
+ * lo pueda importar tanto el driver `database` de relaciones como el espejo del
5
+ * esquema de la suite (que se carga ANTES de bootear la app).
6
+ *
7
+ * El trigger es la defensa en profundidad contra un escritor «a mano» que meta
8
+ * en `authz_relations` una fila cuyo USERSET (sujeto con `subject_relation`)
9
+ * pertenece a OTRA partición que la de la fila. Cada sentencia se ejecuta
10
+ * ENTERA (su cuerpo `BEGIN…END` lleva `;` dentro): nunca por un runner que
11
+ * trocea por `;`.
12
+ *
13
+ * La forma es RADICALMENTE distinta en cada motor (medido por el analista, y
14
+ * probado en INSERT **y** UPDATE):
15
+ * - **SQLite**: `CREATE TRIGGER … BEFORE INSERT/UPDATE … WHEN … BEGIN SELECT
16
+ * RAISE(ABORT, …); END` — un trigger por evento; `IS NOT` es el distinto
17
+ * null-safe.
18
+ * - **PostgreSQL**: exige una FUNCIÓN plpgsql SEPARADA (`RAISE EXCEPTION`) y
19
+ * un `CREATE TRIGGER … EXECUTE FUNCTION` que la invoca; un solo trigger
20
+ * `BEFORE INSERT OR UPDATE`. `IS DISTINCT FROM` es el distinto null-safe.
21
+ * - **MySQL**: `SIGNAL SQLSTATE '45000'` dentro de `IF … THEN … END IF`; un
22
+ * trigger por evento; `<=>` es el igual null-safe (`NOT (a <=> b)` = distinto).
23
+ *
24
+ * Cualquier otro dialecto ⇒ 500 `E_AUTHZ_UNSUPPORTED_DIALECT` (nunca una tabla
25
+ * sin defensa), exactamente como `sqlDescendantsOf`.
26
+ */
27
+ import { UnsupportedDialectError } from './errors.js';
28
+ const RELATIONS_TABLE = 'authz_relations';
29
+ const TRIGGER_MESSAGE = 'authz_relations: un userset no puede pertenecer a otra partición que su tupla';
30
+ export function triggerDialectOf(dialect) {
31
+ if (dialect === 'sqlite3' || dialect === 'better-sqlite3')
32
+ return 'sqlite';
33
+ if (dialect === 'postgres')
34
+ return 'postgres';
35
+ if (dialect === 'mysql' || dialect === 'mysql2')
36
+ return 'mysql';
37
+ throw new UnsupportedDialectError(`relationPartitionTrigger: dialecto '${dialect}' sin observación en la suite ` +
38
+ `(hoy: PostgreSQL, MySQL 8 y SQLite). El trigger de partición defiende al escritor a mano, ` +
39
+ `y su DDL no se declara igual en dos motores: mídelo antes de dar por buena una tabla sin defensa.`);
40
+ }
41
+ /** Las sentencias a EJECUTAR (enteras) para crear el trigger de partición. */
42
+ export function relationPartitionTrigger(dialect) {
43
+ const kind = triggerDialectOf(dialect);
44
+ if (kind === 'sqlite') {
45
+ const body = (event) => `CREATE TRIGGER authz_relations_partition_b${event === 'INSERT' ? 'i' : 'u'} ` +
46
+ `BEFORE ${event} ON ${RELATIONS_TABLE} FOR EACH ROW ` +
47
+ `WHEN NEW.subject_relation IS NOT NULL AND NEW.subject_partition IS NOT NEW.partition_key ` +
48
+ `BEGIN SELECT RAISE(ABORT, '${TRIGGER_MESSAGE}'); END`;
49
+ return [body('INSERT'), body('UPDATE')];
50
+ }
51
+ if (kind === 'postgres') {
52
+ return [
53
+ `CREATE OR REPLACE FUNCTION authz_relations_partition_guard() RETURNS trigger LANGUAGE plpgsql AS $authz$ ` +
54
+ `BEGIN ` +
55
+ `IF NEW.subject_relation IS NOT NULL AND NEW.subject_partition IS DISTINCT FROM NEW.partition_key THEN ` +
56
+ `RAISE EXCEPTION '${TRIGGER_MESSAGE} (subject_partition=%, partition_key=%)', NEW.subject_partition, NEW.partition_key; ` +
57
+ `END IF; RETURN NEW; END; $authz$`,
58
+ `CREATE TRIGGER authz_relations_partition_biu BEFORE INSERT OR UPDATE ON ${RELATIONS_TABLE} ` +
59
+ `FOR EACH ROW EXECUTE FUNCTION authz_relations_partition_guard()`,
60
+ ];
61
+ }
62
+ // mysql
63
+ const body = (event) => `CREATE TRIGGER authz_relations_partition_b${event === 'INSERT' ? 'i' : 'u'} ` +
64
+ `BEFORE ${event} ON ${RELATIONS_TABLE} FOR EACH ROW ` +
65
+ `BEGIN ` +
66
+ `IF NEW.subject_relation IS NOT NULL AND NOT (NEW.subject_partition <=> NEW.partition_key) THEN ` +
67
+ `SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '${TRIGGER_MESSAGE}'; ` +
68
+ `END IF; END`;
69
+ return [body('INSERT'), body('UPDATE')];
70
+ }
71
+ /** Las sentencias para soltar el trigger (y, en PG, su función) en el `down()`. */
72
+ export function relationPartitionTriggerDrops(dialect) {
73
+ const kind = triggerDialectOf(dialect);
74
+ if (kind === 'postgres') {
75
+ return [
76
+ `DROP TRIGGER IF EXISTS authz_relations_partition_biu ON ${RELATIONS_TABLE}`,
77
+ 'DROP FUNCTION IF EXISTS authz_relations_partition_guard()',
78
+ ];
79
+ }
80
+ return [
81
+ 'DROP TRIGGER IF EXISTS authz_relations_partition_bi',
82
+ 'DROP TRIGGER IF EXISTS authz_relations_partition_bu',
83
+ ];
84
+ }
85
+ //# sourceMappingURL=relation_partition_trigger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation_partition_trigger.js","sourceRoot":"","sources":["../../src/relation_partition_trigger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD,MAAM,eAAe,GAAG,iBAAiB,CAAA;AACzC,MAAM,eAAe,GAAG,+EAA+E,CAAA;AAIvG,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,gBAAgB;QAAE,OAAO,QAAQ,CAAA;IAC1E,IAAI,OAAO,KAAK,UAAU;QAAE,OAAO,UAAU,CAAA;IAC7C,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAA;IAC/D,MAAM,IAAI,uBAAuB,CAC/B,uCAAuC,OAAO,gCAAgC;QAC5E,4FAA4F;QAC5F,mGAAmG,CACtG,CAAA;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACtC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,CAAC,KAA0B,EAAE,EAAE,CAC1C,6CAA6C,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG;YAC9E,UAAU,KAAK,OAAO,eAAe,gBAAgB;YACrD,2FAA2F;YAC3F,8BAA8B,eAAe,SAAS,CAAA;QACxD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IACzC,CAAC;IACD,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,OAAO;YACL,2GAA2G;gBACzG,QAAQ;gBACR,wGAAwG;gBACxG,oBAAoB,eAAe,sFAAsF;gBACzH,kCAAkC;YACpC,2EAA2E,eAAe,GAAG;gBAC3F,iEAAiE;SACpE,CAAA;IACH,CAAC;IACD,QAAQ;IACR,MAAM,IAAI,GAAG,CAAC,KAA0B,EAAE,EAAE,CAC1C,6CAA6C,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG;QAC9E,UAAU,KAAK,OAAO,eAAe,gBAAgB;QACrD,QAAQ;QACR,iGAAiG;QACjG,+CAA+C,eAAe,KAAK;QACnE,aAAa,CAAA;IACf,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;AACzC,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,6BAA6B,CAAC,OAAe;IAC3D,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACtC,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,OAAO;YACL,2DAA2D,eAAe,EAAE;YAC5E,2DAA2D;SAC5D,CAAA;IACH,CAAC;IACD,OAAO;QACL,qDAAqD;QACrD,qDAAqD;KACtD,CAAA;AACH,CAAC"}
@@ -0,0 +1,58 @@
1
+ /** Una relación de un tipo de objeto (`document#viewer`), con sus `includes` de un nivel. */
2
+ export interface RelationObjectRelationSpec {
3
+ /** El nombre de la relación (`owner`, `editor`, `viewer`). */
4
+ name: string;
5
+ /**
6
+ * Otras relaciones del MISMO tipo que ésta incluye (`viewer or editor`):
7
+ * un `relate(u, editor, doc)` concede también `viewer`. Un nivel, SIN
8
+ * `from` en v1 (la herencia cross-objeto metería un TTU entre tipos y
9
+ * habría que re-medir profundidad — diferido a 2.6+).
10
+ */
11
+ includes?: readonly string[];
12
+ }
13
+ /** Un tipo de objeto de relaciones (`document`, `folder`, `space`…). */
14
+ export interface RelationObjectTypeSpec {
15
+ /** El tipo FGA del objeto. */
16
+ type: string;
17
+ /** Sus relaciones, en orden de declaración. */
18
+ relations: readonly RelationObjectRelationSpec[];
19
+ }
20
+ /** Opciones específicas del driver `database`. */
21
+ export interface RelationsDatabaseOptions {
22
+ /**
23
+ * Habilita `membersOf` (membresía TRANSITIVA a través de usersets), que solo
24
+ * el driver `database` resuelve (CTE recursiva). En `openfga` la transitiva
25
+ * sería `ListUsers`, que trunca, así que la opción NO es válida fuera de
26
+ * `database`.
27
+ */
28
+ membersOf?: boolean;
29
+ }
30
+ /** La config que declara el consumidor. */
31
+ export interface RelationsConfigSpec {
32
+ /** Los tipos de objeto y sus relaciones. */
33
+ objectTypes: readonly RelationObjectTypeSpec[];
34
+ /**
35
+ * Los holder types del config del consumidor (`user`, `admin`…). Se suman a
36
+ * los tipos reservados: un tipo de objeto de relaciones no puede llamarse
37
+ * como un holder (⚪4).
38
+ */
39
+ holderTypes?: readonly string[];
40
+ /** Opciones del driver `database` (donde vive `membersOf`). */
41
+ database?: RelationsDatabaseOptions;
42
+ }
43
+ /** La config ya validada y CONGELADA que consulta el manager de relaciones. */
44
+ export interface RelationsConfig {
45
+ readonly objectTypes: readonly RelationObjectTypeSpec[];
46
+ /** ¿`membersOf` está habilitado (opción de `database`)? */
47
+ readonly membersOf: boolean;
48
+ /** ¿Existe el tipo de objeto? (F-05, cara del tipo). */
49
+ hasType(objectType: string): boolean;
50
+ /** ¿La relación está declarada para ese tipo? (F-05, cara de la relación). */
51
+ isDeclared(objectType: string, relation: string): boolean;
52
+ }
53
+ /**
54
+ * Valida y congela la config de relaciones. Config inválida ⇒ 422
55
+ * `E_AUTHZ_RELATION_CONFIG` (misma clase que el gate del modelo del lote 4-1).
56
+ */
57
+ export declare function defineRelationsConfig(spec: RelationsConfigSpec): RelationsConfig;
58
+ //# sourceMappingURL=define_relations_config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define_relations_config.d.ts","sourceRoot":"","sources":["../../../src/relations/define_relations_config.ts"],"names":[],"mappings":"AA2BA,6FAA6F;AAC7F,MAAM,WAAW,0BAA0B;IACzC,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC7B;AAED,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACrC,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,+CAA+C;IAC/C,SAAS,EAAE,SAAS,0BAA0B,EAAE,CAAA;CACjD;AAED,kDAAkD;AAClD,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAC9C;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,wBAAwB,CAAA;CACpC;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAA;IACvD,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,wDAAwD;IACxD,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IACpC,8EAA8E;IAC9E,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;CAC1D;AAMD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,CA0IhF"}