hexcore 10.2.0__tar.gz → 11.0.2__tar.gz

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 (403) hide show
  1. {hexcore-10.2.0/hexcore.egg-info → hexcore-11.0.2}/PKG-INFO +28 -5
  2. {hexcore-10.2.0 → hexcore-11.0.2}/README.md +23 -4
  3. hexcore-11.0.2/hexcore/__init__.py +35 -0
  4. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/_deprecation.py +14 -10
  5. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/__init__.py +4 -0
  6. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/__init__.pyi +3 -1
  7. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/services.py +4 -34
  8. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/context.py +43 -0
  9. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/ports.py +49 -0
  10. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/lifespan.py +40 -2
  11. hexcore-11.0.2/hexcore/darwin/plugins/drbac/__init__.py +325 -0
  12. hexcore-11.0.2/hexcore/darwin/plugins/drbac/cache.py +68 -0
  13. hexcore-11.0.2/hexcore/darwin/plugins/drbac/conditions.py +850 -0
  14. hexcore-11.0.2/hexcore/darwin/plugins/drbac/domain.py +307 -0
  15. hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/__init__.py +7 -0
  16. hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/beanie/__init__.py +5 -0
  17. hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/beanie/repository.py +351 -0
  18. hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/sqlalchemy/__init__.py +6 -0
  19. hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/sqlalchemy/models.py +81 -0
  20. hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/sqlalchemy/models_mixins.py +175 -0
  21. hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/sqlalchemy/repository.py +399 -0
  22. hexcore-11.0.2/hexcore/darwin/plugins/drbac/pdp.py +398 -0
  23. hexcore-11.0.2/hexcore/darwin/plugins/drbac/pip.py +147 -0
  24. hexcore-11.0.2/hexcore/darwin/plugins/drbac/predicates.py +136 -0
  25. hexcore-11.0.2/hexcore/darwin/plugins/drbac/provider.py +34 -0
  26. hexcore-11.0.2/hexcore/darwin/plugins/drbac/router.py +515 -0
  27. hexcore-11.0.2/hexcore/darwin/plugins/drbac/service.py +276 -0
  28. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/__init__.py +1 -1
  29. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/__init__.py +1 -1
  30. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/__init__.py +1 -1
  31. hexcore-11.0.2/hexcore/darwin/plugins/rbac/__init__.py +386 -0
  32. hexcore-11.0.2/hexcore/darwin/plugins/rbac/cache.py +145 -0
  33. hexcore-11.0.2/hexcore/darwin/plugins/rbac/cli.py +153 -0
  34. hexcore-11.0.2/hexcore/darwin/plugins/rbac/domain.py +371 -0
  35. hexcore-11.0.2/hexcore/darwin/plugins/rbac/matcher.py +95 -0
  36. hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/__init__.py +13 -0
  37. hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/beanie/__init__.py +6 -0
  38. hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/beanie/repository.py +413 -0
  39. hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/sqlalchemy/__init__.py +7 -0
  40. hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/sqlalchemy/models.py +114 -0
  41. hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/sqlalchemy/models_mixins.py +261 -0
  42. hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/sqlalchemy/repository.py +528 -0
  43. hexcore-11.0.2/hexcore/darwin/plugins/rbac/provider.py +166 -0
  44. hexcore-11.0.2/hexcore/darwin/plugins/rbac/resolver.py +99 -0
  45. hexcore-11.0.2/hexcore/darwin/plugins/rbac/router.py +305 -0
  46. hexcore-11.0.2/hexcore/darwin/plugins/rbac/service.py +468 -0
  47. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/testing/__init__.py +1 -1
  48. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/testing/helpers.py +1 -1
  49. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/events.py +0 -40
  50. hexcore-11.0.2/hexcore/infrastructure/repositories/orms/sqlalchemy/id_types.py +56 -0
  51. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/sqlalchemy/utils.py +4 -1
  52. {hexcore-10.2.0 → hexcore-11.0.2/hexcore.egg-info}/PKG-INFO +28 -5
  53. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/SOURCES.txt +41 -6
  54. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/requires.txt +6 -0
  55. {hexcore-10.2.0 → hexcore-11.0.2}/pyproject.toml +12 -1
  56. hexcore-11.0.2/tests/test_darwin_10_4_hardening.py +418 -0
  57. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_backend_neutrality.py +18 -4
  58. hexcore-11.0.2/tests/test_darwin_drbac_conditions.py +412 -0
  59. hexcore-11.0.2/tests/test_darwin_drbac_pdp.py +449 -0
  60. hexcore-11.0.2/tests/test_darwin_drbac_router.py +381 -0
  61. hexcore-11.0.2/tests/test_darwin_drbac_service.py +470 -0
  62. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_impersonate.py +2 -2
  63. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_oauth.py +2 -2
  64. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_passkey.py +2 -2
  65. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_plugin_decoupling.py +2 -0
  66. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_plugins.py +126 -0
  67. hexcore-11.0.2/tests/test_darwin_rbac.py +438 -0
  68. hexcore-11.0.2/tests/test_darwin_rbac_service.py +518 -0
  69. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_schema_registration.py +13 -0
  70. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_username.py +18 -11
  71. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_deprecations.py +104 -222
  72. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_documentation_examples.py +5 -1
  73. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_optional_dependencies.py +69 -0
  74. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_testing_kit.py +7 -7
  75. hexcore-10.2.0/hexcore/__init__.py +0 -86
  76. hexcore-10.2.0/hexcore/domain/auth/__init__.py +0 -66
  77. hexcore-10.2.0/hexcore/domain/auth/permissions.py +0 -71
  78. hexcore-10.2.0/hexcore/domain/auth/value_objects.py +0 -17
  79. hexcore-10.2.0/hexcore/infrastructure/events/events_backends/memory.py +0 -40
  80. hexcore-10.2.0/hexcore/infrastructure/repositories/__init__.py +0 -0
  81. hexcore-10.2.0/hexcore/infrastructure/repositories/orms/__init__.py +0 -0
  82. {hexcore-10.2.0 → hexcore-11.0.2}/LICENSE +0 -0
  83. {hexcore-10.2.0 → hexcore-11.0.2}/MANIFEST.in +0 -0
  84. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/__main__.py +0 -0
  85. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/__init__.py +0 -0
  86. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/__init__.py +0 -0
  87. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/adapters.py +0 -0
  88. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/config.py +0 -0
  89. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/factory.py +0 -0
  90. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/in_memory_buses.py +0 -0
  91. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/pipeline.py +0 -0
  92. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/registry.py +0 -0
  93. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/scheduler.py +0 -0
  94. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/__init__.py +0 -0
  95. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/base.py +0 -0
  96. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/cursor.py +0 -0
  97. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/errors.py +0 -0
  98. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/query.py +0 -0
  99. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/__init__.py +0 -0
  100. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/config.py +0 -0
  101. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/factory.py +0 -0
  102. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/projector.py +0 -0
  103. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/relay.py +0 -0
  104. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/repository.py +0 -0
  105. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/use_cases/__init__.py +0 -0
  106. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/use_cases/base.py +0 -0
  107. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/use_cases/query.py +0 -0
  108. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/capabilities.py +0 -0
  109. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/config.py +0 -0
  110. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/cqrs.py +0 -0
  111. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/cqrs.pyi +0 -0
  112. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/__init__.py +0 -0
  113. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/authorization.py +0 -0
  114. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/authz_middleware.py +0 -0
  115. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/commands.py +0 -0
  116. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/config.py +0 -0
  117. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/container.py +0 -0
  118. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/hooks.py +0 -0
  119. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/plugins.py +0 -0
  120. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/__init__.py +0 -0
  121. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/authorization.py +0 -0
  122. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/entities.py +0 -0
  123. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/events.py +0 -0
  124. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/exceptions.py +0 -0
  125. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/permissions.py +0 -0
  126. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/plugins.py +0 -0
  127. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/value_objects.py +0 -0
  128. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/__init__.py +0 -0
  129. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/__init__.py +0 -0
  130. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/authorization.py +0 -0
  131. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/dependencies.py +0 -0
  132. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/middlewares.py +0 -0
  133. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/routers.py +0 -0
  134. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/cli.py +0 -0
  135. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/clock.py +0 -0
  136. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/envelope.py +0 -0
  137. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/hashing.py +0 -0
  138. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/keys.py +0 -0
  139. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/__init__.py +0 -0
  140. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/beanie/__init__.py +0 -0
  141. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/beanie/documents.py +0 -0
  142. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/beanie/repositories.py +0 -0
  143. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/beanie/schema.py +0 -0
  144. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/selection.py +0 -0
  145. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/__init__.py +0 -0
  146. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/models.py +0 -0
  147. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/models_mixins.py +0 -0
  148. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/registry.py +0 -0
  149. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/repositories.py +0 -0
  150. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/schema.py +0 -0
  151. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/revocation.py +0 -0
  152. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/secretbox.py +0 -0
  153. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/tokens.py +0 -0
  154. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/transports.py +0 -0
  155. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/__init__.py +0 -0
  156. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/commands.py +0 -0
  157. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/domain.py +0 -0
  158. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/router.py +0 -0
  159. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/service.py +0 -0
  160. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/magic_link/__init__.py +0 -0
  161. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/magic_link/commands.py +0 -0
  162. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/magic_link/router.py +0 -0
  163. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/domain.py +0 -0
  164. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/http.py +0 -0
  165. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/__init__.py +0 -0
  166. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/beanie/__init__.py +0 -0
  167. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/beanie/repository.py +0 -0
  168. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/sqlalchemy/__init__.py +0 -0
  169. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/sqlalchemy/models.py +0 -0
  170. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/sqlalchemy/models_mixins.py +0 -0
  171. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/sqlalchemy/repository.py +0 -0
  172. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/providers.py +0 -0
  173. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/router.py +0 -0
  174. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/service.py +0 -0
  175. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/__init__.py +0 -0
  176. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/domain.py +0 -0
  177. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/__init__.py +0 -0
  178. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/beanie/__init__.py +0 -0
  179. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/beanie/repository.py +0 -0
  180. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/sqlalchemy/__init__.py +0 -0
  181. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/sqlalchemy/models.py +0 -0
  182. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/sqlalchemy/models_mixins.py +0 -0
  183. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/sqlalchemy/repository.py +0 -0
  184. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/router.py +0 -0
  185. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/service.py +0 -0
  186. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/domain.py +0 -0
  187. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/__init__.py +0 -0
  188. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/beanie/__init__.py +0 -0
  189. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/beanie/repository.py +0 -0
  190. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/sqlalchemy/__init__.py +0 -0
  191. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/sqlalchemy/models.py +0 -0
  192. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/sqlalchemy/models_mixins.py +0 -0
  193. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/sqlalchemy/repository.py +0 -0
  194. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/router.py +0 -0
  195. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/service.py +0 -0
  196. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/webauthn_adapter.py +0 -0
  197. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/storage.py +0 -0
  198. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/__init__.py +0 -0
  199. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/commands.py +0 -0
  200. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/crypto.py +0 -0
  201. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/domain.py +0 -0
  202. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/__init__.py +0 -0
  203. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/beanie/__init__.py +0 -0
  204. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/beanie/repository.py +0 -0
  205. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/__init__.py +0 -0
  206. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/models.py +0 -0
  207. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/models_mixins.py +0 -0
  208. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/repository.py +0 -0
  209. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/router.py +0 -0
  210. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/service.py +0 -0
  211. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/totp.py +0 -0
  212. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/testing/fakes.py +0 -0
  213. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/testing/fixtures.py +0 -0
  214. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/__init__.py +0 -0
  215. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/base.py +0 -0
  216. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/__init__.py +0 -0
  217. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/buses.py +0 -0
  218. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/commands.py +0 -0
  219. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/context.py +0 -0
  220. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/cron.py +0 -0
  221. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/decorators.py +0 -0
  222. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/dispatch.py +0 -0
  223. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/envelope.py +0 -0
  224. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/exceptions.py +0 -0
  225. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/handlers.py +0 -0
  226. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/middleware.py +0 -0
  227. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/queries.py +0 -0
  228. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/resolution.py +0 -0
  229. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/serializer.py +0 -0
  230. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/task_queues.py +0 -0
  231. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/__init__.py +0 -0
  232. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/aggregate.py +0 -0
  233. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/exceptions.py +0 -0
  234. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/projections.py +0 -0
  235. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/snapshots.py +0 -0
  236. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/store.py +0 -0
  237. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/stored.py +0 -0
  238. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/exceptions.py +0 -0
  239. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/repositories.py +0 -0
  240. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/services.py +0 -0
  241. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/uow.py +0 -0
  242. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/eventsourcing.py +0 -0
  243. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/eventsourcing.pyi +0 -0
  244. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/fastapi.py +0 -0
  245. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/fastapi.pyi +0 -0
  246. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/__init__.py +0 -0
  247. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/__init__.py +0 -0
  248. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/app.py +0 -0
  249. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/cqrs.py +0 -0
  250. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/eventsourcing.py +0 -0
  251. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/exception_handlers.py +0 -0
  252. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/health.py +0 -0
  253. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/lifespan.py +0 -0
  254. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/middlewares.py +0 -0
  255. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/rate_limit.py +0 -0
  256. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/routing.py +0 -0
  257. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/streaming.py +0 -0
  258. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/utils.py +0 -0
  259. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cache/__init__.py +0 -0
  260. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cache/cache_backends/__init__.py +0 -0
  261. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cache/cache_backends/memory.py +0 -0
  262. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cache/cache_backends/redis.py +0 -0
  263. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cli.py +0 -0
  264. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/__init__.py +0 -0
  265. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/cron_sql.py +0 -0
  266. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/middlewares.py +0 -0
  267. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/postgres_bus.py +0 -0
  268. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/postgres_lock.py +0 -0
  269. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/procrastinate.py +0 -0
  270. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/pydantic_serializer.py +0 -0
  271. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/rabbitmq.py +0 -0
  272. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/redis_bus.py +0 -0
  273. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/redis_lock.py +0 -0
  274. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/__init__.py +0 -0
  275. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/beanie_documents.py +0 -0
  276. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/beanie_store.py +0 -0
  277. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/memory.py +0 -0
  278. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/redis_store.py +0 -0
  279. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/sqlalchemy_models.py +0 -0
  280. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/sqlalchemy_models_mixins.py +0 -0
  281. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/sqlalchemy_store.py +0 -0
  282. {hexcore-10.2.0/hexcore/infrastructure/events → hexcore-11.0.2/hexcore/infrastructure/repositories}/__init__.py +0 -0
  283. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/_beanie_impl.py +0 -0
  284. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/_sqlalchemy_impl.py +0 -0
  285. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/base.py +0 -0
  286. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/decorators.py +0 -0
  287. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/implementations.py +0 -0
  288. {hexcore-10.2.0/hexcore/infrastructure/events/events_backends → hexcore-11.0.2/hexcore/infrastructure/repositories/orms}/__init__.py +0 -0
  289. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/beanie/__init__.py +0 -0
  290. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/beanie/utils.py +0 -0
  291. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/sqlalchemy/__init__.py +0 -0
  292. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/sqlalchemy/session.py +0 -0
  293. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/utils.py +0 -0
  294. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/task_queues/__init__.py +0 -0
  295. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/task_queues/celery_adapter.py +0 -0
  296. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/task_queues/procrastinate_adapter.py +0 -0
  297. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/uow/__init__.py +0 -0
  298. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/uow/decorators.py +0 -0
  299. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/uow/helpers.py +0 -0
  300. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/uow/scopes.py +0 -0
  301. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/workers/__init__.py +0 -0
  302. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/workers/consumer.py +0 -0
  303. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/workers/rabbitmq_worker.py +0 -0
  304. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/workers/runner.py +0 -0
  305. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/py.typed +0 -0
  306. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/sql.py +0 -0
  307. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/sql.pyi +0 -0
  308. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/__init__.py +0 -0
  309. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/fakes.py +0 -0
  310. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/fixtures.py +0 -0
  311. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/helpers.py +0 -0
  312. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/repositories.py +0 -0
  313. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/types.py +0 -0
  314. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/dependency_links.txt +0 -0
  315. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/entry_points.txt +0 -0
  316. {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/top_level.txt +0 -0
  317. {hexcore-10.2.0 → hexcore-11.0.2}/setup.cfg +0 -0
  318. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_alembic_metadata_completeness.py +0 -0
  319. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_anclas_del_repo.py +0 -0
  320. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_app_and_lifespan.py +0 -0
  321. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_cqrs_providers.py +0 -0
  322. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_exception_handlers.py +0 -0
  323. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_health.py +0 -0
  324. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_middlewares_and_routing.py +0 -0
  325. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_rate_limit.py +0 -0
  326. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_streaming.py +0 -0
  327. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_basic.py +0 -0
  328. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_beanie_query_utils.py +0 -0
  329. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_celery_event_loop.py +0 -0
  330. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_config_cors_security.py +0 -0
  331. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_config_loading.py +0 -0
  332. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_consumer_optional_event_bus.py +0 -0
  333. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cqrs.py +0 -0
  334. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cqrs_envelope.py +0 -0
  335. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cqrs_factory.py +0 -0
  336. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cqrs_middlewares.py +0 -0
  337. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cron_sql.py +0 -0
  338. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_authorization_engine.py +0 -0
  339. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_authorization_http.py +0 -0
  340. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_beanie.py +0 -0
  341. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_cli.py +0 -0
  342. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_container.py +0 -0
  343. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_context.py +0 -0
  344. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_custom_plugin.py +0 -0
  345. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_envelope.py +0 -0
  346. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_facade_and_events.py +0 -0
  347. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_flows.py +0 -0
  348. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_hashing.py +0 -0
  349. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_http.py +0 -0
  350. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_magic_link.py +0 -0
  351. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_models.py +0 -0
  352. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_openapi.py +0 -0
  353. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_organization.py +0 -0
  354. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_permissions.py +0 -0
  355. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_principals.py +0 -0
  356. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_production_defaults.py +0 -0
  357. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_repositories.py +0 -0
  358. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_revocation.py +0 -0
  359. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_storage_selection.py +0 -0
  360. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_tokens.py +0 -0
  361. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_two_factor.py +0 -0
  362. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_value_objects.py +0 -0
  363. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_domain_base_contract.py +0 -0
  364. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_domain_service_query.py +0 -0
  365. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_dotted_resolution.py +0 -0
  366. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_event_dispatch_mro.py +0 -0
  367. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_aggregate.py +0 -0
  368. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_beanie.py +0 -0
  369. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_config.py +0 -0
  370. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_ports.py +0 -0
  371. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_projections.py +0 -0
  372. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_redis.py +0 -0
  373. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_relay.py +0 -0
  374. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_repository.py +0 -0
  375. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_snapshot_checkpoint.py +0 -0
  376. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_sql_schema.py +0 -0
  377. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_store_contract.py +0 -0
  378. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_uow_integration.py +0 -0
  379. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_facades.py +0 -0
  380. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_handler_registry.py +0 -0
  381. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_infrastructure_query_path.py +0 -0
  382. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_lock_error_policy.py +0 -0
  383. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_packaging.py +0 -0
  384. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_postgres_bus.py +0 -0
  385. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_postgres_lock.py +0 -0
  386. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_query_cursor_and_endpoint.py +0 -0
  387. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_query_field_validation.py +0 -0
  388. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_rabbitmq_bus.py +0 -0
  389. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_redis_bus.py +0 -0
  390. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_redis_lock.py +0 -0
  391. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_repositories_utils.py +0 -0
  392. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_scheduler.py +0 -0
  393. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_scheduler_catchup.py +0 -0
  394. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_smart_routing.py +0 -0
  395. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_sql_naming_convention.py +0 -0
  396. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_sql_session_layer.py +0 -0
  397. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_task_queues_adapters.py +0 -0
  398. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_testing_utilities.py +0 -0
  399. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_typing_gate.py +0 -0
  400. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_uow_session_regression.py +0 -0
  401. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_use_cases_query.py +0 -0
  402. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_worker_bus_integration.py +0 -0
  403. {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_worker_runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hexcore
3
- Version: 10.2.0
3
+ Version: 11.0.2
4
4
  Summary: Reusable core for Python projects with hexagonal architecture, DDD, CQRS and background tasks. Ships the abstractions and the infrastructure: SQL session layer, FastAPI factories, worker runner, dynamic cron and identity.
5
5
  Author-email: "David Latosefki (Indroic)" <indroic@outlook.com>
6
6
  License-Expression: MIT
@@ -71,6 +71,10 @@ Requires-Dist: hexcore[darwin]; extra == "darwin-passkey"
71
71
  Requires-Dist: webauthn>=2.0.0; extra == "darwin-passkey"
72
72
  Provides-Extra: darwin-organization
73
73
  Requires-Dist: hexcore[darwin]; extra == "darwin-organization"
74
+ Provides-Extra: darwin-rbac
75
+ Requires-Dist: hexcore[darwin]; extra == "darwin-rbac"
76
+ Provides-Extra: darwin-drbac
77
+ Requires-Dist: hexcore[darwin]; extra == "darwin-drbac"
74
78
  Provides-Extra: all
75
79
  Requires-Dist: fastapi>=0.116.1; extra == "all"
76
80
  Requires-Dist: redis>=6.4.0; extra == "all"
@@ -278,8 +282,9 @@ Both generate a root `config.py` and leave Alembic configured. See
278
282
 
279
283
  | Series | Status | What it means |
280
284
  | :-- | :-- | :-- |
281
- | **10.x** | ✅ **Active** | The only supported one. Receives features and fixes. Darwin gains username sign-in, an optional email, a resolver for roles and scopes, a persisted key store, and startup checks that refuse the development defaults in production. |
282
- | **9.x** | ⛔ **Deprecated** | Adds the event store and Event Sourcing, and leaves a single event bus port. Migrating to 10.x is mechanical: `sign_in(email=...)` still resolves and warns, and the sign-in body still accepts `email`. The schema change is not: see the storage guide. |
285
+ | **11.x** | ✅ **Active** | The only supported one. Receives features and fixes. Removes everything 11.0 had promised to remove — see the table below — and fixes the plugin startup steps that broke boot. |
286
+ | **10.x** | ⛔ **Deprecated** | Darwin gains username sign-in, an optional email, a resolver for roles and scopes, a persisted key store, and startup checks that refuse the development defaults in production. Migrating to 11.x means dropping the names removed there; the deprecation warnings named each replacement. |
287
+ | **9.x** | ⛔ **Deprecated** | Adds the event store and Event Sourcing, and leaves a single event bus port. The schema change is not mechanical: see the storage guide. |
283
288
  | **8.x** | ⛔ **Deprecated** | Ships Darwin. Migrating to 9.x is mechanical: the two deprecated names still resolve and warn. |
284
289
  | **7.x** | ⛔ **Deprecated** | Removes the pre-5.0 surface and fixes the CORS and rate-limiting defects. No Darwin: it shipped before the module landed on `master`. |
285
290
  | **6.x** | ⛔ **Deprecated** | No longer receives fixes. Contains the CORS and rate-limiting security defects fixed in 7.0, and the pre-5.0 aliases still present. |
@@ -305,8 +310,8 @@ The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — an
305
310
  | `ICommandHandler`, `IQueryHandler` | `AbstractCommandHandler`, `AbstractQueryHandler` |
306
311
  | `IMiddleware` | `AbstractMiddleware` |
307
312
  | `ISerializer` | `AbstractSerializer` |
308
- | `IEventDispatcher` | `EventBus` |
309
- | `EventBus.register()` / `.dispatch()` | `EventBus.subscribe()` / `.publish()` |
313
+ | `IEventDispatcher` | `AbstractEventBus` |
314
+ | `EventBus.register()` / `.dispatch()` | `AbstractEventBus.subscribe()` / `.publish()` |
310
315
  | `ServerConfig.event_dispatcher` | `ServerConfig.event_bus` |
311
316
  | `SQLAlchemyCommonImplementationsRepo` | `SqlAlchemyRepository` |
312
317
  | `BeanieODMCommonImplementationsRepo` | `BeanieRepository` |
@@ -314,6 +319,24 @@ The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — an
314
319
  | `reset_sqlalchemy_engine()` | `dispose_engine()` |
315
320
  | `MiddlewareConfig` | **Removed in 3.0.** It was dead code: never read. |
316
321
 
322
+ The 9.0 and 10.0 deprecations were removed in 11.0, on the schedule each warning announced.
323
+ The replacement is mechanical in every case: the old name kept working, and warned, for a full
324
+ major.
325
+
326
+ | Removed in 11.0 | Use instead | Deprecated since |
327
+ | :-- | :-- | :-- |
328
+ | `hexcore.domain.events.EventBus` | `hexcore.domain.cqrs.buses.AbstractEventBus` | 9.0 |
329
+ | `hexcore.infrastructure.events.events_backends.memory.InMemoryEventBus` | `hexcore.cqrs.InMemoryEventBus` | 9.0 |
330
+ | `hexcore.domain.auth` (the whole package) | `hexcore.darwin` | 10.0 |
331
+ | `hexcore.domain.auth.PermissionsRegistry`, `hexcore.PermissionsRegistry` | `hexcore.darwin.RoleRegistry` | 10.0 |
332
+ | `hexcore.domain.auth.TokenClaims`, `hexcore.TokenClaims` | `hexcore.darwin.AccessTokenClaims` | 10.0 |
333
+ | `IdentityService.sign_in(email=...)` | `IdentityService.sign_in(identifier=...)` | 10.0 |
334
+
335
+ `TokenClaims` and `AccessTokenClaims` were never interchangeable — different fields, different
336
+ invariants, and `TokenClaims` had no `sid`, so a session issued with it could not be revoked.
337
+ That is why the old name returned the old object and warned instead of aliasing to the new one,
338
+ and it is why porting is a rewrite of the claims you build, not a rename.
339
+
317
340
  Passing `event_dispatcher=` to `ServerConfig` **fails with an error that says what to use**,
318
341
  rather than being silently ignored: pydantic discards keyword arguments it does not know, and
319
342
  keeping the default bus without noticing would surface much later as "my events never arrive".
@@ -187,8 +187,9 @@ Both generate a root `config.py` and leave Alembic configured. See
187
187
 
188
188
  | Series | Status | What it means |
189
189
  | :-- | :-- | :-- |
190
- | **10.x** | ✅ **Active** | The only supported one. Receives features and fixes. Darwin gains username sign-in, an optional email, a resolver for roles and scopes, a persisted key store, and startup checks that refuse the development defaults in production. |
191
- | **9.x** | ⛔ **Deprecated** | Adds the event store and Event Sourcing, and leaves a single event bus port. Migrating to 10.x is mechanical: `sign_in(email=...)` still resolves and warns, and the sign-in body still accepts `email`. The schema change is not: see the storage guide. |
190
+ | **11.x** | ✅ **Active** | The only supported one. Receives features and fixes. Removes everything 11.0 had promised to remove — see the table below — and fixes the plugin startup steps that broke boot. |
191
+ | **10.x** | ⛔ **Deprecated** | Darwin gains username sign-in, an optional email, a resolver for roles and scopes, a persisted key store, and startup checks that refuse the development defaults in production. Migrating to 11.x means dropping the names removed there; the deprecation warnings named each replacement. |
192
+ | **9.x** | ⛔ **Deprecated** | Adds the event store and Event Sourcing, and leaves a single event bus port. The schema change is not mechanical: see the storage guide. |
192
193
  | **8.x** | ⛔ **Deprecated** | Ships Darwin. Migrating to 9.x is mechanical: the two deprecated names still resolve and warn. |
193
194
  | **7.x** | ⛔ **Deprecated** | Removes the pre-5.0 surface and fixes the CORS and rate-limiting defects. No Darwin: it shipped before the module landed on `master`. |
194
195
  | **6.x** | ⛔ **Deprecated** | No longer receives fixes. Contains the CORS and rate-limiting security defects fixed in 7.0, and the pre-5.0 aliases still present. |
@@ -214,8 +215,8 @@ The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — an
214
215
  | `ICommandHandler`, `IQueryHandler` | `AbstractCommandHandler`, `AbstractQueryHandler` |
215
216
  | `IMiddleware` | `AbstractMiddleware` |
216
217
  | `ISerializer` | `AbstractSerializer` |
217
- | `IEventDispatcher` | `EventBus` |
218
- | `EventBus.register()` / `.dispatch()` | `EventBus.subscribe()` / `.publish()` |
218
+ | `IEventDispatcher` | `AbstractEventBus` |
219
+ | `EventBus.register()` / `.dispatch()` | `AbstractEventBus.subscribe()` / `.publish()` |
219
220
  | `ServerConfig.event_dispatcher` | `ServerConfig.event_bus` |
220
221
  | `SQLAlchemyCommonImplementationsRepo` | `SqlAlchemyRepository` |
221
222
  | `BeanieODMCommonImplementationsRepo` | `BeanieRepository` |
@@ -223,6 +224,24 @@ The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — an
223
224
  | `reset_sqlalchemy_engine()` | `dispose_engine()` |
224
225
  | `MiddlewareConfig` | **Removed in 3.0.** It was dead code: never read. |
225
226
 
227
+ The 9.0 and 10.0 deprecations were removed in 11.0, on the schedule each warning announced.
228
+ The replacement is mechanical in every case: the old name kept working, and warned, for a full
229
+ major.
230
+
231
+ | Removed in 11.0 | Use instead | Deprecated since |
232
+ | :-- | :-- | :-- |
233
+ | `hexcore.domain.events.EventBus` | `hexcore.domain.cqrs.buses.AbstractEventBus` | 9.0 |
234
+ | `hexcore.infrastructure.events.events_backends.memory.InMemoryEventBus` | `hexcore.cqrs.InMemoryEventBus` | 9.0 |
235
+ | `hexcore.domain.auth` (the whole package) | `hexcore.darwin` | 10.0 |
236
+ | `hexcore.domain.auth.PermissionsRegistry`, `hexcore.PermissionsRegistry` | `hexcore.darwin.RoleRegistry` | 10.0 |
237
+ | `hexcore.domain.auth.TokenClaims`, `hexcore.TokenClaims` | `hexcore.darwin.AccessTokenClaims` | 10.0 |
238
+ | `IdentityService.sign_in(email=...)` | `IdentityService.sign_in(identifier=...)` | 10.0 |
239
+
240
+ `TokenClaims` and `AccessTokenClaims` were never interchangeable — different fields, different
241
+ invariants, and `TokenClaims` had no `sid`, so a session issued with it could not be revoked.
242
+ That is why the old name returned the old object and warned instead of aliasing to the new one,
243
+ and it is why porting is a rewrite of the claims you build, not a rename.
244
+
226
245
  Passing `event_dispatcher=` to `ServerConfig` **fails with an error that says what to use**,
227
246
  rather than being silently ignored: pydantic discards keyword arguments it does not know, and
228
247
  keeping the default bus without noticing would surface much later as "my events never arrive".
@@ -0,0 +1,35 @@
1
+ """
2
+ Euphoria Kernel Core
3
+ Submódulo principal con entidades, eventos y repositorios.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ from .domain.base import BaseEntity
8
+ from .domain.events import (
9
+ DomainEvent,
10
+ EntityCreatedEvent,
11
+ EntityDeletedEvent,
12
+ EntityUpdatedEvent,
13
+ )
14
+ from .domain.repositories import IBaseRepository
15
+ from .infrastructure.repositories.base import (
16
+ BaseSQLAlchemyRepository,
17
+ )
18
+ from .infrastructure import cli
19
+ from .infrastructure import cache
20
+ from .application.dtos.base import DTO
21
+ from . import config
22
+
23
+ __all__ = [
24
+ "BaseEntity",
25
+ "DTO",
26
+ "DomainEvent",
27
+ "EntityCreatedEvent",
28
+ "EntityDeletedEvent",
29
+ "EntityUpdatedEvent",
30
+ "IBaseRepository",
31
+ "BaseSQLAlchemyRepository",
32
+ "cli",
33
+ "cache",
34
+ "config",
35
+ ]
@@ -3,8 +3,10 @@ Mecanismo de deprecación de HexCore.
3
3
 
4
4
  Los alias anteriores a 5.0 (`ICommandBus`, `ISerializer`, `NoSqlUnitOfWork`, …) **se
5
5
  eliminaron en 7.0**: estaban deprecados desde 5.0, o sea dos majors de aviso. Este módulo
6
- queda como el mecanismo, no como su inventario — lo usa lo que se deprece de acá en adelante,
7
- empezando por `hexcore.domain.auth`, que Darwin reemplaza.
6
+ queda como el mecanismo, no como su inventario — lo usa lo que se deprece de acá en adelante.
7
+ En 11.0 se eliminó la tanda que vencía ahí (`hexcore.domain.auth`, los dos buses de eventos
8
+ viejos y `sign_in(email=...)`), así que hoy el inventario está vacío: el módulo es el mecanismo
9
+ listo para la próxima deprecación.
8
10
 
9
11
  Un alias declarado como `ICommandBus = AbstractCommandBus` **no puede avisar**: es una
10
12
  asignación, y leerlo no ejecuta nada. Por eso el aviso se implementa con `__getattr__` de
@@ -45,14 +47,16 @@ __all__ = [
45
47
  #: En 7.0 los alias pre-5.0 **se eliminaron de verdad**. La constante apunta siempre al
46
48
  #: próximo major por publicar, y por eso se corre con cada major en vez de quedarse fija.
47
49
  #:
48
- #: Con 9.0 pasa a **10.0**, y esta vez la fecha no está vacía: 9.0 depreca
49
- #: `hexcore.domain.events.EventBus` y el `InMemoryEventBus` de `infrastructure.events`, que
50
- #: son los dos nombres que esperan esa remoción. Un major completo de aviso.
50
+ #: En 11.0 se eliminó lo que prometía irse en 11.0, que es lo que mantiene honesta a la
51
+ #: constante: `hexcore.domain.events.EventBus` y el `InMemoryEventBus` de
52
+ #: `infrastructure.events` (deprecados en 9.0), `hexcore.domain.auth` entero con
53
+ #: `PermissionsRegistry` y `TokenClaims`, y el alias `sign_in(email=...)` (deprecado en 10.0).
54
+ #: El bump a 11.0.0 los dejó pasar, y los dos tests de abajo fueron los que lo cazaron.
51
55
  #:
52
56
  #: Lo vigila `test_removed_in_is_ahead_of_the_published_version`: si un bump vuelve a alcanzar
53
57
  #: este valor, el fallo salta en CI y no en el aviso que lee el usuario. Ese test es el que
54
58
  #: convierte "se nos pasó" en "no se puede releasear".
55
- REMOVED_IN = "11.0"
59
+ REMOVED_IN = "12.0"
56
60
 
57
61
 
58
62
  def warn_deprecated(
@@ -135,10 +139,10 @@ def deprecated_lazy_names(
135
139
 
136
140
  La diferencia con `deprecated_aliases`, que es la razón de que existan las dos: `deprecated_aliases`
137
141
  resuelve el alias al **reemplazo** —sirve cuando los dos nombres apuntan a lo mismo— y esto
138
- devuelve lo viejo, que sigue existiendo con su propia forma. Es el caso de
139
- `hexcore.domain.auth`: `TokenClaims` y `AccessTokenClaims` **no** son intercambiables (distintos
140
- campos, distintos invariantes), así que aliasarlos rompería a quien todavía use el viejo. Lo que
141
- hace falta es que siga funcionando **y avise**.
142
+ devuelve lo viejo, que sigue existiendo con su propia forma. Fue el caso de
143
+ `hexcore.domain.auth` hasta que se eliminó en 11.0: `TokenClaims` y `AccessTokenClaims` **no**
144
+ eran intercambiables (distintos campos, distintos invariantes), así que aliasarlos habría roto
145
+ a quien todavía usaba el viejo. Lo que hacía falta era que siguiera funcionando **y avisara**.
142
146
 
143
147
  Y perezoso porque el objeto viejo puede vivir en un módulo que no se quiere importar en el
144
148
  arranque: el `from` eager es justamente lo que se está sacando.
@@ -90,6 +90,10 @@ _EXPORTS: dict[str, tuple[str, str]] = {
90
90
  "hexcore.darwin.domain.ports",
91
91
  "NullPrincipalResolver",
92
92
  ),
93
+ "CompositePrincipalResolver": (
94
+ "hexcore.darwin.domain.ports",
95
+ "CompositePrincipalResolver",
96
+ ),
93
97
  "ResolvedPrincipal": ("hexcore.darwin.domain.ports", "ResolvedPrincipal"),
94
98
  "AbstractSessionRepository": (
95
99
  "hexcore.darwin.domain.ports",
@@ -9,7 +9,7 @@
9
9
  #
10
10
  # Existe porque la fachada resuelve sus exports con `__getattr__` y declara
11
11
  # `__all__ = sorted(_EXPORTS)`: las dos son expresiones de runtime, así que sin este stub
12
- # los 214 símbolos de `hexcore.darwin` tipan `Any`. El runtime no cambia — Python usa
12
+ # los 215 símbolos de `hexcore.darwin` tipan `Any`. El runtime no cambia — Python usa
13
13
  # el `.py` y el checker usa el `.pyi`, así que la carga perezosa se mantiene.
14
14
 
15
15
 
@@ -128,6 +128,7 @@ from hexcore.darwin.domain.ports import AbstractRevocationList as AbstractRevoca
128
128
  from hexcore.darwin.domain.ports import AbstractSessionRepository as AbstractSessionRepository
129
129
  from hexcore.darwin.domain.ports import AbstractUserRepository as AbstractUserRepository
130
130
  from hexcore.darwin.domain.ports import AbstractVerificationRepository as AbstractVerificationRepository
131
+ from hexcore.darwin.domain.ports import CompositePrincipalResolver as CompositePrincipalResolver
131
132
  from hexcore.darwin.domain.ports import NullPrincipalResolver as NullPrincipalResolver
132
133
  from hexcore.darwin.domain.ports import ResolvedPrincipal as ResolvedPrincipal
133
134
  from hexcore.darwin.domain.value_objects import AccessTokenClaims as AccessTokenClaims
@@ -270,6 +271,7 @@ __all__ = [
270
271
  "CacheErrorPolicy",
271
272
  "CacheRevocationList",
272
273
  "ChangePassword",
274
+ "CompositePrincipalResolver",
273
275
  "CookieConfig",
274
276
  "CookieTransport",
275
277
  "CoreVerificationPurpose",
@@ -798,34 +798,6 @@ class IdentityService:
798
798
  )
799
799
  return usuario, codigo
800
800
 
801
- def _resolver_alias_de_identificador(
802
- self, identifier: str | None, email: str | None
803
- ) -> str:
804
- """
805
- Acepta `email=` como alias deprecado de `identifier=`.
806
-
807
- El parámetro se llamaba `email` hasta 10.0, y renombrarlo sin más rompería en silencio
808
- a todo el que llame al servicio por keyword — que es la forma en que el servicio se
809
- llama, porque la firma es keyword-only.
810
- """
811
- if identifier is not None and email is not None:
812
- raise ValueError(
813
- "Se pasaron `identifier` y `email` a la vez. `email` es el nombre viejo del "
814
- "mismo parámetro: usá sólo `identifier`."
815
- )
816
- if identifier is not None:
817
- return identifier
818
- if email is not None:
819
- from hexcore._deprecation import warn_deprecated
820
-
821
- warn_deprecated(
822
- "IdentityService.sign_in(email=...)",
823
- "IdentityService.sign_in(identifier=...)",
824
- since="10.0",
825
- )
826
- return email
827
- raise ValueError("Falta el identificador: `sign_in(identifier=..., password=...)`.")
828
-
829
801
  async def _buscar_por_identificador(self, identificador: str) -> User | None:
830
802
  """
831
803
  Busca al usuario por lo que la configuración habilite.
@@ -930,20 +902,19 @@ class IdentityService:
930
902
  async def sign_in(
931
903
  self,
932
904
  *,
933
- identifier: str | None = None,
905
+ identifier: str,
934
906
  password: str,
935
907
  transport: Transport = "cookie",
936
908
  ip_address: str | None = None,
937
909
  user_agent: str | None = None,
938
910
  scopes: t.Iterable[str] | None = None,
939
- email: str | None = None,
940
911
  ) -> tuple[User, IdentitySession, TokenPair]:
941
912
  """
942
913
  Autentica con credencial local y crea la sesión.
943
914
 
944
915
  `identifier` es el mail o el nombre de usuario, según lo que habilite
945
- `IdentityConfig.sign_in_identifiers`. `email=` se acepta como alias deprecado del
946
- parámetro viejo, para que el código de 9.x siga compilando.
916
+ `IdentityConfig.sign_in_identifiers`. El alias `email=`, deprecado en 10.0, se
917
+ **eliminó en 11.0**.
947
918
 
948
919
  **El orden de los chequeos es deliberado y es la parte que importa.** Primero se resuelve
949
920
  la credencial y se verifica la contraseña —hasheando un señuelo si no hay fila— y sólo
@@ -962,8 +933,7 @@ class IdentityService:
962
933
  mismo error para los dos**, y con el mismo tiempo de respuesta.
963
934
  AccountLockedError, EmailNotVerifiedError: sólo tras validar la contraseña.
964
935
  """
965
- identificador = self._resolver_alias_de_identificador(identifier, email)
966
- usuario = await self._buscar_por_identificador(identificador)
936
+ usuario = await self._buscar_por_identificador(identifier)
967
937
 
968
938
  credencial = (
969
939
  await self._accounts.get_credential(usuario.id) if usuario else None
@@ -226,6 +226,49 @@ class AuthContext(BaseModel, t.Generic[TUser]):
226
226
 
227
227
  return self
228
228
 
229
+ # ── Callers externos a Darwin ─────────────────────────────────────────────
230
+ @classmethod
231
+ def external(
232
+ cls,
233
+ user_id: UUID,
234
+ *,
235
+ roles: t.Iterable[str] = (),
236
+ scopes: t.Iterable[str] = (),
237
+ status: str | None = None,
238
+ transport: Transport = "bearer",
239
+ ) -> "AuthContext[t.Any]":
240
+ """
241
+ Un `AuthContext` para un caller externo a Darwin (HC-21).
242
+
243
+ `AccessRequest.context` exige un `AuthContext`, y hasta acá la única forma de tener uno
244
+ era un `Principal` de Darwin real —con su `session_id`, resuelto por
245
+ `AbstractPrincipalResolver`—. Un token de **otro** sistema de identidad —el caso que
246
+ motiva esto es la APK de redv2, que se queda en Better Auth mientras la web migra a
247
+ Darwin— no tiene nada de eso, y no había forma de que ese caller pasara por
248
+ `AuthorizationEngine.decide()` sin fabricar una sesión Darwin que no existe.
249
+
250
+ `actor` y `subject` son el mismo `Principal`, sin `session_id` (no hay sesión Darwin
251
+ que revocar) y sin `impersonation` (un caller externo no tiene cómo impersonar *dentro*
252
+ de Darwin — esa noción no existe para él). `transport` queda auditado como lo que
253
+ realmente es: por defecto `"bearer"`, pasable si el caller usa otro transporte.
254
+
255
+ Uso::
256
+
257
+ contexto = AuthContext.external(
258
+ UUID(claims["sub"]), roles=claims["roles"], scopes=claims["permissions"]
259
+ )
260
+ decision = await engine.decide(
261
+ AccessRequest(context=contexto, action="invoice.approve", resource=recurso)
262
+ )
263
+ """
264
+ principal = Principal(
265
+ user_id=user_id,
266
+ roles=frozenset(roles),
267
+ scopes=frozenset(scopes),
268
+ status=status,
269
+ )
270
+ return cls(actor=principal, subject=principal, transport=transport)
271
+
229
272
  # ── Identidades ───────────────────────────────────────────────────────────
230
273
  @property
231
274
  def actor_id(self) -> UUID | str:
@@ -49,6 +49,7 @@ __all__ = [
49
49
  "AbstractAuditSink",
50
50
  "AbstractPrincipalResolver",
51
51
  "NullPrincipalResolver",
52
+ "CompositePrincipalResolver",
52
53
  "ResolvedPrincipal",
53
54
  ]
54
55
 
@@ -466,3 +467,51 @@ class NullPrincipalResolver(AbstractPrincipalResolver):
466
467
  async def resolve(self, user: "User") -> "ResolvedPrincipal":
467
468
  del user
468
469
  return ResolvedPrincipal()
470
+
471
+
472
+ class CompositePrincipalResolver(AbstractPrincipalResolver):
473
+ """
474
+ Combina varios `AbstractPrincipalResolver` en uno solo.
475
+
476
+ `configure_identity(principals=...)` sólo tiene **un** slot (HC-16): no hay forma de
477
+ cablear a la vez, por ejemplo, `RbacPrincipalResolver` —que resuelve roles/scopes y nunca
478
+ toca `status`— con un resolver propio de la app que sólo sabe de `status` ("pending",
479
+ "banned", lo que sea). Sin este puente, quien necesitara ambos tenía que reimplementar a
480
+ mano lo que `RbacPrincipalResolver` ya hace, sólo para poder agregarle un `status`.
481
+
482
+ Corre los resolvers en orden y los combina:
483
+
484
+ - `roles` y `scopes`: unión de todos.
485
+ - `status`: el primer resolver de la lista que devuelva algo distinto de `None` — no una
486
+ unión, porque el estado de una cuenta no es un conjunto, es un valor. El orden importa:
487
+ poné primero el resolver cuyo `status` tiene que ganar.
488
+
489
+ Uso::
490
+
491
+ configure_identity(
492
+ IdentityConfig(),
493
+ principals=CompositePrincipalResolver([
494
+ rbac.principal_resolver(), # roles y scopes
495
+ EstadoDeCuentaResolver(uow), # status
496
+ ]),
497
+ )
498
+ """
499
+
500
+ def __init__(self, resolvers: t.Sequence[AbstractPrincipalResolver]) -> None:
501
+ self._resolvers = list(resolvers)
502
+
503
+ async def resolve(self, user: "User") -> "ResolvedPrincipal":
504
+ roles: set[str] = set()
505
+ scopes: set[str] = set()
506
+ status: str | None = None
507
+
508
+ for resolver in self._resolvers:
509
+ resuelto = await resolver.resolve(user)
510
+ roles.update(resuelto.roles)
511
+ scopes.update(resuelto.scopes)
512
+ if status is None and resuelto.status is not None:
513
+ status = resuelto.status
514
+
515
+ return ResolvedPrincipal(
516
+ roles=frozenset(roles), scopes=frozenset(scopes), status=status
517
+ )
@@ -22,6 +22,26 @@ logger = logging.getLogger("hexcore.darwin.lifespan")
22
22
  __all__ = ["IdentityStep", "SessionReaperStep", "identity_startup_steps"]
23
23
 
24
24
 
25
+ def _verificar_paso(paso: t.Any) -> None:
26
+ """
27
+ Verifica que el paso de un plugin cumpla `StartupStep` **antes** de arrancar ninguno.
28
+
29
+ Se valida la lista entera primero, y recién después se arranca: un paso mal formado en el
30
+ segundo plugin no puede descubrirse después de que el primero ya corrió su seeding.
31
+
32
+ El mensaje nombra al paso y la forma que le falta porque el síntoma sin esto es
33
+ `AttributeError: 'X' object has no attribute 'start'` saliendo de un módulo del framework,
34
+ que no le dice a nadie que el culpable es el plugin que acaba de agregar.
35
+ """
36
+ if callable(getattr(paso, "start", None)):
37
+ return
38
+ raise TypeError(
39
+ f"El paso de arranque {type(paso).__name__!r} que aporta un plugin no cumple "
40
+ "`StartupStep`: le falta `async def start(self) -> None`. Un `__call__` no alcanza — "
41
+ "`build_lifespan` y `IdentityStep` llaman a `start()`."
42
+ )
43
+
44
+
25
45
  class IdentityStep:
26
46
  """
27
47
  Configura Darwin y verifica que su esquema esté visible para Alembic.
@@ -56,11 +76,12 @@ class IdentityStep:
56
76
  self._config = config
57
77
  self._components = dict(components or {})
58
78
  self._verify_schema = verify_schema
79
+ self._plugin_steps: list[t.Any] = []
59
80
 
60
81
  async def start(self) -> None:
61
82
  from hexcore.darwin.application.container import configure_identity
62
83
 
63
- configure_identity(self._config, **self._components)
84
+ contenedor = configure_identity(self._config, **self._components)
64
85
  logger.info("Darwin configurado.")
65
86
 
66
87
  self._verificar_defaults_de_produccion()
@@ -68,15 +89,32 @@ class IdentityStep:
68
89
  if self._verify_schema:
69
90
  self._verificar_esquema()
70
91
 
92
+ # `PluginRegistry.startup_steps()` existe hace varias versiones, pero nada lo llamaba
93
+ # acá — `RbacSeedStep` (y cualquier otro paso de plugin, como el reaper de passkeys)
94
+ # sólo corría si el consumidor lo descubría y lo agregaba a mano a su propio
95
+ # `build_lifespan(...)` (HC-17). Se corren en el orden en que los plugins fueron
96
+ # registrados, después de que el contenedor ya existe.
97
+ self._plugin_steps = list(contenedor.plugins.startup_steps())
98
+ for paso in self._plugin_steps:
99
+ _verificar_paso(paso)
100
+ for paso in self._plugin_steps:
101
+ await paso.start()
102
+
71
103
  async def stop(self) -> None:
72
104
  """
73
- Descarta el contenedor y deregistra el sobre.
105
+ Para los pasos de los plugins y descarta el contenedor.
74
106
 
75
107
  Importa en un worker de vida larga que reconfigura, y en los tests: sin esto el
76
108
  registro del sobre queda apuntando a un contenedor que ya no existe.
77
109
  """
78
110
  from hexcore.darwin.application.container import reset_identity
79
111
 
112
+ for paso in reversed(self._plugin_steps):
113
+ detener = getattr(paso, "stop", None)
114
+ if detener is not None:
115
+ await detener()
116
+ self._plugin_steps = []
117
+
80
118
  reset_identity()
81
119
 
82
120
  def _verificar_esquema(self) -> None: