@authup/server-core 1.0.0-beta.63 → 1.0.0-beta.64

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 (710) hide show
  1. package/dist/adapters/database/data-source/options/module.d.ts +1 -0
  2. package/dist/adapters/database/data-source/options/module.d.ts.map +1 -1
  3. package/dist/adapters/database/data-source/options/module.mjs +33 -4
  4. package/dist/adapters/database/data-source/options/module.mjs.map +1 -1
  5. package/dist/adapters/database/domains/client/entity.d.ts +1 -2
  6. package/dist/adapters/database/domains/client/entity.d.ts.map +1 -1
  7. package/dist/adapters/database/domains/client/entity.mjs +7 -14
  8. package/dist/adapters/database/domains/client/entity.mjs.map +1 -1
  9. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.d.ts +2 -1
  10. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.d.ts.map +1 -1
  11. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs +2 -2
  12. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs.map +1 -1
  13. package/dist/adapters/database/domains/session/entity.d.ts +8 -0
  14. package/dist/adapters/database/domains/session/entity.d.ts.map +1 -1
  15. package/dist/adapters/database/domains/session/entity.mjs +19 -0
  16. package/dist/adapters/database/domains/session/entity.mjs.map +1 -1
  17. package/dist/adapters/database/domains/user/entity.d.ts +1 -0
  18. package/dist/adapters/database/domains/user/entity.d.ts.map +1 -1
  19. package/dist/adapters/database/domains/user/entity.mjs +6 -0
  20. package/dist/adapters/database/domains/user/entity.mjs.map +1 -1
  21. package/dist/adapters/database/extra-attribute-repository/repository.mjs +1 -1
  22. package/dist/adapters/database/extra-attribute-repository/repository.mjs.map +1 -1
  23. package/dist/adapters/database/extra-attribute-repository/tree/adapter.mjs +4 -2
  24. package/dist/adapters/database/extra-attribute-repository/tree/adapter.mjs.map +1 -1
  25. package/dist/adapters/database/extra-attribute-repository/tree/repository.mjs +1 -1
  26. package/dist/adapters/database/extra-attribute-repository/tree/repository.mjs.map +1 -1
  27. package/dist/adapters/database/index.mjs +3 -3
  28. package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.d.ts +56 -0
  29. package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.d.ts.map +1 -0
  30. package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.mjs +105 -0
  31. package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.mjs.map +1 -0
  32. package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.d.ts +56 -0
  33. package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.d.ts.map +1 -0
  34. package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.mjs +104 -0
  35. package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.mjs.map +1 -0
  36. package/dist/adapters/database/subscriber/module.d.ts +6 -2
  37. package/dist/adapters/database/subscriber/module.d.ts.map +1 -1
  38. package/dist/adapters/database/subscriber/module.mjs +9 -5
  39. package/dist/adapters/database/subscriber/module.mjs.map +1 -1
  40. package/dist/adapters/http/adapters/oauth2/authorization/module.mjs +1 -1
  41. package/dist/adapters/http/adapters/oauth2/authorization/module.mjs.map +1 -1
  42. package/dist/adapters/http/constants.d.ts +18 -0
  43. package/dist/adapters/http/constants.d.ts.map +1 -0
  44. package/dist/adapters/http/constants.mjs +23 -0
  45. package/dist/adapters/http/constants.mjs.map +1 -0
  46. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +3 -3
  47. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  48. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts +6 -0
  49. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts.map +1 -1
  50. package/dist/adapters/http/controllers/entities/realm/module.d.ts.map +1 -1
  51. package/dist/adapters/http/controllers/entities/realm/module.mjs +2 -0
  52. package/dist/adapters/http/controllers/entities/realm/module.mjs.map +1 -1
  53. package/dist/adapters/http/controllers/entities/session/module.d.ts +33 -1
  54. package/dist/adapters/http/controllers/entities/session/module.d.ts.map +1 -1
  55. package/dist/adapters/http/controllers/entities/session/module.mjs +74 -0
  56. package/dist/adapters/http/controllers/entities/session/module.mjs.map +1 -1
  57. package/dist/adapters/http/controllers/index.mjs +3 -1
  58. package/dist/adapters/http/controllers/workflows/account/index.d.ts +1 -0
  59. package/dist/adapters/http/controllers/workflows/account/index.d.ts.map +1 -1
  60. package/dist/adapters/http/controllers/workflows/account/module.d.ts +25 -16
  61. package/dist/adapters/http/controllers/workflows/account/module.d.ts.map +1 -1
  62. package/dist/adapters/http/controllers/workflows/account/module.mjs +40 -17
  63. package/dist/adapters/http/controllers/workflows/account/module.mjs.map +1 -1
  64. package/dist/adapters/http/controllers/workflows/account/types.d.ts +33 -0
  65. package/dist/adapters/http/controllers/workflows/account/types.d.ts.map +1 -0
  66. package/dist/adapters/http/controllers/workflows/activate/module.d.ts +8 -4
  67. package/dist/adapters/http/controllers/workflows/activate/module.d.ts.map +1 -1
  68. package/dist/adapters/http/controllers/workflows/activate/module.mjs +7 -9
  69. package/dist/adapters/http/controllers/workflows/activate/module.mjs.map +1 -1
  70. package/dist/adapters/http/controllers/workflows/admin/index.d.ts.map +1 -0
  71. package/dist/adapters/http/controllers/workflows/admin/index.mjs +5 -0
  72. package/dist/adapters/http/controllers/workflows/admin/module.d.ts +30 -0
  73. package/dist/adapters/http/controllers/workflows/admin/module.d.ts.map +1 -0
  74. package/dist/adapters/http/controllers/workflows/admin/module.mjs +88 -0
  75. package/dist/adapters/http/controllers/workflows/admin/module.mjs.map +1 -0
  76. package/dist/adapters/http/controllers/workflows/admin/types.d.ts +14 -0
  77. package/dist/adapters/http/controllers/workflows/admin/types.d.ts.map +1 -0
  78. package/dist/adapters/http/controllers/workflows/auth-console.d.ts +16 -0
  79. package/dist/adapters/http/controllers/workflows/auth-console.d.ts.map +1 -0
  80. package/dist/adapters/http/controllers/workflows/auth-console.mjs +32 -0
  81. package/dist/adapters/http/controllers/workflows/auth-console.mjs.map +1 -0
  82. package/dist/adapters/http/controllers/workflows/authorize/module.d.ts +16 -1
  83. package/dist/adapters/http/controllers/workflows/authorize/module.d.ts.map +1 -1
  84. package/dist/adapters/http/controllers/workflows/authorize/module.mjs +40 -22
  85. package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
  86. package/dist/adapters/http/controllers/workflows/authorize/types.d.ts +5 -0
  87. package/dist/adapters/http/controllers/workflows/authorize/types.d.ts.map +1 -1
  88. package/dist/adapters/http/controllers/workflows/console-login/index.d.ts +3 -0
  89. package/dist/adapters/http/controllers/workflows/console-login/index.d.ts.map +1 -0
  90. package/dist/adapters/http/controllers/workflows/console-login/index.mjs +5 -0
  91. package/dist/adapters/http/controllers/workflows/console-login/module.d.ts +83 -0
  92. package/dist/adapters/http/controllers/workflows/console-login/module.d.ts.map +1 -0
  93. package/dist/adapters/http/controllers/workflows/console-login/module.mjs +230 -0
  94. package/dist/adapters/http/controllers/workflows/console-login/module.mjs.map +1 -0
  95. package/dist/adapters/http/controllers/workflows/console-login/types.d.ts +58 -0
  96. package/dist/adapters/http/controllers/workflows/console-login/types.d.ts.map +1 -0
  97. package/dist/adapters/http/controllers/workflows/index.d.ts +2 -0
  98. package/dist/adapters/http/controllers/workflows/index.d.ts.map +1 -1
  99. package/dist/adapters/http/controllers/workflows/index.mjs +5 -1
  100. package/dist/adapters/http/controllers/workflows/logout/module.d.ts +32 -3
  101. package/dist/adapters/http/controllers/workflows/logout/module.d.ts.map +1 -1
  102. package/dist/adapters/http/controllers/workflows/logout/module.mjs +48 -24
  103. package/dist/adapters/http/controllers/workflows/logout/module.mjs.map +1 -1
  104. package/dist/adapters/http/controllers/workflows/logout/types.d.ts +1 -1
  105. package/dist/adapters/http/controllers/workflows/logout/types.d.ts.map +1 -1
  106. package/dist/adapters/http/controllers/workflows/password-forgot/module.d.ts +8 -4
  107. package/dist/adapters/http/controllers/workflows/password-forgot/module.d.ts.map +1 -1
  108. package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs +7 -9
  109. package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs.map +1 -1
  110. package/dist/adapters/http/controllers/workflows/password-reset/module.d.ts +8 -4
  111. package/dist/adapters/http/controllers/workflows/password-reset/module.d.ts.map +1 -1
  112. package/dist/adapters/http/controllers/workflows/password-reset/module.mjs +7 -10
  113. package/dist/adapters/http/controllers/workflows/password-reset/module.mjs.map +1 -1
  114. package/dist/adapters/http/controllers/workflows/register/module.d.ts +8 -4
  115. package/dist/adapters/http/controllers/workflows/register/module.d.ts.map +1 -1
  116. package/dist/adapters/http/controllers/workflows/register/module.mjs +7 -9
  117. package/dist/adapters/http/controllers/workflows/register/module.mjs.map +1 -1
  118. package/dist/adapters/http/controllers/workflows/status/module.mjs +1 -1
  119. package/dist/adapters/http/controllers/workflows/token/module.d.ts +45 -2
  120. package/dist/adapters/http/controllers/workflows/token/module.d.ts.map +1 -1
  121. package/dist/adapters/http/controllers/workflows/token/module.mjs +102 -24
  122. package/dist/adapters/http/controllers/workflows/token/module.mjs.map +1 -1
  123. package/dist/adapters/http/cookie/index.d.ts +2 -0
  124. package/dist/adapters/http/cookie/index.d.ts.map +1 -0
  125. package/dist/adapters/http/cookie/index.mjs +5 -0
  126. package/dist/adapters/http/cookie/session.d.ts +35 -0
  127. package/dist/adapters/http/cookie/session.d.ts.map +1 -0
  128. package/dist/adapters/http/cookie/session.mjs +62 -0
  129. package/dist/adapters/http/cookie/session.mjs.map +1 -0
  130. package/dist/adapters/http/index.d.ts +2 -0
  131. package/dist/adapters/http/index.d.ts.map +1 -1
  132. package/dist/adapters/http/index.mjs +20 -16
  133. package/dist/adapters/http/internal-client/index.d.ts +3 -0
  134. package/dist/adapters/http/internal-client/index.d.ts.map +1 -0
  135. package/dist/adapters/http/internal-client/index.mjs +5 -0
  136. package/dist/adapters/http/internal-client/module.d.ts +21 -0
  137. package/dist/adapters/http/internal-client/module.d.ts.map +1 -0
  138. package/dist/adapters/http/{ui/auth-console/http-client.mjs → internal-client/module.mjs} +16 -15
  139. package/dist/adapters/http/internal-client/module.mjs.map +1 -0
  140. package/dist/adapters/http/internal-client/types.d.ts +13 -0
  141. package/dist/adapters/http/internal-client/types.d.ts.map +1 -0
  142. package/dist/adapters/http/middleware/built-in/authorization/index.d.ts +1 -0
  143. package/dist/adapters/http/middleware/built-in/authorization/index.d.ts.map +1 -1
  144. package/dist/adapters/http/middleware/built-in/authorization/index.mjs +2 -1
  145. package/dist/adapters/http/middleware/built-in/authorization/issuance.d.ts +45 -0
  146. package/dist/adapters/http/middleware/built-in/authorization/issuance.d.ts.map +1 -0
  147. package/dist/adapters/http/middleware/built-in/authorization/issuance.mjs +61 -0
  148. package/dist/adapters/http/middleware/built-in/authorization/issuance.mjs.map +1 -0
  149. package/dist/adapters/http/middleware/built-in/authorization/module.d.ts +26 -2
  150. package/dist/adapters/http/middleware/built-in/authorization/module.d.ts.map +1 -1
  151. package/dist/adapters/http/middleware/built-in/authorization/module.mjs +67 -1
  152. package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
  153. package/dist/adapters/http/middleware/built-in/authorization/types.d.ts +21 -1
  154. package/dist/adapters/http/middleware/built-in/authorization/types.d.ts.map +1 -1
  155. package/dist/adapters/http/middleware/built-in/basic.d.ts +2 -2
  156. package/dist/adapters/http/middleware/built-in/basic.d.ts.map +1 -1
  157. package/dist/adapters/http/middleware/built-in/basic.mjs.map +1 -1
  158. package/dist/adapters/http/middleware/built-in/cors.d.ts +8 -2
  159. package/dist/adapters/http/middleware/built-in/cors.d.ts.map +1 -1
  160. package/dist/adapters/http/middleware/built-in/cors.mjs +20 -3
  161. package/dist/adapters/http/middleware/built-in/cors.mjs.map +1 -1
  162. package/dist/adapters/http/middleware/built-in/error.d.ts +2 -2
  163. package/dist/adapters/http/middleware/built-in/error.d.ts.map +1 -1
  164. package/dist/adapters/http/middleware/built-in/error.mjs.map +1 -1
  165. package/dist/adapters/http/middleware/built-in/index.d.ts +1 -4
  166. package/dist/adapters/http/middleware/built-in/index.d.ts.map +1 -1
  167. package/dist/adapters/http/middleware/built-in/index.mjs +3 -4
  168. package/dist/adapters/http/middleware/built-in/internal-http-client.d.ts +17 -0
  169. package/dist/adapters/http/middleware/built-in/internal-http-client.d.ts.map +1 -0
  170. package/dist/adapters/http/middleware/built-in/internal-http-client.mjs +27 -0
  171. package/dist/adapters/http/middleware/built-in/internal-http-client.mjs.map +1 -0
  172. package/dist/adapters/http/middleware/built-in/logger.mjs +1 -1
  173. package/dist/adapters/http/middleware/built-in/logger.mjs.map +1 -1
  174. package/dist/adapters/http/middleware/built-in/prometheus.d.ts +6 -5
  175. package/dist/adapters/http/middleware/built-in/prometheus.d.ts.map +1 -1
  176. package/dist/adapters/http/middleware/built-in/prometheus.mjs +3 -2
  177. package/dist/adapters/http/middleware/built-in/prometheus.mjs.map +1 -1
  178. package/dist/adapters/http/middleware/built-in/rate-limit.d.ts +2 -2
  179. package/dist/adapters/http/middleware/built-in/rate-limit.d.ts.map +1 -1
  180. package/dist/adapters/http/middleware/built-in/rate-limit.mjs +15 -0
  181. package/dist/adapters/http/middleware/built-in/rate-limit.mjs.map +1 -1
  182. package/dist/adapters/http/middleware/index.mjs +3 -4
  183. package/dist/adapters/http/request/constants.d.ts +1 -1
  184. package/dist/adapters/http/request/constants.d.ts.map +1 -1
  185. package/dist/adapters/http/request/constants.mjs +1 -5
  186. package/dist/adapters/http/request/constants.mjs.map +1 -1
  187. package/dist/adapters/http/request/helpers/index.d.ts +1 -1
  188. package/dist/adapters/http/request/helpers/index.d.ts.map +1 -1
  189. package/dist/adapters/http/request/helpers/index.mjs +2 -2
  190. package/dist/adapters/http/request/helpers/locale.d.ts +2 -1
  191. package/dist/adapters/http/request/helpers/locale.d.ts.map +1 -1
  192. package/dist/adapters/http/request/helpers/locale.mjs +1 -1
  193. package/dist/adapters/http/request/helpers/locale.mjs.map +1 -1
  194. package/dist/adapters/http/request/helpers/same-origin.d.ts +38 -0
  195. package/dist/adapters/http/request/helpers/same-origin.d.ts.map +1 -0
  196. package/dist/adapters/http/request/helpers/same-origin.mjs +68 -0
  197. package/dist/adapters/http/request/helpers/same-origin.mjs.map +1 -0
  198. package/dist/adapters/http/request/index.mjs +2 -2
  199. package/dist/adapters/http/request/permission/module.mjs +1 -1
  200. package/dist/adapters/http/request/permission/module.mjs.map +1 -1
  201. package/dist/adapters/http/request/types.d.ts +1 -2
  202. package/dist/adapters/http/request/types.d.ts.map +1 -1
  203. package/dist/adapters/shared/ldap/module.d.ts.map +1 -1
  204. package/dist/adapters/shared/ldap/module.mjs +4 -1
  205. package/dist/adapters/shared/ldap/module.mjs.map +1 -1
  206. package/dist/app/builder.d.ts +4 -4
  207. package/dist/app/builder.d.ts.map +1 -1
  208. package/dist/app/builder.mjs +7 -4
  209. package/dist/app/builder.mjs.map +1 -1
  210. package/dist/app/factory.d.ts +10 -0
  211. package/dist/app/factory.d.ts.map +1 -1
  212. package/dist/app/factory.mjs +26 -2
  213. package/dist/app/factory.mjs.map +1 -1
  214. package/dist/app/index.mjs +17 -19
  215. package/dist/app/modules/authentication/module.d.ts.map +1 -1
  216. package/dist/app/modules/authentication/module.mjs +15 -2
  217. package/dist/app/modules/authentication/module.mjs.map +1 -1
  218. package/dist/app/modules/authentication/repositories/session.d.ts +4 -1
  219. package/dist/app/modules/authentication/repositories/session.d.ts.map +1 -1
  220. package/dist/app/modules/authentication/repositories/session.mjs +20 -3
  221. package/dist/app/modules/authentication/repositories/session.mjs.map +1 -1
  222. package/dist/app/modules/components/index.d.ts +1 -0
  223. package/dist/app/modules/components/index.d.ts.map +1 -1
  224. package/dist/app/modules/components/module.d.ts +3 -1
  225. package/dist/app/modules/components/module.d.ts.map +1 -1
  226. package/dist/app/modules/components/module.mjs +26 -7
  227. package/dist/app/modules/components/module.mjs.map +1 -1
  228. package/dist/app/modules/components/types.d.ts +11 -0
  229. package/dist/app/modules/components/types.d.ts.map +1 -0
  230. package/dist/app/modules/config/app-origins.d.ts +10 -0
  231. package/dist/app/modules/config/app-origins.d.ts.map +1 -0
  232. package/dist/app/modules/config/app-origins.mjs +21 -0
  233. package/dist/app/modules/config/app-origins.mjs.map +1 -0
  234. package/dist/app/modules/config/constants.d.ts +23 -50
  235. package/dist/app/modules/config/constants.d.ts.map +1 -1
  236. package/dist/app/modules/config/constants.mjs +34 -51
  237. package/dist/app/modules/config/constants.mjs.map +1 -1
  238. package/dist/app/modules/config/index.d.ts +2 -3
  239. package/dist/app/modules/config/index.d.ts.map +1 -1
  240. package/dist/app/modules/config/index.mjs +4 -8
  241. package/dist/app/modules/config/module.d.ts +2 -2
  242. package/dist/app/modules/config/module.d.ts.map +1 -1
  243. package/dist/app/modules/config/module.mjs +1 -1
  244. package/dist/app/modules/config/module.mjs.map +1 -1
  245. package/dist/app/modules/config/read.d.ts +29 -0
  246. package/dist/app/modules/config/read.d.ts.map +1 -0
  247. package/dist/app/modules/config/read.mjs +65 -0
  248. package/dist/app/modules/config/read.mjs.map +1 -0
  249. package/dist/app/modules/config/types.d.ts +30 -405
  250. package/dist/app/modules/config/types.d.ts.map +1 -1
  251. package/dist/app/modules/config/validator.d.ts.map +1 -1
  252. package/dist/app/modules/config/validator.mjs +3 -87
  253. package/dist/app/modules/config/validator.mjs.map +1 -1
  254. package/dist/app/modules/database/index.d.ts +1 -0
  255. package/dist/app/modules/database/index.d.ts.map +1 -1
  256. package/dist/app/modules/database/index.mjs +2 -1
  257. package/dist/app/modules/database/migration.d.ts +33 -0
  258. package/dist/app/modules/database/migration.d.ts.map +1 -0
  259. package/dist/app/modules/database/migration.mjs +52 -0
  260. package/dist/app/modules/database/migration.mjs.map +1 -0
  261. package/dist/app/modules/database/module.d.ts.map +1 -1
  262. package/dist/app/modules/database/module.mjs +12 -6
  263. package/dist/app/modules/database/module.mjs.map +1 -1
  264. package/dist/app/modules/database/repositories/client/repository.d.ts +6 -1
  265. package/dist/app/modules/database/repositories/client/repository.d.ts.map +1 -1
  266. package/dist/app/modules/database/repositories/client/repository.mjs +21 -4
  267. package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
  268. package/dist/app/modules/database/repositories/event/repository.d.ts +29 -2
  269. package/dist/app/modules/database/repositories/event/repository.d.ts.map +1 -1
  270. package/dist/app/modules/database/repositories/event/repository.mjs +42 -24
  271. package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
  272. package/dist/app/modules/database/repositories/helpers.d.ts +24 -1
  273. package/dist/app/modules/database/repositories/helpers.d.ts.map +1 -1
  274. package/dist/app/modules/database/repositories/helpers.mjs +38 -1
  275. package/dist/app/modules/database/repositories/helpers.mjs.map +1 -1
  276. package/dist/app/modules/database/repositories/identity-provider/repository.mjs +1 -1
  277. package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs +4 -2
  278. package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs.map +1 -1
  279. package/dist/app/modules/database/repositories/key/repository.mjs +1 -1
  280. package/dist/app/modules/database/repositories/permission/repository.mjs +1 -1
  281. package/dist/app/modules/database/repositories/policy/repository.mjs +1 -1
  282. package/dist/app/modules/database/repositories/role/repository.mjs +1 -1
  283. package/dist/app/modules/database/repositories/scope/repository.mjs +1 -1
  284. package/dist/app/modules/database/repositories/trust-anchor/repository.mjs +1 -1
  285. package/dist/app/modules/database/repositories/user/repository.d.ts +7 -2
  286. package/dist/app/modules/database/repositories/user/repository.d.ts.map +1 -1
  287. package/dist/app/modules/database/repositories/user/repository.mjs +21 -4
  288. package/dist/app/modules/database/repositories/user/repository.mjs.map +1 -1
  289. package/dist/app/modules/http/constants.d.ts +3 -1
  290. package/dist/app/modules/http/constants.d.ts.map +1 -1
  291. package/dist/app/modules/http/constants.mjs +3 -2
  292. package/dist/app/modules/http/constants.mjs.map +1 -1
  293. package/dist/app/modules/http/module.d.ts +30 -9
  294. package/dist/app/modules/http/module.d.ts.map +1 -1
  295. package/dist/app/modules/http/module.mjs +31 -33
  296. package/dist/app/modules/http/module.mjs.map +1 -1
  297. package/dist/app/modules/http/modules/controller.d.ts +4 -3
  298. package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
  299. package/dist/app/modules/http/modules/controller.mjs +65 -36
  300. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  301. package/dist/app/modules/http/modules/middleware.d.ts +13 -22
  302. package/dist/app/modules/http/modules/middleware.d.ts.map +1 -1
  303. package/dist/app/modules/http/modules/middleware.mjs +20 -36
  304. package/dist/app/modules/http/modules/middleware.mjs.map +1 -1
  305. package/dist/app/modules/identity/module.mjs +4 -4
  306. package/dist/app/modules/identity/repositories/client.mjs +4 -2
  307. package/dist/app/modules/identity/repositories/client.mjs.map +1 -1
  308. package/dist/app/modules/identity/repositories/user.mjs +4 -2
  309. package/dist/app/modules/identity/repositories/user.mjs.map +1 -1
  310. package/dist/app/modules/index.mjs +21 -23
  311. package/dist/app/modules/logger/module.mjs +1 -1
  312. package/dist/app/modules/logger/module.mjs.map +1 -1
  313. package/dist/app/modules/mail/module.d.ts.map +1 -1
  314. package/dist/app/modules/mail/module.mjs.map +1 -1
  315. package/dist/app/modules/oauth2/constants.d.ts +2 -1
  316. package/dist/app/modules/oauth2/constants.d.ts.map +1 -1
  317. package/dist/app/modules/oauth2/constants.mjs +1 -0
  318. package/dist/app/modules/oauth2/constants.mjs.map +1 -1
  319. package/dist/app/modules/oauth2/module.d.ts.map +1 -1
  320. package/dist/app/modules/oauth2/module.mjs +9 -4
  321. package/dist/app/modules/oauth2/module.mjs.map +1 -1
  322. package/dist/app/modules/oauth2/repositories/client/repository.mjs +4 -2
  323. package/dist/app/modules/oauth2/repositories/client/repository.mjs.map +1 -1
  324. package/dist/app/modules/oauth2/repositories/consent/repository.d.ts.map +1 -1
  325. package/dist/app/modules/oauth2/repositories/consent/repository.mjs +3 -2
  326. package/dist/app/modules/oauth2/repositories/consent/repository.mjs.map +1 -1
  327. package/dist/app/modules/oauth2/repositories/console-login/index.d.ts +2 -0
  328. package/dist/app/modules/oauth2/repositories/console-login/index.d.ts.map +1 -0
  329. package/dist/app/modules/oauth2/repositories/console-login/index.mjs +5 -0
  330. package/dist/app/modules/oauth2/repositories/console-login/store.d.ts +19 -0
  331. package/dist/app/modules/oauth2/repositories/console-login/store.d.ts.map +1 -0
  332. package/dist/app/modules/oauth2/repositories/console-login/store.mjs +47 -0
  333. package/dist/app/modules/oauth2/repositories/console-login/store.mjs.map +1 -0
  334. package/dist/app/modules/oauth2/repositories/constants.d.ts +1 -0
  335. package/dist/app/modules/oauth2/repositories/constants.d.ts.map +1 -1
  336. package/dist/app/modules/oauth2/repositories/constants.mjs +1 -0
  337. package/dist/app/modules/oauth2/repositories/constants.mjs.map +1 -1
  338. package/dist/app/modules/oauth2/repositories/index.d.ts +1 -0
  339. package/dist/app/modules/oauth2/repositories/index.d.ts.map +1 -1
  340. package/dist/app/modules/oauth2/repositories/index.mjs +3 -1
  341. package/dist/app/modules/oauth2/repositories/session-token/repository.d.ts +2 -2
  342. package/dist/app/modules/oauth2/repositories/session-token/repository.d.ts.map +1 -1
  343. package/dist/app/modules/oauth2/repositories/session-token/repository.mjs +5 -3
  344. package/dist/app/modules/oauth2/repositories/session-token/repository.mjs.map +1 -1
  345. package/dist/app/modules/provisioning/module.d.ts.map +1 -1
  346. package/dist/app/modules/provisioning/module.mjs +5 -6
  347. package/dist/app/modules/provisioning/module.mjs.map +1 -1
  348. package/dist/app/modules/provisioning/sources/composite/module.d.ts.map +1 -1
  349. package/dist/app/modules/provisioning/sources/composite/module.mjs +2 -1
  350. package/dist/app/modules/provisioning/sources/composite/module.mjs.map +1 -1
  351. package/dist/app/modules/provisioning/sources/default/module.d.ts.map +1 -1
  352. package/dist/app/modules/provisioning/sources/default/module.mjs +2 -1
  353. package/dist/app/modules/provisioning/sources/default/module.mjs.map +1 -1
  354. package/dist/app/modules/runtime/module.d.ts.map +1 -1
  355. package/dist/app/modules/runtime/module.mjs +2 -1
  356. package/dist/app/modules/runtime/module.mjs.map +1 -1
  357. package/dist/app/types.d.ts +16 -0
  358. package/dist/app/types.d.ts.map +1 -1
  359. package/dist/cli/commands/config.d.ts +40 -0
  360. package/dist/cli/commands/config.d.ts.map +1 -0
  361. package/dist/cli/commands/config.mjs +65 -0
  362. package/dist/cli/commands/config.mjs.map +1 -0
  363. package/dist/cli/commands/healthcheck.d.ts +3 -2
  364. package/dist/cli/commands/healthcheck.d.ts.map +1 -1
  365. package/dist/cli/commands/healthcheck.mjs +6 -3
  366. package/dist/cli/commands/healthcheck.mjs.map +1 -1
  367. package/dist/cli/commands/index.d.ts +3 -0
  368. package/dist/cli/commands/index.d.ts.map +1 -1
  369. package/dist/cli/commands/index.mjs +3 -1
  370. package/dist/cli/commands/migration.d.ts +3 -10
  371. package/dist/cli/commands/migration.d.ts.map +1 -1
  372. package/dist/cli/commands/migration.mjs +17 -9
  373. package/dist/cli/commands/migration.mjs.map +1 -1
  374. package/dist/cli/commands/shutdown.d.ts +16 -0
  375. package/dist/cli/commands/shutdown.d.ts.map +1 -0
  376. package/dist/cli/commands/shutdown.mjs +41 -0
  377. package/dist/cli/commands/shutdown.mjs.map +1 -0
  378. package/dist/cli/commands/start.d.ts +3 -2
  379. package/dist/cli/commands/start.d.ts.map +1 -1
  380. package/dist/cli/commands/start.mjs +3 -21
  381. package/dist/cli/commands/start.mjs.map +1 -1
  382. package/dist/cli/commands/types.d.ts.map +1 -0
  383. package/dist/cli/index.d.ts +8 -0
  384. package/dist/cli/index.d.ts.map +1 -1
  385. package/dist/cli/index.mjs.map +1 -1
  386. package/dist/cli/module.d.ts +0 -2
  387. package/dist/cli/module.d.ts.map +1 -1
  388. package/dist/cli/module.mjs +4 -3
  389. package/dist/cli/module.mjs.map +1 -1
  390. package/dist/components/oauth2-cleaner/module.d.ts +2 -2
  391. package/dist/components/oauth2-cleaner/module.d.ts.map +1 -1
  392. package/dist/components/oauth2-cleaner/module.mjs +10 -7
  393. package/dist/components/oauth2-cleaner/module.mjs.map +1 -1
  394. package/dist/core/authentication/index.mjs +2 -1
  395. package/dist/core/authentication/session/constants.d.ts +10 -0
  396. package/dist/core/authentication/session/constants.d.ts.map +1 -0
  397. package/dist/core/authentication/session/constants.mjs +16 -0
  398. package/dist/core/authentication/session/constants.mjs.map +1 -0
  399. package/dist/core/authentication/session/index.d.ts +1 -0
  400. package/dist/core/authentication/session/index.d.ts.map +1 -1
  401. package/dist/core/authentication/session/index.mjs +2 -1
  402. package/dist/core/authentication/session/module.d.ts +2 -1
  403. package/dist/core/authentication/session/module.d.ts.map +1 -1
  404. package/dist/core/authentication/session/module.mjs +7 -1
  405. package/dist/core/authentication/session/module.mjs.map +1 -1
  406. package/dist/core/authentication/session/types.d.ts +70 -1
  407. package/dist/core/authentication/session/types.d.ts.map +1 -1
  408. package/dist/core/authentication/session/types.mjs.map +1 -1
  409. package/dist/core/entities/client/schema.d.ts.map +1 -1
  410. package/dist/core/entities/client/schema.mjs +1 -2
  411. package/dist/core/entities/client/schema.mjs.map +1 -1
  412. package/dist/core/entities/client/service.d.ts.map +1 -1
  413. package/dist/core/entities/client/service.mjs +15 -1
  414. package/dist/core/entities/client/service.mjs.map +1 -1
  415. package/dist/core/entities/client/system-clients.d.ts +0 -5
  416. package/dist/core/entities/client/system-clients.d.ts.map +1 -1
  417. package/dist/core/entities/client/system-clients.mjs +0 -6
  418. package/dist/core/entities/client/system-clients.mjs.map +1 -1
  419. package/dist/core/entities/client/types.d.ts +12 -0
  420. package/dist/core/entities/client/types.d.ts.map +1 -1
  421. package/dist/core/entities/client-permission/service.mjs +1 -1
  422. package/dist/core/entities/client-permission/service.mjs.map +1 -1
  423. package/dist/core/entities/event/constants.d.ts +1 -6
  424. package/dist/core/entities/event/constants.d.ts.map +1 -1
  425. package/dist/core/entities/event/constants.mjs +1 -5
  426. package/dist/core/entities/event/constants.mjs.map +1 -1
  427. package/dist/core/entities/event/entity-event-handler.d.ts.map +1 -1
  428. package/dist/core/entities/event/entity-event-handler.mjs +3 -2
  429. package/dist/core/entities/event/entity-event-handler.mjs.map +1 -1
  430. package/dist/core/entities/event/service.d.ts.map +1 -1
  431. package/dist/core/entities/event/service.mjs +3 -3
  432. package/dist/core/entities/event/service.mjs.map +1 -1
  433. package/dist/core/entities/event/types.d.ts +15 -1
  434. package/dist/core/entities/event/types.d.ts.map +1 -1
  435. package/dist/core/entities/permission/service.mjs +1 -2
  436. package/dist/core/entities/permission/service.mjs.map +1 -1
  437. package/dist/core/entities/role-permission/service.mjs +1 -1
  438. package/dist/core/entities/role-permission/service.mjs.map +1 -1
  439. package/dist/core/entities/session/service.d.ts +13 -1
  440. package/dist/core/entities/session/service.d.ts.map +1 -1
  441. package/dist/core/entities/session/service.mjs +19 -16
  442. package/dist/core/entities/session/service.mjs.map +1 -1
  443. package/dist/core/entities/user/schema.d.ts.map +1 -1
  444. package/dist/core/entities/user/schema.mjs +1 -0
  445. package/dist/core/entities/user/schema.mjs.map +1 -1
  446. package/dist/core/entities/user/service.d.ts.map +1 -1
  447. package/dist/core/entities/user/service.mjs +21 -1
  448. package/dist/core/entities/user/service.mjs.map +1 -1
  449. package/dist/core/entities/user/types.d.ts +12 -0
  450. package/dist/core/entities/user/types.d.ts.map +1 -1
  451. package/dist/core/entities/user-permission/service.mjs +1 -1
  452. package/dist/core/entities/user-permission/service.mjs.map +1 -1
  453. package/dist/core/identity/permission/junction-grant.mjs +1 -1
  454. package/dist/core/identity/permission/junction-grant.mjs.map +1 -1
  455. package/dist/core/identity/provider/account/module.mjs +1 -1
  456. package/dist/core/identity/provider/account/module.mjs.map +1 -1
  457. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs +1 -1
  458. package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs.map +1 -1
  459. package/dist/core/identity/registration/service.d.ts.map +1 -1
  460. package/dist/core/identity/registration/service.mjs +2 -1
  461. package/dist/core/identity/registration/service.mjs.map +1 -1
  462. package/dist/core/index.mjs +11 -3
  463. package/dist/core/oauth2/authorization/helpers.d.ts +14 -0
  464. package/dist/core/oauth2/authorization/helpers.d.ts.map +1 -1
  465. package/dist/core/oauth2/authorization/helpers.mjs +9 -1
  466. package/dist/core/oauth2/authorization/helpers.mjs.map +1 -1
  467. package/dist/core/oauth2/authorization/index.mjs +2 -2
  468. package/dist/core/oauth2/authorization/module.mjs +1 -1
  469. package/dist/core/oauth2/authorization/module.mjs.map +1 -1
  470. package/dist/core/oauth2/backchannel-logout/constants.d.ts +16 -0
  471. package/dist/core/oauth2/backchannel-logout/constants.d.ts.map +1 -0
  472. package/dist/core/oauth2/backchannel-logout/constants.mjs +20 -0
  473. package/dist/core/oauth2/backchannel-logout/constants.mjs.map +1 -0
  474. package/dist/core/oauth2/backchannel-logout/index.d.ts +4 -0
  475. package/dist/core/oauth2/backchannel-logout/index.d.ts.map +1 -0
  476. package/dist/core/oauth2/backchannel-logout/index.mjs +6 -0
  477. package/dist/core/oauth2/backchannel-logout/module.d.ts +26 -0
  478. package/dist/core/oauth2/backchannel-logout/module.d.ts.map +1 -0
  479. package/dist/core/oauth2/backchannel-logout/module.mjs +78 -0
  480. package/dist/core/oauth2/backchannel-logout/module.mjs.map +1 -0
  481. package/dist/core/oauth2/backchannel-logout/types.d.ts +29 -0
  482. package/dist/core/oauth2/backchannel-logout/types.d.ts.map +1 -0
  483. package/dist/core/oauth2/console-login/constants.d.ts +19 -0
  484. package/dist/core/oauth2/console-login/constants.d.ts.map +1 -0
  485. package/dist/core/oauth2/console-login/constants.mjs +24 -0
  486. package/dist/core/oauth2/console-login/constants.mjs.map +1 -0
  487. package/dist/core/oauth2/console-login/index.d.ts +3 -0
  488. package/dist/core/oauth2/console-login/index.d.ts.map +1 -0
  489. package/dist/core/oauth2/console-login/index.mjs +5 -0
  490. package/dist/core/oauth2/console-login/types.d.ts +53 -0
  491. package/dist/core/oauth2/console-login/types.d.ts.map +1 -0
  492. package/dist/core/oauth2/end-session/service.mjs +1 -1
  493. package/dist/core/oauth2/end-session/service.mjs.map +1 -1
  494. package/dist/core/oauth2/federated-login/module.mjs +3 -3
  495. package/dist/core/oauth2/federated-login/module.mjs.map +1 -1
  496. package/dist/core/oauth2/index.d.ts +4 -0
  497. package/dist/core/oauth2/index.d.ts.map +1 -1
  498. package/dist/core/oauth2/index.mjs +13 -3
  499. package/dist/core/oauth2/introspection/index.d.ts +3 -0
  500. package/dist/core/oauth2/introspection/index.d.ts.map +1 -0
  501. package/dist/core/oauth2/introspection/index.mjs +5 -0
  502. package/dist/core/oauth2/introspection/module.d.ts +14 -0
  503. package/dist/core/oauth2/introspection/module.d.ts.map +1 -0
  504. package/dist/core/oauth2/introspection/module.mjs +49 -0
  505. package/dist/core/oauth2/introspection/module.mjs.map +1 -0
  506. package/dist/core/oauth2/introspection/types.d.ts +45 -0
  507. package/dist/core/oauth2/introspection/types.d.ts.map +1 -0
  508. package/dist/core/oauth2/introspection/types.mjs +4 -0
  509. package/dist/core/oauth2/openid/claims.d.ts +20 -2
  510. package/dist/core/oauth2/openid/claims.d.ts.map +1 -1
  511. package/dist/core/oauth2/openid/claims.mjs +18 -4
  512. package/dist/core/oauth2/openid/claims.mjs.map +1 -1
  513. package/dist/core/oauth2/session-credential/constants.d.ts +30 -0
  514. package/dist/core/oauth2/session-credential/constants.d.ts.map +1 -0
  515. package/dist/core/oauth2/session-credential/constants.mjs +34 -0
  516. package/dist/core/oauth2/session-credential/constants.mjs.map +1 -0
  517. package/dist/core/oauth2/session-credential/index.d.ts +3 -0
  518. package/dist/core/oauth2/session-credential/index.d.ts.map +1 -0
  519. package/dist/core/oauth2/session-credential/index.mjs +6 -0
  520. package/dist/core/oauth2/session-credential/module.d.ts +31 -0
  521. package/dist/core/oauth2/session-credential/module.d.ts.map +1 -0
  522. package/dist/core/oauth2/session-credential/module.mjs +43 -0
  523. package/dist/core/oauth2/session-credential/module.mjs.map +1 -0
  524. package/dist/core/oauth2/session-token/constants.d.ts +10 -0
  525. package/dist/core/oauth2/session-token/constants.d.ts.map +1 -0
  526. package/dist/core/oauth2/session-token/constants.mjs +16 -0
  527. package/dist/core/oauth2/session-token/constants.mjs.map +1 -0
  528. package/dist/core/oauth2/session-token/index.d.ts +1 -0
  529. package/dist/core/oauth2/session-token/index.d.ts.map +1 -1
  530. package/dist/core/oauth2/session-token/index.mjs +2 -1
  531. package/dist/core/oauth2/session-token/types.d.ts +13 -2
  532. package/dist/core/oauth2/session-token/types.d.ts.map +1 -1
  533. package/dist/core/provisioning/merge/module.mjs +5 -3
  534. package/dist/core/provisioning/merge/module.mjs.map +1 -1
  535. package/dist/core/query/module.mjs +1 -1
  536. package/dist/core/query/module.mjs.map +1 -1
  537. package/dist/core/security/policy/evaluator.mjs +1 -1
  538. package/dist/core/security/policy/evaluator.mjs.map +1 -1
  539. package/dist/index.mjs +62 -59
  540. package/dist/path.mjs +1 -1
  541. package/dist/swagger.json +466 -104
  542. package/dist/utils/error.d.ts +6 -0
  543. package/dist/utils/error.d.ts.map +1 -1
  544. package/dist/utils/error.mjs +6 -2
  545. package/dist/utils/error.mjs.map +1 -1
  546. package/dist/utils/index.mjs +2 -2
  547. package/package.json +31 -25
  548. package/dist/adapters/http/middleware/built-in/assets.d.ts +0 -11
  549. package/dist/adapters/http/middleware/built-in/assets.d.ts.map +0 -1
  550. package/dist/adapters/http/middleware/built-in/assets.mjs +0 -91
  551. package/dist/adapters/http/middleware/built-in/assets.mjs.map +0 -1
  552. package/dist/adapters/http/middleware/built-in/theme.d.ts +0 -15
  553. package/dist/adapters/http/middleware/built-in/theme.d.ts.map +0 -1
  554. package/dist/adapters/http/middleware/built-in/theme.mjs +0 -27
  555. package/dist/adapters/http/middleware/built-in/theme.mjs.map +0 -1
  556. package/dist/adapters/http/middleware/built-in/types.d.ts +0 -14
  557. package/dist/adapters/http/middleware/built-in/types.d.ts.map +0 -1
  558. package/dist/adapters/http/middleware/built-in/ui-http-client.d.ts +0 -15
  559. package/dist/adapters/http/middleware/built-in/ui-http-client.d.ts.map +0 -1
  560. package/dist/adapters/http/middleware/built-in/ui-http-client.mjs +0 -25
  561. package/dist/adapters/http/middleware/built-in/ui-http-client.mjs.map +0 -1
  562. package/dist/adapters/http/request/helpers/redirect.d.ts +0 -14
  563. package/dist/adapters/http/request/helpers/redirect.d.ts.map +0 -1
  564. package/dist/adapters/http/request/helpers/redirect.mjs +0 -36
  565. package/dist/adapters/http/request/helpers/redirect.mjs.map +0 -1
  566. package/dist/adapters/http/ui/account-console/index.d.ts +0 -4
  567. package/dist/adapters/http/ui/account-console/index.d.ts.map +0 -1
  568. package/dist/adapters/http/ui/account-console/index.mjs +0 -6
  569. package/dist/adapters/http/ui/account-console/module.d.ts +0 -28
  570. package/dist/adapters/http/ui/account-console/module.d.ts.map +0 -1
  571. package/dist/adapters/http/ui/account-console/module.mjs +0 -80
  572. package/dist/adapters/http/ui/account-console/module.mjs.map +0 -1
  573. package/dist/adapters/http/ui/account-console/ref.d.ts +0 -30
  574. package/dist/adapters/http/ui/account-console/ref.d.ts.map +0 -1
  575. package/dist/adapters/http/ui/account-console/ref.mjs +0 -50
  576. package/dist/adapters/http/ui/account-console/ref.mjs.map +0 -1
  577. package/dist/adapters/http/ui/account-console/types.d.ts +0 -11
  578. package/dist/adapters/http/ui/account-console/types.d.ts.map +0 -1
  579. package/dist/adapters/http/ui/auth-console/http-client.d.ts +0 -22
  580. package/dist/adapters/http/ui/auth-console/http-client.d.ts.map +0 -1
  581. package/dist/adapters/http/ui/auth-console/http-client.mjs.map +0 -1
  582. package/dist/adapters/http/ui/auth-console/index.d.ts +0 -6
  583. package/dist/adapters/http/ui/auth-console/index.d.ts.map +0 -1
  584. package/dist/adapters/http/ui/auth-console/index.mjs +0 -8
  585. package/dist/adapters/http/ui/auth-console/module.d.ts +0 -4
  586. package/dist/adapters/http/ui/auth-console/module.d.ts.map +0 -1
  587. package/dist/adapters/http/ui/auth-console/module.mjs +0 -73
  588. package/dist/adapters/http/ui/auth-console/module.mjs.map +0 -1
  589. package/dist/adapters/http/ui/auth-console/resolve.d.ts +0 -21
  590. package/dist/adapters/http/ui/auth-console/resolve.d.ts.map +0 -1
  591. package/dist/adapters/http/ui/auth-console/resolve.mjs +0 -53
  592. package/dist/adapters/http/ui/auth-console/resolve.mjs.map +0 -1
  593. package/dist/adapters/http/ui/auth-console/serve.d.ts +0 -9
  594. package/dist/adapters/http/ui/auth-console/serve.d.ts.map +0 -1
  595. package/dist/adapters/http/ui/auth-console/serve.mjs +0 -35
  596. package/dist/adapters/http/ui/auth-console/serve.mjs.map +0 -1
  597. package/dist/adapters/http/ui/auth-console/types.d.ts +0 -26
  598. package/dist/adapters/http/ui/auth-console/types.d.ts.map +0 -1
  599. package/dist/adapters/http/ui/console-packages/index.d.ts.map +0 -1
  600. package/dist/adapters/http/ui/console-packages/index.mjs +0 -5
  601. package/dist/adapters/http/ui/console-packages/module.d.ts +0 -33
  602. package/dist/adapters/http/ui/console-packages/module.d.ts.map +0 -1
  603. package/dist/adapters/http/ui/console-packages/module.mjs +0 -70
  604. package/dist/adapters/http/ui/console-packages/module.mjs.map +0 -1
  605. package/dist/adapters/http/ui/console-packages/types.d.ts +0 -12
  606. package/dist/adapters/http/ui/console-packages/types.d.ts.map +0 -1
  607. package/dist/adapters/http/ui/index.d.ts +0 -6
  608. package/dist/adapters/http/ui/index.d.ts.map +0 -1
  609. package/dist/adapters/http/ui/index.mjs +0 -25
  610. package/dist/adapters/http/ui/shared/html.d.ts +0 -76
  611. package/dist/adapters/http/ui/shared/html.d.ts.map +0 -1
  612. package/dist/adapters/http/ui/shared/html.mjs +0 -104
  613. package/dist/adapters/http/ui/shared/html.mjs.map +0 -1
  614. package/dist/adapters/http/ui/shared/index.d.ts +0 -2
  615. package/dist/adapters/http/ui/shared/index.d.ts.map +0 -1
  616. package/dist/adapters/http/ui/shared/index.mjs +0 -5
  617. package/dist/adapters/http/ui/theme/apply.d.ts +0 -12
  618. package/dist/adapters/http/ui/theme/apply.d.ts.map +0 -1
  619. package/dist/adapters/http/ui/theme/apply.mjs +0 -29
  620. package/dist/adapters/http/ui/theme/apply.mjs.map +0 -1
  621. package/dist/adapters/http/ui/theme/assets.d.ts +0 -20
  622. package/dist/adapters/http/ui/theme/assets.d.ts.map +0 -1
  623. package/dist/adapters/http/ui/theme/assets.mjs +0 -86
  624. package/dist/adapters/http/ui/theme/assets.mjs.map +0 -1
  625. package/dist/adapters/http/ui/theme/constants.d.ts +0 -16
  626. package/dist/adapters/http/ui/theme/constants.d.ts.map +0 -1
  627. package/dist/adapters/http/ui/theme/constants.mjs +0 -20
  628. package/dist/adapters/http/ui/theme/constants.mjs.map +0 -1
  629. package/dist/adapters/http/ui/theme/contract/constants.d.ts +0 -120
  630. package/dist/adapters/http/ui/theme/contract/constants.d.ts.map +0 -1
  631. package/dist/adapters/http/ui/theme/contract/constants.mjs +0 -136
  632. package/dist/adapters/http/ui/theme/contract/constants.mjs.map +0 -1
  633. package/dist/adapters/http/ui/theme/contract/head.d.ts +0 -12
  634. package/dist/adapters/http/ui/theme/contract/head.d.ts.map +0 -1
  635. package/dist/adapters/http/ui/theme/contract/head.mjs +0 -61
  636. package/dist/adapters/http/ui/theme/contract/head.mjs.map +0 -1
  637. package/dist/adapters/http/ui/theme/contract/index.d.ts +0 -6
  638. package/dist/adapters/http/ui/theme/contract/index.d.ts.map +0 -1
  639. package/dist/adapters/http/ui/theme/contract/index.mjs +0 -8
  640. package/dist/adapters/http/ui/theme/contract/manifest.d.ts +0 -25
  641. package/dist/adapters/http/ui/theme/contract/manifest.d.ts.map +0 -1
  642. package/dist/adapters/http/ui/theme/contract/manifest.mjs +0 -77
  643. package/dist/adapters/http/ui/theme/contract/manifest.mjs.map +0 -1
  644. package/dist/adapters/http/ui/theme/contract/types.d.ts +0 -26
  645. package/dist/adapters/http/ui/theme/contract/types.d.ts.map +0 -1
  646. package/dist/adapters/http/ui/theme/contract/utils.d.ts +0 -11
  647. package/dist/adapters/http/ui/theme/contract/utils.d.ts.map +0 -1
  648. package/dist/adapters/http/ui/theme/contract/utils.mjs +0 -22
  649. package/dist/adapters/http/ui/theme/contract/utils.mjs.map +0 -1
  650. package/dist/adapters/http/ui/theme/index.d.ts +0 -7
  651. package/dist/adapters/http/ui/theme/index.d.ts.map +0 -1
  652. package/dist/adapters/http/ui/theme/index.mjs +0 -13
  653. package/dist/adapters/http/ui/theme/module.d.ts +0 -79
  654. package/dist/adapters/http/ui/theme/module.d.ts.map +0 -1
  655. package/dist/adapters/http/ui/theme/module.mjs +0 -206
  656. package/dist/adapters/http/ui/theme/module.mjs.map +0 -1
  657. package/dist/adapters/http/ui/theme/types.d.ts +0 -42
  658. package/dist/adapters/http/ui/theme/types.d.ts.map +0 -1
  659. package/dist/app/modules/config/helpers.d.ts +0 -9
  660. package/dist/app/modules/config/helpers.d.ts.map +0 -1
  661. package/dist/app/modules/config/helpers.mjs +0 -22
  662. package/dist/app/modules/config/helpers.mjs.map +0 -1
  663. package/dist/app/modules/config/normalize.d.ts +0 -3
  664. package/dist/app/modules/config/normalize.d.ts.map +0 -1
  665. package/dist/app/modules/config/normalize.mjs +0 -117
  666. package/dist/app/modules/config/normalize.mjs.map +0 -1
  667. package/dist/app/modules/config/origins.d.ts +0 -25
  668. package/dist/app/modules/config/origins.d.ts.map +0 -1
  669. package/dist/app/modules/config/origins.mjs +0 -46
  670. package/dist/app/modules/config/origins.mjs.map +0 -1
  671. package/dist/app/modules/config/read/env.d.ts +0 -3
  672. package/dist/app/modules/config/read/env.d.ts.map +0 -1
  673. package/dist/app/modules/config/read/env.mjs +0 -139
  674. package/dist/app/modules/config/read/env.mjs.map +0 -1
  675. package/dist/app/modules/config/read/fs.d.ts +0 -3
  676. package/dist/app/modules/config/read/fs.d.ts.map +0 -1
  677. package/dist/app/modules/config/read/fs.mjs +0 -60
  678. package/dist/app/modules/config/read/fs.mjs.map +0 -1
  679. package/dist/app/modules/config/read/index.d.ts +0 -5
  680. package/dist/app/modules/config/read/index.d.ts.map +0 -1
  681. package/dist/app/modules/config/read/index.mjs +0 -7
  682. package/dist/app/modules/config/read/module.d.ts +0 -4
  683. package/dist/app/modules/config/read/module.d.ts.map +0 -1
  684. package/dist/app/modules/config/read/module.mjs +0 -29
  685. package/dist/app/modules/config/read/module.mjs.map +0 -1
  686. package/dist/app/modules/config/read/types.d.ts +0 -9
  687. package/dist/app/modules/config/read/types.d.ts.map +0 -1
  688. package/dist/app/modules/config/trust-proxy.d.ts +0 -28
  689. package/dist/app/modules/config/trust-proxy.d.ts.map +0 -1
  690. package/dist/app/modules/config/trust-proxy.mjs +0 -64
  691. package/dist/app/modules/config/trust-proxy.mjs.map +0 -1
  692. package/dist/cli/config.d.ts +0 -18
  693. package/dist/cli/config.d.ts.map +0 -1
  694. package/dist/cli/config.mjs +0 -34
  695. package/dist/cli/config.mjs.map +0 -1
  696. package/dist/cli/types.d.ts.map +0 -1
  697. package/dist/utils/host.d.ts +0 -2
  698. package/dist/utils/host.d.ts.map +0 -1
  699. package/dist/utils/host.mjs +0 -12
  700. package/dist/utils/host.mjs.map +0 -1
  701. /package/dist/adapters/http/{middleware/built-in → controllers/workflows/account}/types.mjs +0 -0
  702. /package/dist/adapters/http/{ui/console-packages → controllers/workflows/admin}/index.d.ts +0 -0
  703. /package/dist/adapters/http/{ui/account-console → controllers/workflows/admin}/types.mjs +0 -0
  704. /package/dist/adapters/http/{ui/auth-console → controllers/workflows/console-login}/types.mjs +0 -0
  705. /package/dist/adapters/http/{ui/console-packages → internal-client}/types.mjs +0 -0
  706. /package/dist/{adapters/http/ui/theme/contract → app/modules/components}/types.mjs +0 -0
  707. /package/dist/cli/{types.d.ts → commands/types.d.ts} +0 -0
  708. /package/dist/{adapters/http/ui/theme → cli/commands}/types.mjs +0 -0
  709. /package/dist/{app/modules/config/read → core/oauth2/backchannel-logout}/types.mjs +0 -0
  710. /package/dist/{cli → core/oauth2/console-login}/types.mjs +0 -0
@@ -0,0 +1,52 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { AuthupError } from "@authup/errors";
5
+ import { synchronizeDatabaseSchema } from "typeorm-extension";
6
+ //#region src/app/modules/database/migration.ts
7
+ /**
8
+ * Verify the database schema is current without running any DDL.
9
+ *
10
+ * Resolves `false` when the resolved data-source options carry no
11
+ * migrations at all. That is the sqlite shape: nothing can be pending, and
12
+ * the schema still has to be created, so the caller falls through to a
13
+ * schema synchronize. The predicate is the options, never a dialect
14
+ * compare.
15
+ *
16
+ * Resolves `true` when migrations are configured and none of them are
17
+ * pending. Throws when any are pending, so a process can never silently
18
+ * serve against an older schema.
19
+ */ async function assertNoPendingMigrations(dataSource) {
20
+ const { migrations } = dataSource.options;
21
+ if (!(Array.isArray(migrations) ? migrations.length > 0 : !!migrations && Object.keys(migrations).length > 0)) return false;
22
+ if (await dataSource.showMigrations()) throw new AuthupError("The database has pending migrations, and this process applies no schema changes. Run the migration CLI command (authup migration run) and start again.");
23
+ return true;
24
+ }
25
+ /**
26
+ * Bring a process up against a schema another process owns: verify it, and
27
+ * create it only where there is nothing to verify.
28
+ *
29
+ * `assertNoPendingMigrations` throws when the chain is behind, so a verified
30
+ * return is the only way past it. Its `false` return means the data source
31
+ * carries no migrations at all (the sqlite shape), where nothing can be
32
+ * pending and the schema still has to be created, so that branch falls
33
+ * through to a synchronize. Dropping the fall-through would leave a sqlite
34
+ * process with no schema.
35
+ *
36
+ * Both callers that must not migrate share this: `DatabaseModule.migrate`
37
+ * under `migrationEnabled: false`, and the worker preset, which never
38
+ * migrates whatever the flag says.
39
+ */ async function verifySchemaOrSynchronize(logger, dataSource) {
40
+ logger.debug("Verifying database schema...");
41
+ if (await assertNoPendingMigrations(dataSource)) {
42
+ logger.debug("Verified database schema.");
43
+ return;
44
+ }
45
+ logger.debug("Migrating database...");
46
+ await synchronizeDatabaseSchema(dataSource);
47
+ logger.debug("Migrated database");
48
+ }
49
+ //#endregion
50
+ export { assertNoPendingMigrations, verifySchemaOrSynchronize };
51
+
52
+ //# sourceMappingURL=migration.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.mjs","names":["AuthupError","synchronizeDatabaseSchema","assertNoPendingMigrations","dataSource","migrations","options","configured","Array","isArray","length","Object","keys","pending","showMigrations","verifySchemaOrSynchronize","logger","debug","verified"],"sources":["../../../../src/app/modules/database/migration.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { AuthupError } from '@authup/errors';\nimport type { Logger } from '@authup/server-kit';\nimport type { DataSource } from 'typeorm';\nimport { synchronizeDatabaseSchema } from 'typeorm-extension';\n\n/**\n * Verify the database schema is current without running any DDL.\n *\n * Resolves `false` when the resolved data-source options carry no\n * migrations at all. That is the sqlite shape: nothing can be pending, and\n * the schema still has to be created, so the caller falls through to a\n * schema synchronize. The predicate is the options, never a dialect\n * compare.\n *\n * Resolves `true` when migrations are configured and none of them are\n * pending. Throws when any are pending, so a process can never silently\n * serve against an older schema.\n */\nexport async function assertNoPendingMigrations(dataSource: DataSource) : Promise<boolean> {\n const { migrations } = dataSource.options;\n\n const configured = Array.isArray(migrations) ?\n migrations.length > 0 :\n !!migrations && Object.keys(migrations).length > 0;\n\n if (!configured) {\n return false;\n }\n\n // typeorm: true means pending migrations exist.\n const pending = await dataSource.showMigrations();\n if (pending) {\n throw new AuthupError('The database has pending migrations, and this process applies no schema changes. Run the migration CLI command (authup migration run) and start again.');\n }\n\n return true;\n}\n\n/**\n * Bring a process up against a schema another process owns: verify it, and\n * create it only where there is nothing to verify.\n *\n * `assertNoPendingMigrations` throws when the chain is behind, so a verified\n * return is the only way past it. Its `false` return means the data source\n * carries no migrations at all (the sqlite shape), where nothing can be\n * pending and the schema still has to be created, so that branch falls\n * through to a synchronize. Dropping the fall-through would leave a sqlite\n * process with no schema.\n *\n * Both callers that must not migrate share this: `DatabaseModule.migrate`\n * under `migrationEnabled: false`, and the worker preset, which never\n * migrates whatever the flag says.\n */\nexport async function verifySchemaOrSynchronize(\n logger: Logger,\n dataSource: DataSource,\n): Promise<void> {\n logger.debug('Verifying database schema...');\n\n const verified = await assertNoPendingMigrations(dataSource);\n if (verified) {\n logger.debug('Verified database schema.');\n return;\n }\n\n logger.debug('Migrating database...');\n await synchronizeDatabaseSchema(dataSource);\n logger.debug('Migrated database');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;GAyBA,eAAsBE,0BAA0BC,YAAsB;CAClE,MAAM,EAAEC,eAAeD,WAAWE;CAMlC,IAAI,EAJeE,MAAMC,QAAQJ,UAAAA,IAC7BA,WAAWK,SAAS,IACpB,CAAC,CAACL,cAAcM,OAAOC,KAAKP,UAAAA,CAAAA,CAAYK,SAAS,IAGjD,OAAO;CAKX,IAAIG,MADkBT,WAAWU,eAAc,GAE3C,MAAM,IAAIb,YAAY,wJAAA;CAG1B,OAAO;AACX;;;;;;;;;;;;;;;GAiBA,eAAsBc,0BAClBC,QACAZ,YAAsB;CAEtBY,OAAOC,MAAM,8BAAA;CAGb,IAAIC,MADmBf,0BAA0BC,UAAAA,GACnC;EACVY,OAAOC,MAAM,2BAAA;EACb;CACJ;CAEAD,OAAOC,MAAM,uBAAA;CACb,MAAMf,0BAA0BE,UAAAA;CAChCY,OAAOC,MAAM,mBAAA;AACjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../src/app/modules/database/module.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,oBAAoB,EAIvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,UAAU,EAAmB,MAAM,SAAS,CAAC;AAMtD,OAAO,EACH,wBAAwB,EAM3B,MAAM,qCAAqC,CAAC;AAO7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIrC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGxC,MAAM,MAAM,qBAAqB,GAAG;IAChC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E,CAAC;AAEF,qBAAa,cAAe,YAAW,OAAO;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAEhC,SAAS,CAAC,cAAc,EAAG,wBAAwB,CAAC;IAEpD,SAAS,CAAC,OAAO,EAAE,qBAAqB,CAAC;IAEzC,SAAS,CAAC,gBAAgB,CAAC,EAAG,WAAW,CAAC;IAE1C,SAAS,CAAC,cAAc,CAAC,EAAG,oBAAoB,CAAC;gBAErC,OAAO,GAAE,qBAA0B;IAQzC,KAAK,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAsD3C,QAAQ,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;cAiBpC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;cActC,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;cAgB/E,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrF;;;;OAIG;cACa,sBAAsB,CAAC,SAAS,EAAE,UAAU,GAAI,OAAO,CAAC,iBAAiB,CAAC;IAgC1F,SAAS,CAAC,oBAAoB,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAI,IAAI;IAiBpF,SAAS,CAAC,sBAAsB,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAkC9E,SAAS,CAAC,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;CAmBzE"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../src/app/modules/database/module.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,oBAAoB,EAIvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,UAAU,EAAmB,MAAM,SAAS,CAAC;AAMtD,OAAO,EACH,wBAAwB,EAM3B,MAAM,qCAAqC,CAAC;AAQ7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIrC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGxC,MAAM,MAAM,qBAAqB,GAAG;IAChC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E,CAAC;AAEF,qBAAa,cAAe,YAAW,OAAO;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAEhC,SAAS,CAAC,cAAc,EAAG,wBAAwB,CAAC;IAEpD,SAAS,CAAC,OAAO,EAAE,qBAAqB,CAAC;IAEzC,SAAS,CAAC,gBAAgB,CAAC,EAAG,WAAW,CAAC;IAE1C,SAAS,CAAC,cAAc,CAAC,EAAG,oBAAoB,CAAC;gBAErC,OAAO,GAAE,qBAA0B;IAQzC,KAAK,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAsD3C,QAAQ,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;cAiBpC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;cActC,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;cAgB/E,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrF;;;;OAIG;cACa,sBAAsB,CAAC,SAAS,EAAE,UAAU,GAAI,OAAO,CAAC,iBAAiB,CAAC;IAmC1F,SAAS,CAAC,oBAAoB,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAI,IAAI;IAiBpF,SAAS,CAAC,sBAAsB,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAoC9E,SAAS,CAAC,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;CAmBzE"}
@@ -10,19 +10,20 @@ import "../../../core/index.mjs";
10
10
  import { CacheInjectionKey } from "../cache/constants.mjs";
11
11
  import { ModuleName } from "../constants.mjs";
12
12
  import { ConfigInjectionKey } from "../config/constants.mjs";
13
- import { useRequestEventContext } from "../../../adapters/http/request/event-context.mjs";
14
- import "../../../adapters/http/request/index.mjs";
15
13
  import "../config/index.mjs";
16
14
  import "../cache/index.mjs";
15
+ import { LoggerInjectionKey } from "../logger/constants.mjs";
16
+ import "../logger/index.mjs";
17
17
  import { DatabaseQueryResultCache } from "../../../adapters/database/cache/module.mjs";
18
18
  import { DataSourceOptionsBuilder } from "../../../adapters/database/data-source/options/module.mjs";
19
19
  import "../../../adapters/database/index.mjs";
20
20
  import { EventRepositoryAdapter } from "./repositories/event/repository.mjs";
21
21
  import "./repositories/index.mjs";
22
22
  import { DatabaseInjectionKey } from "./constants.mjs";
23
+ import { verifySchemaOrSynchronize } from "./migration.mjs";
24
+ import { useRequestEventContext } from "../../../adapters/http/request/event-context.mjs";
25
+ import "../../../adapters/http/request/index.mjs";
23
26
  import { validateEntitySchemas } from "./repositories/schema-validation.mjs";
24
- import { LoggerInjectionKey } from "../logger/constants.mjs";
25
- import "../logger/index.mjs";
26
27
  import { DataSource, InstanceChecker } from "typeorm";
27
28
  import { DomainEventPublisher, DomainEventRedisHandler, DomainEventSocketHandler, createRedisClient } from "@authup/server-kit";
28
29
  import { AuthupError } from "@authup/errors";
@@ -103,7 +104,12 @@ var DatabaseModule = class {
103
104
  }
104
105
  }
105
106
  async migrate(container, dataSource) {
107
+ const config = container.resolve(ConfigInjectionKey);
106
108
  const logger = container.resolve(LoggerInjectionKey);
109
+ if (!config.migrationEnabled) {
110
+ await verifySchemaOrSynchronize(logger, dataSource);
111
+ return;
112
+ }
107
113
  logger.debug("Migrating database...");
108
114
  await synchronizeDatabaseSchema(dataSource);
109
115
  logger.debug("Migrated database");
@@ -116,9 +122,9 @@ var DatabaseModule = class {
116
122
  const config = container.resolve(ConfigInjectionKey);
117
123
  let options;
118
124
  if (config.db) options = this.optionsBuilder.buildWith(config.db);
119
- else options = this.optionsBuilder.buildWithEnv();
125
+ else options = this.optionsBuilder.buildWithEnvOrDefault();
120
126
  if (!isDatabaseTypeSupported(options.type)) throw new AuthupError(`Database type ${options.type} is not supported (only: mysql, better-sqlite3 and postgres).`);
121
- if (!isDatabaseTypeSupportedForEnvironment(options.type, config.env)) throw new AuthupError(`Database type ${options.type} is not supported for ${config.env}.`);
127
+ if (!isDatabaseTypeSupportedForEnvironment(options.type, config.env)) throw new AuthupError(`Database type "${options.type}" is not supported in the ${config.env} environment. Set DB_TYPE to "postgres" or "mysql" together with DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD and DB_DATABASE, or declare "db" in authup.yml. With no database configured at all, "better-sqlite3" is the fallback.`);
122
128
  const cacheResult = container.tryResolve(CacheInjectionKey);
123
129
  if (cacheResult.success) Object.assign(options, { cache: { provider() {
124
130
  return new DatabaseQueryResultCache(cacheResult.data);
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":["DomainEventPublisher","DomainEventRedisHandler","DomainEventSocketHandler","createRedisClient","AuthupError","DataSource","InstanceChecker","checkDatabase","createDatabase","synchronizeDatabaseSchema","DataSourceOptionsBuilder","DatabaseQueryResultCache","EntitySubscriber","EventEntity","isDatabaseTypeSupported","isDatabaseTypeSupportedForEnvironment","EntityEventHandler","EventService","useRequestEventContext","EventRepositoryAdapter","validateEntitySchemas","CacheInjectionKey","ModuleName","DatabaseInjectionKey","ConfigInjectionKey","LoggerInjectionKey","DatabaseModule","name","dependencies","optionsBuilder","options","eventRedisClient","eventPublisher","DATABASE","CONFIG","LOGGER","setup","container","logger","resolve","prepareBuild","dataSourceOptions","buildDataSourceOptions","setupDatabase","dataSource","debug","initialize","migrate","registerRepositories","registerEvents","registerEventPublisher","register","useValue","e","isInitialized","destroy","disposeEventPublisher","cleanupError","warn","teardown","tryResolve","success","data","unregister","EventRepository","dispose","undefined","disconnect","check","exists","synchronize","ifNotExist","config","db","buildWith","buildWithEnv","type","env","cacheResult","Object","assign","cache","provider","entities","Array","isArray","entity","isEntitySchema","useFactory","getRepository","publisher","redis","client","eventLogEnabled","eventLogEntityEnabled","eventService","requestContext","retentionDays","eventLogEntityRetentionDays","i","subscribers","length","subscriber","setPublisher","repository","service","enabled","eventLogRetentionDays"],"sources":["../../../../src/app/modules/database/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n DomainEventPublisher,\n DomainEventRedisHandler,\n DomainEventSocketHandler,\n createRedisClient,\n} from '@authup/server-kit';\nimport type { RedisClient } from '@authup/server-kit';\nimport { AuthupError } from '@authup/errors';\nimport type { DataSourceOptions } from 'typeorm';\nimport { DataSource, InstanceChecker } from 'typeorm';\nimport {\n checkDatabase,\n createDatabase,\n synchronizeDatabaseSchema,\n} from 'typeorm-extension';\nimport {\n DataSourceOptionsBuilder,\n DatabaseQueryResultCache,\n EntitySubscriber,\n EventEntity,\n isDatabaseTypeSupported,\n isDatabaseTypeSupportedForEnvironment,\n} from '../../../adapters/database/index.ts';\nimport type { Event } from '@authup/core-kit';\nimport { EntityEventHandler, EventService } from '../../../core/index.ts';\nimport { useRequestEventContext } from '../../../adapters/http/request/index.ts';\nimport { EventRepositoryAdapter } from './repositories/index.ts';\nimport { validateEntitySchemas } from './repositories/schema-validation.ts';\nimport { CacheInjectionKey } from '../cache/index.ts';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport { DatabaseInjectionKey } from './constants.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport type { IContainer } from 'eldin';\nimport { LoggerInjectionKey } from '../logger/index.ts';\n\nexport type DatabaseModuleOptions = {\n prepareBuild?: (container: IContainer) => Promise<void>;\n setup?: (container: IContainer, options: DataSourceOptions) => Promise<void>;\n migrate?: (container: IContainer, dataSource: DataSource) => Promise<void>;\n};\n\nexport class DatabaseModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n protected optionsBuilder : DataSourceOptionsBuilder;\n\n protected options: DatabaseModuleOptions;\n\n protected eventRedisClient? : RedisClient;\n\n protected eventPublisher? : DomainEventPublisher;\n\n constructor(options: DatabaseModuleOptions = {}) {\n this.name = ModuleName.DATABASE;\n this.dependencies = [ModuleName.CONFIG, ModuleName.LOGGER];\n\n this.optionsBuilder = new DataSourceOptionsBuilder();\n this.options = options;\n }\n\n async setup(container: IContainer): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n if (this.options.prepareBuild) {\n await this.options.prepareBuild(container);\n }\n\n const dataSourceOptions = await this.buildDataSourceOptions(container);\n\n if (this.options.setup) {\n await this.options.setup(container, dataSourceOptions);\n } else {\n await this.setupDatabase(container, dataSourceOptions);\n }\n\n const dataSource = new DataSource(dataSourceOptions);\n\n logger.debug('Establishing database connection...');\n await dataSource.initialize();\n logger.debug('Established database connection.');\n\n try {\n if (this.options.migrate) {\n await this.options.migrate(container, dataSource);\n } else {\n await this.migrate(container, dataSource);\n }\n\n validateEntitySchemas(dataSource);\n this.registerRepositories(container, dataSource);\n // the event service must exist before the publisher wiring — the\n // entity-CRUD bridge handler resolves it from the container.\n this.registerEvents(container, dataSource);\n this.registerEventPublisher(container, dataSource);\n\n container.register(DatabaseInjectionKey.DataSource, { useValue: dataSource });\n } catch (e) {\n // teardown() is skipped for a module that fails its own setup(),\n // so release the connection pool and any event-publisher handles\n // here. Guard cleanup so it can never mask the original error.\n try {\n if (dataSource.isInitialized) {\n await dataSource.destroy();\n }\n\n await this.disposeEventPublisher();\n } catch (cleanupError) {\n logger.warn(`Failed to clean up database resources after setup error: ${cleanupError}`);\n }\n\n throw e;\n }\n }\n\n async teardown(container: IContainer): Promise<void> {\n const dataSource = container.tryResolve(DatabaseInjectionKey.DataSource);\n if (dataSource.success) {\n if (dataSource.data.isInitialized) {\n await dataSource.data.destroy();\n }\n\n container.unregister(DatabaseInjectionKey.DataSource);\n }\n\n container.unregister(DatabaseInjectionKey.DomainEventPublisher);\n container.unregister(DatabaseInjectionKey.EventRepository);\n container.unregister(DatabaseInjectionKey.EventService);\n\n await this.disposeEventPublisher();\n }\n\n protected async disposeEventPublisher(): Promise<void> {\n if (this.eventPublisher) {\n await this.eventPublisher.dispose();\n this.eventPublisher = undefined;\n }\n\n if (this.eventRedisClient) {\n this.eventRedisClient.disconnect();\n this.eventRedisClient = undefined;\n }\n }\n\n // ----------------------------------------------------\n\n protected async setupDatabase(container: IContainer, options: DataSourceOptions): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n const check = await checkDatabase({ options });\n\n if (!check.exists) {\n logger.debug('Creating database...');\n await createDatabase({\n options,\n synchronize: false,\n ifNotExist: true, \n });\n logger.debug('Created database');\n }\n }\n\n protected async migrate(container: IContainer, dataSource: DataSource): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n logger.debug('Migrating database...');\n await synchronizeDatabaseSchema(dataSource);\n logger.debug('Migrated database');\n }\n\n // ----------------------------------------------------\n\n /**\n * Load data source options for connection.\n *\n * @protected\n */\n protected async buildDataSourceOptions(container: IContainer) : Promise<DataSourceOptions> {\n const config = container.resolve(ConfigInjectionKey);\n\n let options : DataSourceOptions | undefined;\n if (config.db) {\n options = this.optionsBuilder.buildWith(config.db);\n } else {\n options = this.optionsBuilder.buildWithEnv();\n }\n\n if (!isDatabaseTypeSupported(options.type)) {\n throw new AuthupError(`Database type ${options.type} is not supported (only: mysql, better-sqlite3 and postgres).`);\n }\n\n if (!isDatabaseTypeSupportedForEnvironment(options.type, config.env)) {\n throw new AuthupError(`Database type ${options.type} is not supported for ${config.env}.`);\n }\n\n const cacheResult = container.tryResolve(CacheInjectionKey);\n if (cacheResult.success) {\n Object.assign(options, {\n cache: {\n provider() {\n return new DatabaseQueryResultCache(cacheResult.data);\n },\n },\n } satisfies Partial<DataSourceOptions>);\n }\n\n return options;\n }\n\n protected registerRepositories(container: IContainer, dataSource: DataSource) : void {\n const entities = dataSource.options.entities || [];\n if (!Array.isArray(entities)) {\n return;\n }\n\n for (const entity of entities) {\n if (InstanceChecker.isEntitySchema(entity)) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n container.register(entity, { useFactory: () => dataSource.getRepository(entity) });\n }\n }\n\n protected registerEventPublisher(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const publisher = new DomainEventPublisher({ logger });\n this.eventPublisher = publisher;\n if (config.redis) {\n const client = createRedisClient(config.redis);\n if (client !== config.redis) {\n this.eventRedisClient = client;\n }\n\n publisher.register(new DomainEventRedisHandler(client));\n publisher.register(new DomainEventSocketHandler(client));\n }\n\n if (config.eventLogEnabled && config.eventLogEntityEnabled) {\n publisher.register(new EntityEventHandler({\n eventService: container.resolve(DatabaseInjectionKey.EventService),\n requestContext: useRequestEventContext,\n options: { retentionDays: config.eventLogEntityRetentionDays },\n }));\n }\n\n container.register(DatabaseInjectionKey.DomainEventPublisher, { useValue: publisher });\n\n for (let i = 0; i < dataSource.subscribers.length; i++) {\n const subscriber = dataSource.subscribers[i];\n if (subscriber instanceof EntitySubscriber) {\n subscriber.setPublisher(publisher);\n }\n }\n }\n\n protected registerEvents(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const repository = new EventRepositoryAdapter(\n dataSource.getRepository<Event>(EventEntity),\n );\n container.register(DatabaseInjectionKey.EventRepository, { useValue: repository });\n\n const service = new EventService({\n repository,\n options: {\n enabled: config.eventLogEnabled,\n retentionDays: config.eventLogRetentionDays,\n },\n logger,\n });\n container.register(DatabaseInjectionKey.EventService, { useValue: service });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"module.mjs","names":["DomainEventPublisher","DomainEventRedisHandler","DomainEventSocketHandler","createRedisClient","AuthupError","DataSource","InstanceChecker","checkDatabase","createDatabase","synchronizeDatabaseSchema","DataSourceOptionsBuilder","DatabaseQueryResultCache","EntitySubscriber","EventEntity","isDatabaseTypeSupported","isDatabaseTypeSupportedForEnvironment","EntityEventHandler","EventService","useRequestEventContext","EventRepositoryAdapter","validateEntitySchemas","verifySchemaOrSynchronize","CacheInjectionKey","ModuleName","DatabaseInjectionKey","ConfigInjectionKey","LoggerInjectionKey","DatabaseModule","name","dependencies","optionsBuilder","options","eventRedisClient","eventPublisher","DATABASE","CONFIG","LOGGER","setup","container","logger","resolve","prepareBuild","dataSourceOptions","buildDataSourceOptions","setupDatabase","dataSource","debug","initialize","migrate","registerRepositories","registerEvents","registerEventPublisher","register","useValue","e","isInitialized","destroy","disposeEventPublisher","cleanupError","warn","teardown","tryResolve","success","data","unregister","EventRepository","dispose","undefined","disconnect","check","exists","synchronize","ifNotExist","config","migrationEnabled","db","buildWith","buildWithEnvOrDefault","type","env","cacheResult","Object","assign","cache","provider","entities","Array","isArray","entity","isEntitySchema","useFactory","getRepository","publisher","redis","client","eventLogEnabled","eventLogEntityEnabled","eventService","requestContext","retentionDays","eventLogEntityRetentionDays","i","subscribers","length","subscriber","setPublisher","repository","service","enabled","eventLogRetentionDays"],"sources":["../../../../src/app/modules/database/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n DomainEventPublisher,\n DomainEventRedisHandler,\n DomainEventSocketHandler,\n createRedisClient,\n} from '@authup/server-kit';\nimport type { RedisClient } from '@authup/server-kit';\nimport { AuthupError } from '@authup/errors';\nimport type { DataSourceOptions } from 'typeorm';\nimport { DataSource, InstanceChecker } from 'typeorm';\nimport {\n checkDatabase,\n createDatabase,\n synchronizeDatabaseSchema,\n} from 'typeorm-extension';\nimport {\n DataSourceOptionsBuilder,\n DatabaseQueryResultCache,\n EntitySubscriber,\n EventEntity,\n isDatabaseTypeSupported,\n isDatabaseTypeSupportedForEnvironment,\n} from '../../../adapters/database/index.ts';\nimport type { Event } from '@authup/core-kit';\nimport { EntityEventHandler, EventService } from '../../../core/index.ts';\nimport { useRequestEventContext } from '../../../adapters/http/request/index.ts';\nimport { EventRepositoryAdapter } from './repositories/index.ts';\nimport { validateEntitySchemas } from './repositories/schema-validation.ts';\nimport { verifySchemaOrSynchronize } from './migration.ts';\nimport { CacheInjectionKey } from '../cache/index.ts';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport { DatabaseInjectionKey } from './constants.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport type { IContainer } from 'eldin';\nimport { LoggerInjectionKey } from '../logger/index.ts';\n\nexport type DatabaseModuleOptions = {\n prepareBuild?: (container: IContainer) => Promise<void>;\n setup?: (container: IContainer, options: DataSourceOptions) => Promise<void>;\n migrate?: (container: IContainer, dataSource: DataSource) => Promise<void>;\n};\n\nexport class DatabaseModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n protected optionsBuilder : DataSourceOptionsBuilder;\n\n protected options: DatabaseModuleOptions;\n\n protected eventRedisClient? : RedisClient;\n\n protected eventPublisher? : DomainEventPublisher;\n\n constructor(options: DatabaseModuleOptions = {}) {\n this.name = ModuleName.DATABASE;\n this.dependencies = [ModuleName.CONFIG, ModuleName.LOGGER];\n\n this.optionsBuilder = new DataSourceOptionsBuilder();\n this.options = options;\n }\n\n async setup(container: IContainer): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n if (this.options.prepareBuild) {\n await this.options.prepareBuild(container);\n }\n\n const dataSourceOptions = await this.buildDataSourceOptions(container);\n\n if (this.options.setup) {\n await this.options.setup(container, dataSourceOptions);\n } else {\n await this.setupDatabase(container, dataSourceOptions);\n }\n\n const dataSource = new DataSource(dataSourceOptions);\n\n logger.debug('Establishing database connection...');\n await dataSource.initialize();\n logger.debug('Established database connection.');\n\n try {\n if (this.options.migrate) {\n await this.options.migrate(container, dataSource);\n } else {\n await this.migrate(container, dataSource);\n }\n\n validateEntitySchemas(dataSource);\n this.registerRepositories(container, dataSource);\n // the event service must exist before the publisher wiring — the\n // entity-CRUD bridge handler resolves it from the container.\n this.registerEvents(container, dataSource);\n this.registerEventPublisher(container, dataSource);\n\n container.register(DatabaseInjectionKey.DataSource, { useValue: dataSource });\n } catch (e) {\n // teardown() is skipped for a module that fails its own setup(),\n // so release the connection pool and any event-publisher handles\n // here. Guard cleanup so it can never mask the original error.\n try {\n if (dataSource.isInitialized) {\n await dataSource.destroy();\n }\n\n await this.disposeEventPublisher();\n } catch (cleanupError) {\n logger.warn(`Failed to clean up database resources after setup error: ${cleanupError}`);\n }\n\n throw e;\n }\n }\n\n async teardown(container: IContainer): Promise<void> {\n const dataSource = container.tryResolve(DatabaseInjectionKey.DataSource);\n if (dataSource.success) {\n if (dataSource.data.isInitialized) {\n await dataSource.data.destroy();\n }\n\n container.unregister(DatabaseInjectionKey.DataSource);\n }\n\n container.unregister(DatabaseInjectionKey.DomainEventPublisher);\n container.unregister(DatabaseInjectionKey.EventRepository);\n container.unregister(DatabaseInjectionKey.EventService);\n\n await this.disposeEventPublisher();\n }\n\n protected async disposeEventPublisher(): Promise<void> {\n if (this.eventPublisher) {\n await this.eventPublisher.dispose();\n this.eventPublisher = undefined;\n }\n\n if (this.eventRedisClient) {\n this.eventRedisClient.disconnect();\n this.eventRedisClient = undefined;\n }\n }\n\n // ----------------------------------------------------\n\n protected async setupDatabase(container: IContainer, options: DataSourceOptions): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n const check = await checkDatabase({ options });\n\n if (!check.exists) {\n logger.debug('Creating database...');\n await createDatabase({\n options,\n synchronize: false,\n ifNotExist: true, \n });\n logger.debug('Created database');\n }\n }\n\n protected async migrate(container: IContainer, dataSource: DataSource): Promise<void> {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n if (!config.migrationEnabled) {\n await verifySchemaOrSynchronize(logger, dataSource);\n return;\n }\n\n logger.debug('Migrating database...');\n await synchronizeDatabaseSchema(dataSource);\n logger.debug('Migrated database');\n }\n\n // ----------------------------------------------------\n\n /**\n * Load data source options for connection.\n *\n * @protected\n */\n protected async buildDataSourceOptions(container: IContainer) : Promise<DataSourceOptions> {\n const config = container.resolve(ConfigInjectionKey);\n\n let options : DataSourceOptions | undefined;\n if (config.db) {\n // the configuration surface is deliberately untyped: `db` is\n // authup's own loose shape, and the supported-dialect assertion\n // below is what narrows it.\n options = this.optionsBuilder.buildWith(config.db as DataSourceOptions);\n } else {\n options = this.optionsBuilder.buildWithEnvOrDefault();\n }\n\n if (!isDatabaseTypeSupported(options.type)) {\n throw new AuthupError(`Database type ${options.type} is not supported (only: mysql, better-sqlite3 and postgres).`);\n }\n\n if (!isDatabaseTypeSupportedForEnvironment(options.type, config.env)) {\n throw new AuthupError(`Database type \"${options.type}\" is not supported in the ${config.env} environment. Set DB_TYPE to \"postgres\" or \"mysql\" together with DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD and DB_DATABASE, or declare \"db\" in authup.yml. With no database configured at all, \"better-sqlite3\" is the fallback.`);\n }\n\n const cacheResult = container.tryResolve(CacheInjectionKey);\n if (cacheResult.success) {\n Object.assign(options, {\n cache: {\n provider() {\n return new DatabaseQueryResultCache(cacheResult.data);\n },\n },\n } satisfies Partial<DataSourceOptions>);\n }\n\n return options;\n }\n\n protected registerRepositories(container: IContainer, dataSource: DataSource) : void {\n const entities = dataSource.options.entities || [];\n if (!Array.isArray(entities)) {\n return;\n }\n\n for (const entity of entities) {\n if (InstanceChecker.isEntitySchema(entity)) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n container.register(entity, { useFactory: () => dataSource.getRepository(entity) });\n }\n }\n\n protected registerEventPublisher(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const publisher = new DomainEventPublisher({ logger });\n this.eventPublisher = publisher;\n if (config.redis) {\n // the configuration surface is deliberately untyped: the object\n // arm of `redis` is opaque, and the client owns its real shape.\n const client = createRedisClient(config.redis);\n if (client !== config.redis) {\n this.eventRedisClient = client;\n }\n\n publisher.register(new DomainEventRedisHandler(client));\n publisher.register(new DomainEventSocketHandler(client));\n }\n\n if (config.eventLogEnabled && config.eventLogEntityEnabled) {\n publisher.register(new EntityEventHandler({\n eventService: container.resolve(DatabaseInjectionKey.EventService),\n requestContext: useRequestEventContext,\n options: { retentionDays: config.eventLogEntityRetentionDays },\n }));\n }\n\n container.register(DatabaseInjectionKey.DomainEventPublisher, { useValue: publisher });\n\n for (let i = 0; i < dataSource.subscribers.length; i++) {\n const subscriber = dataSource.subscribers[i];\n if (subscriber instanceof EntitySubscriber) {\n subscriber.setPublisher(publisher);\n }\n }\n }\n\n protected registerEvents(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const repository = new EventRepositoryAdapter(\n dataSource.getRepository<Event>(EventEntity),\n );\n container.register(DatabaseInjectionKey.EventRepository, { useValue: repository });\n\n const service = new EventService({\n repository,\n options: {\n enabled: config.eventLogEnabled,\n retentionDays: config.eventLogRetentionDays,\n },\n logger,\n });\n container.register(DatabaseInjectionKey.EventService, { useValue: service });\n }\n}\n"],"mappings":"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"}
@@ -8,10 +8,14 @@ export type ClientRepositoryAdapterContext = {
8
8
  repository: Repository<Client>;
9
9
  realmRepository: Repository<Realm>;
10
10
  };
11
+ export type ClientRepositoryAdapterOptions = {
12
+ lockRows?: boolean;
13
+ };
11
14
  export declare class ClientRepositoryAdapter implements IClientRepository {
12
15
  private readonly repository;
13
16
  private readonly realmRepository;
14
- constructor(ctx: ClientRepositoryAdapterContext);
17
+ private readonly lockRows;
18
+ constructor(ctx: ClientRepositoryAdapterContext, options?: ClientRepositoryAdapterOptions);
15
19
  findMany(query: IQuery): Promise<EntityRepositoryFindManyResult<Client>>;
16
20
  findOneById(id: string): Promise<Client | null>;
17
21
  findOneByName(name: string, realmKey?: string): Promise<Client | null>;
@@ -24,6 +28,7 @@ export declare class ClientRepositoryAdapter implements IClientRepository {
24
28
  merge(entity: Client, data: Partial<Client>): Client;
25
29
  save(entity: Client): Promise<Client>;
26
30
  remove(entity: Client): Promise<void>;
31
+ transaction<R>(fn: (repository: IClientRepository) => Promise<R>): Promise<R>;
27
32
  validateJoinColumns(data: Partial<Client>): Promise<void>;
28
33
  checkUniqueness(data: Partial<Client>, existing?: Client): Promise<void>;
29
34
  getBoundRoles(entity: string | Client): Promise<Role[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../../src/app/modules/database/repositories/client/repository.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAoB,MAAM,8BAA8B,CAAC;AAYxF,MAAM,MAAM,8BAA8B,GAAG;IACzC,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAC/B,eAAe,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;CACtC,CAAC;AAEF,qBAAa,uBAAwB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAEhD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmB;gBAEvC,GAAG,EAAE,8BAA8B;IAKzC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IAiB9E,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIzC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAetE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAsB9E,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAM3E,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzD,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI7D,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAY3E,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;IAIrC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;IAI9C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOzD,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAaxE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAmBvD,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC;CAUzF"}
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../../src/app/modules/database/repositories/client/repository.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,17 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
+ import { isDatabaseTypeRowLockable } from "../../../../../adapters/database/helpers/is-supported.mjs";
5
+ import "../../../../../adapters/database/helpers/index.mjs";
6
+ import { RealmEntity } from "../../../../../adapters/database/domains/realm/entity.mjs";
4
7
  import { CachePrefix } from "../../../../../adapters/database/domains/constants.mjs";
5
8
  import { ClientEntity } from "../../../../../adapters/database/domains/client/entity.mjs";
6
9
  import { ClientRoleEntity } from "../../../../../adapters/database/domains/client-role/entity.mjs";
7
10
  import { ClientPermissionEntity } from "../../../../../adapters/database/domains/client-permission/entity.mjs";
8
11
  import "../../../../../adapters/database/domains/index.mjs";
9
12
  import { applyQuery, redactFieldConditions } from "../query.mjs";
10
- import { isEntityUnique, translateWhereConditions } from "../helpers.mjs";
11
13
  import { DatabaseConflictError } from "../../../../../adapters/database/errors/conflict.mjs";
14
+ import { isEntityUnique, translateWhereConditions } from "../helpers.mjs";
12
15
  import "../../../../../adapters/database/index.mjs";
13
16
  import { loadBoundPermissions } from "../bindings.mjs";
14
17
  import { RealmRepositoryAdapter } from "../realm/repository.mjs";
@@ -16,12 +19,14 @@ import { isUUID } from "@authup/kit";
16
19
  import { buildRedisKeyPath } from "@authup/server-kit";
17
20
  import { validateEntityJoinColumns } from "typeorm-extension";
18
21
  //#region src/app/modules/database/repositories/client/repository.ts
19
- var ClientRepositoryAdapter = class {
22
+ var ClientRepositoryAdapter = class ClientRepositoryAdapter {
20
23
  repository;
21
24
  realmRepository;
22
- constructor(ctx) {
25
+ lockRows;
26
+ constructor(ctx, options = {}) {
23
27
  this.repository = ctx.repository;
24
28
  this.realmRepository = new RealmRepositoryAdapter(ctx.realmRepository);
29
+ this.lockRows = options.lockRows ?? false;
25
30
  }
26
31
  async findMany(query) {
27
32
  const qb = this.repository.createQueryBuilder("client");
@@ -70,7 +75,10 @@ var ClientRepositoryAdapter = class {
70
75
  return this.repository.findBy(translateWhereConditions(where));
71
76
  }
72
77
  async findOneBy(where) {
73
- return this.repository.findOneBy(translateWhereConditions(where));
78
+ return this.repository.findOne({
79
+ where: translateWhereConditions(where),
80
+ ...this.lockRows ? { lock: { mode: "pessimistic_write" } } : {}
81
+ });
74
82
  }
75
83
  async findOneWithSecret(where) {
76
84
  const qb = this.repository.createQueryBuilder("client");
@@ -78,6 +86,7 @@ var ClientRepositoryAdapter = class {
78
86
  qb.andWhere(`client.${key} = :${key}`, { [key]: value });
79
87
  });
80
88
  qb.addSelect("client.secret");
89
+ if (this.lockRows) qb.setLock("pessimistic_write");
81
90
  return qb.getOne();
82
91
  }
83
92
  create(data) {
@@ -92,6 +101,14 @@ var ClientRepositoryAdapter = class {
92
101
  async remove(entity) {
93
102
  await this.repository.remove(entity);
94
103
  }
104
+ async transaction(fn) {
105
+ const dataSource = this.repository.manager.connection;
106
+ if (!isDatabaseTypeRowLockable(dataSource.options.type)) return fn(this);
107
+ return dataSource.transaction((manager) => fn(new ClientRepositoryAdapter({
108
+ repository: manager.getRepository(ClientEntity),
109
+ realmRepository: manager.getRepository(RealmEntity)
110
+ }, { lockRows: true })));
111
+ }
95
112
  async validateJoinColumns(data) {
96
113
  await validateEntityJoinColumns(data, {
97
114
  dataSource: this.repository.manager.connection,
@@ -1 +1 @@
1
- {"version":3,"file":"repository.mjs","names":["buildRedisKeyPath","isUUID","validateEntityJoinColumns","applyQuery","redactFieldConditions","DatabaseConflictError","isEntityUnique","translateWhereConditions","loadBoundPermissions","CachePrefix","ClientEntity","ClientPermissionEntity","ClientRoleEntity","RealmRepositoryAdapter","ClientRepositoryAdapter","repository","realmRepository","ctx","findMany","query","qb","createQueryBuilder","groupBy","pagination","entities","total","getManyAndCount","data","meta","findOneById","id","findOneBy","findOneByName","name","realmKey","where","realmId","resolveId","andWhere","getOne","findOne","findOneByIdOrName","idOrName","realm","findManyBy","findBy","findOneWithSecret","Object","entries","forEach","key","value","addSelect","create","merge","entity","save","remove","validateJoinColumns","dataSource","manager","connection","entityTarget","checkUniqueness","existing","isUnique","entityExisting","getBoundRoles","getRepository","find","clientId","relations","role","cache","prefix","CLIENT_OWNED_ROLES","milliseconds","map","entry","getBoundPermissions","junctionTarget","cachePrefix","CLIENT_OWNED_PERMISSIONS","cacheKey"],"sources":["../../../../../../src/app/modules/database/repositories/client/repository.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Client, Realm, Role } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { PermissionPolicyBinding } from '@authup/access';\nimport { buildRedisKeyPath } from '@authup/server-kit';\nimport { isUUID } from '@authup/kit';\nimport type { Repository } from 'typeorm';\nimport { validateEntityJoinColumns } from 'typeorm-extension';\nimport { applyQuery, redactFieldConditions } from '../query.ts';\nimport type { EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IClientRepository, IRealmRepository } from '../../../../../core/index.ts';\nimport { DatabaseConflictError } from '../../../../../adapters/database/index.ts';\nimport { isEntityUnique, translateWhereConditions } from '../helpers.ts';\nimport { loadBoundPermissions } from '../bindings.ts';\nimport {\n CachePrefix,\n ClientEntity,\n ClientPermissionEntity,\n ClientRoleEntity,\n} from '../../../../../adapters/database/domains/index.ts';\nimport { RealmRepositoryAdapter } from '../realm/repository.ts';\n\nexport type ClientRepositoryAdapterContext = {\n repository: Repository<Client>,\n realmRepository: Repository<Realm>,\n};\n\nexport class ClientRepositoryAdapter implements IClientRepository {\n private readonly repository: Repository<Client>;\n\n private readonly realmRepository: IRealmRepository;\n\n constructor(ctx: ClientRepositoryAdapterContext) {\n this.repository = ctx.repository;\n this.realmRepository = new RealmRepositoryAdapter(ctx.realmRepository);\n }\n\n async findMany(query: IQuery): Promise<EntityRepositoryFindManyResult<Client>> {\n const qb = this.repository.createQueryBuilder('client');\n qb.groupBy('client.id');\n\n const { pagination } = applyQuery(qb, query);\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: redactFieldConditions(query, entities),\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n findOneById(id: string): Promise<Client | null> {\n return this.findOneBy({ id });\n }\n\n async findOneByName(name: string, realmKey?: string): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n qb.where('client.name = :name', { name });\n\n if (realmKey) {\n const realmId = await this.realmRepository.resolveId(realmKey);\n if (!realmId) {\n return null;\n }\n qb.andWhere('client.realmId = :realmId', { realmId });\n }\n\n return qb.getOne();\n }\n\n async findOne(id: string, query?: IQuery, realmKey?: string): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n\n if (isUUID(id)) {\n qb.where('client.id = :id', { id });\n } else {\n qb.where('client.name = :name', { name: id });\n\n if (realmKey) {\n const realmId = await this.realmRepository.resolveId(realmKey);\n if (!realmId) {\n return null;\n }\n qb.andWhere('client.realmId = :realmId', { realmId });\n }\n }\n\n applyQuery(qb, query);\n\n return qb.getOne();\n }\n\n async findOneByIdOrName(idOrName: string, realm?: string): Promise<Client | null> {\n return isUUID(idOrName) ?\n this.findOneById(idOrName) :\n this.findOneByName(idOrName, realm);\n }\n\n async findManyBy(where: Record<string, any>): Promise<Client[]> {\n return this.repository.findBy(translateWhereConditions(where));\n }\n\n async findOneBy(where: Record<string, any>): Promise<Client | null> {\n return this.repository.findOneBy(translateWhereConditions(where));\n }\n\n async findOneWithSecret(where: Record<string, any>): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n\n Object.entries(where).forEach(([key, value]) => {\n qb.andWhere(`client.${key} = :${key}`, { [key]: value });\n });\n\n qb.addSelect('client.secret');\n\n return qb.getOne();\n }\n\n create(data: Partial<Client>): Client {\n return this.repository.create(data);\n }\n\n merge(entity: Client, data: Partial<Client>): Client {\n return this.repository.merge(entity, data);\n }\n\n async save(entity: Client): Promise<Client> {\n return this.repository.save(entity);\n }\n\n async remove(entity: Client): Promise<void> {\n await this.repository.remove(entity);\n }\n\n async validateJoinColumns(data: Partial<Client>): Promise<void> {\n await validateEntityJoinColumns(data, {\n dataSource: this.repository.manager.connection,\n entityTarget: ClientEntity,\n });\n }\n\n async checkUniqueness(data: Partial<Client>, existing?: Client): Promise<void> {\n const isUnique = await isEntityUnique({\n dataSource: this.repository.manager.connection,\n entityTarget: ClientEntity,\n entity: data,\n entityExisting: existing,\n });\n\n if (!isUnique) {\n throw new DatabaseConflictError();\n }\n }\n\n async getBoundRoles(entity: string | Client): Promise<Role[]> {\n const id = typeof entity === 'string' ? entity : entity.id;\n const entries = await this.repository.manager\n .getRepository(ClientRoleEntity)\n .find({\n where: { clientId: id },\n relations: { role: true },\n cache: {\n id: buildRedisKeyPath({\n prefix: CachePrefix.CLIENT_OWNED_ROLES,\n key: id,\n }),\n milliseconds: 60_000,\n },\n });\n\n return entries.map((entry) => entry.role);\n }\n\n async getBoundPermissions(entity: string | Client): Promise<PermissionPolicyBinding[]> {\n const id = typeof entity === 'string' ? entity : entity.id;\n return loadBoundPermissions({\n manager: this.repository.manager,\n junctionTarget: ClientPermissionEntity,\n where: { clientId: id },\n cachePrefix: CachePrefix.CLIENT_OWNED_PERMISSIONS,\n cacheKey: id,\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"repository.mjs","names":["buildRedisKeyPath","isUUID","validateEntityJoinColumns","applyQuery","redactFieldConditions","DatabaseConflictError","isDatabaseTypeRowLockable","isEntityUnique","translateWhereConditions","loadBoundPermissions","CachePrefix","ClientEntity","ClientPermissionEntity","ClientRoleEntity","RealmEntity","RealmRepositoryAdapter","ClientRepositoryAdapter","repository","realmRepository","lockRows","ctx","options","findMany","query","qb","createQueryBuilder","groupBy","pagination","entities","total","getManyAndCount","data","meta","findOneById","id","findOneBy","findOneByName","name","realmKey","where","realmId","resolveId","andWhere","getOne","findOne","findOneByIdOrName","idOrName","realm","findManyBy","findBy","lock","mode","findOneWithSecret","Object","entries","forEach","key","value","addSelect","setLock","create","merge","entity","save","remove","transaction","fn","dataSource","manager","connection","type","getRepository","validateJoinColumns","entityTarget","checkUniqueness","existing","isUnique","entityExisting","getBoundRoles","find","clientId","relations","role","cache","prefix","CLIENT_OWNED_ROLES","milliseconds","map","entry","getBoundPermissions","junctionTarget","cachePrefix","CLIENT_OWNED_PERMISSIONS","cacheKey"],"sources":["../../../../../../src/app/modules/database/repositories/client/repository.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Client, Realm, Role } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { PermissionPolicyBinding } from '@authup/access';\nimport { buildRedisKeyPath } from '@authup/server-kit';\nimport { isUUID } from '@authup/kit';\nimport type { Repository } from 'typeorm';\nimport { validateEntityJoinColumns } from 'typeorm-extension';\nimport { applyQuery, redactFieldConditions } from '../query.ts';\nimport type { EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IClientRepository, IRealmRepository } from '../../../../../core/index.ts';\nimport { DatabaseConflictError } from '../../../../../adapters/database/index.ts';\nimport { isDatabaseTypeRowLockable } from '../../../../../adapters/database/helpers/index.ts';\nimport { isEntityUnique, translateWhereConditions } from '../helpers.ts';\nimport { loadBoundPermissions } from '../bindings.ts';\nimport {\n CachePrefix,\n ClientEntity,\n ClientPermissionEntity,\n ClientRoleEntity,\n RealmEntity,\n} from '../../../../../adapters/database/domains/index.ts';\nimport { RealmRepositoryAdapter } from '../realm/repository.ts';\n\nexport type ClientRepositoryAdapterContext = {\n repository: Repository<Client>,\n realmRepository: Repository<Realm>,\n};\n\nexport type ClientRepositoryAdapterOptions = {\n lockRows?: boolean,\n};\n\nexport class ClientRepositoryAdapter implements IClientRepository {\n private readonly repository: Repository<Client>;\n\n private readonly realmRepository: IRealmRepository;\n\n private readonly lockRows: boolean;\n\n constructor(ctx: ClientRepositoryAdapterContext, options: ClientRepositoryAdapterOptions = {}) {\n this.repository = ctx.repository;\n this.realmRepository = new RealmRepositoryAdapter(ctx.realmRepository);\n this.lockRows = options.lockRows ?? false;\n }\n\n async findMany(query: IQuery): Promise<EntityRepositoryFindManyResult<Client>> {\n const qb = this.repository.createQueryBuilder('client');\n qb.groupBy('client.id');\n\n const { pagination } = applyQuery(qb, query);\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: redactFieldConditions(query, entities),\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n findOneById(id: string): Promise<Client | null> {\n return this.findOneBy({ id });\n }\n\n async findOneByName(name: string, realmKey?: string): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n qb.where('client.name = :name', { name });\n\n if (realmKey) {\n const realmId = await this.realmRepository.resolveId(realmKey);\n if (!realmId) {\n return null;\n }\n qb.andWhere('client.realmId = :realmId', { realmId });\n }\n\n return qb.getOne();\n }\n\n async findOne(id: string, query?: IQuery, realmKey?: string): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n\n if (isUUID(id)) {\n qb.where('client.id = :id', { id });\n } else {\n qb.where('client.name = :name', { name: id });\n\n if (realmKey) {\n const realmId = await this.realmRepository.resolveId(realmKey);\n if (!realmId) {\n return null;\n }\n qb.andWhere('client.realmId = :realmId', { realmId });\n }\n }\n\n applyQuery(qb, query);\n\n return qb.getOne();\n }\n\n async findOneByIdOrName(idOrName: string, realm?: string): Promise<Client | null> {\n return isUUID(idOrName) ?\n this.findOneById(idOrName) :\n this.findOneByName(idOrName, realm);\n }\n\n async findManyBy(where: Record<string, any>): Promise<Client[]> {\n return this.repository.findBy(translateWhereConditions(where));\n }\n\n async findOneBy(where: Record<string, any>): Promise<Client | null> {\n return this.repository.findOne({\n where: translateWhereConditions(where),\n ...(this.lockRows ? { lock: { mode: 'pessimistic_write' } } : {}),\n });\n }\n\n async findOneWithSecret(where: Record<string, any>): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n\n Object.entries(where).forEach(([key, value]) => {\n qb.andWhere(`client.${key} = :${key}`, { [key]: value });\n });\n\n qb.addSelect('client.secret');\n\n if (this.lockRows) {\n qb.setLock('pessimistic_write');\n }\n\n return qb.getOne();\n }\n\n create(data: Partial<Client>): Client {\n return this.repository.create(data);\n }\n\n merge(entity: Client, data: Partial<Client>): Client {\n return this.repository.merge(entity, data);\n }\n\n async save(entity: Client): Promise<Client> {\n return this.repository.save(entity);\n }\n\n async remove(entity: Client): Promise<void> {\n await this.repository.remove(entity);\n }\n\n async transaction<R>(fn: (repository: IClientRepository) => Promise<R>): Promise<R> {\n const dataSource = this.repository.manager.connection;\n if (!isDatabaseTypeRowLockable(dataSource.options.type)) {\n // better-sqlite3: no FOR UPDATE, and the driver shares ONE query\n // runner, so a transaction here would nest as a savepoint inside\n // whatever else is running on it. Plain unlocked passthrough,\n // exactly as the un-guarded path did (the removeGuarded rule).\n return fn(this);\n }\n\n // mysql / postgres: real concurrency. Hand the callback an adapter\n // bound to the transaction's manager whose single-row reads lock,\n // so the row loaded by save() cannot change under the merge.\n return dataSource.transaction((manager) => fn(new ClientRepositoryAdapter({\n repository: manager.getRepository(ClientEntity),\n realmRepository: manager.getRepository(RealmEntity),\n }, { lockRows: true })));\n }\n\n async validateJoinColumns(data: Partial<Client>): Promise<void> {\n await validateEntityJoinColumns(data, {\n dataSource: this.repository.manager.connection,\n entityTarget: ClientEntity,\n });\n }\n\n async checkUniqueness(data: Partial<Client>, existing?: Client): Promise<void> {\n const isUnique = await isEntityUnique({\n dataSource: this.repository.manager.connection,\n entityTarget: ClientEntity,\n entity: data,\n entityExisting: existing,\n });\n\n if (!isUnique) {\n throw new DatabaseConflictError();\n }\n }\n\n async getBoundRoles(entity: string | Client): Promise<Role[]> {\n const id = typeof entity === 'string' ? entity : entity.id;\n const entries = await this.repository.manager\n .getRepository(ClientRoleEntity)\n .find({\n where: { clientId: id },\n relations: { role: true },\n cache: {\n id: buildRedisKeyPath({\n prefix: CachePrefix.CLIENT_OWNED_ROLES,\n key: id,\n }),\n milliseconds: 60_000,\n },\n });\n\n return entries.map((entry) => entry.role);\n }\n\n async getBoundPermissions(entity: string | Client): Promise<PermissionPolicyBinding[]> {\n const id = typeof entity === 'string' ? entity : entity.id;\n return loadBoundPermissions({\n manager: this.repository.manager,\n junctionTarget: ClientPermissionEntity,\n where: { clientId: id },\n cachePrefix: CachePrefix.CLIENT_OWNED_PERMISSIONS,\n cacheKey: id,\n });\n }\n}\n"],"mappings":"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"}
@@ -2,12 +2,39 @@ import type { Event } from '@authup/core-kit';
2
2
  import type { IQuery } from '@rapiq/core';
3
3
  import type { Repository } from 'typeorm';
4
4
  import type { EntityRepositoryFindManyResult } from '@authup/server-kit';
5
- import type { EventCountRecentFilter, EventDeleteExpiredOptions, EventFindManyOptions, IEventRepository } from '../../../../../core/index.ts';
5
+ import type { EventCountRecentFilter, EventDeleteExpiredOptions, EventFindManyOptions, EventSaveOptions, IEventRepository } from '../../../../../core/index.ts';
6
6
  export declare class EventRepositoryAdapter implements IEventRepository {
7
7
  private readonly repository;
8
+ /**
9
+ * One pending audit save per caller connection, keyed by the manager the
10
+ * hook handed over (every hook of one broadcast gets the same object).
11
+ */
12
+ private readonly transactionQueue;
8
13
  constructor(repository: Repository<Event>);
9
14
  create(data: Partial<Event>): Event;
10
- save(entity: Event): Promise<Event>;
15
+ save(entity: Event, options?: EventSaveOptions): Promise<Event>;
16
+ /**
17
+ * Writes the row on the connection the caller already holds.
18
+ *
19
+ * Serialized per connection, because the after-hooks of one array save run
20
+ * concurrently (typeorm awaits them with Promise.all) and would otherwise
21
+ * put several statements in flight on one client. pg deprecates that in
22
+ * 8.22 and removes it in 9, and typeorm avoids it everywhere it controls
23
+ * the fan-out.
24
+ *
25
+ * `transaction: false` keeps the nested save from opening a transaction of
26
+ * its own. Inside a persist transaction it would not have, but a
27
+ * query-builder insert (the extra-attribute add path) broadcasts its hooks
28
+ * on a runner carrying no transaction, and there each save would otherwise
29
+ * BEGIN and COMMIT one.
30
+ *
31
+ * Deliberately no savepoint: savepoints are a stack per connection, and
32
+ * `startTransaction` issues `SAVEPOINT typeorm_<depth>` and awaits it
33
+ * before incrementing the depth, so concurrent hooks raced it and a
34
+ * RELEASE named a savepoint that was never created. The residual is
35
+ * postgres-only and stated in .agents/architecture.md.
36
+ */
37
+ private saveOnCallerConnection;
11
38
  findOneById(id: string): Promise<Event | null>;
12
39
  findMany(query: IQuery, options?: EventFindManyOptions): Promise<EntityRepositoryFindManyResult<Event>>;
13
40
  countRecent(filter: EventCountRecentFilter): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../../src/app/modules/database/repositories/event/repository.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EACR,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,EACnB,MAAM,8BAA8B,CAAC;AAItC,qBAAa,sBAAuB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;gBAEnC,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC;IAIzC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK;IAI7B,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAInC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAI9C,QAAQ,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,oBAAyB,GACnC,OAAO,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC;IAoD3C,WAAW,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAmC5D,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,yBAA8B,GAAG,OAAO,CAAC,MAAM,CAAC;CA+C7F"}
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../../src/app/modules/database/repositories/event/repository.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EACR,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EACnB,MAAM,8BAA8B,CAAC;AAItC,qBAAa,sBAAuB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAE/C;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA2C;gBAEhE,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC;IAKzC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK;IAI7B,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC;IAYzE;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,sBAAsB;IAexB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAI9C,QAAQ,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,oBAAyB,GACnC,OAAO,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC;IAoD3C,WAAW,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAmC5D,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,yBAA8B,GAAG,OAAO,CAAC,MAAM,CAAC;CAU7F"}
@@ -4,20 +4,51 @@ import.meta.url;
4
4
  import { EVENT_RETENTION_SWEEP_BATCH_SIZE } from "../../../../../core/entities/event/constants.mjs";
5
5
  import "../../../../../core/index.mjs";
6
6
  import { applyQuery, redactFieldConditions } from "../query.mjs";
7
- import { applyRealmScopeSelect } from "../helpers.mjs";
8
- import { In, LessThan } from "typeorm";
7
+ import { applyRealmScopeSelect, deleteInBatches, resolveSweepBatchSize } from "../helpers.mjs";
8
+ import { EntityManager, LessThan } from "typeorm";
9
9
  //#region src/app/modules/database/repositories/event/repository.ts
10
10
  var EventRepositoryAdapter = class {
11
11
  repository;
12
+ /**
13
+ * One pending audit save per caller connection, keyed by the manager the
14
+ * hook handed over (every hook of one broadcast gets the same object).
15
+ */ transactionQueue;
12
16
  constructor(repository) {
13
17
  this.repository = repository;
18
+ this.transactionQueue = /* @__PURE__ */ new WeakMap();
14
19
  }
15
20
  create(data) {
16
21
  return this.repository.create(data);
17
22
  }
18
- async save(entity) {
23
+ async save(entity, options = {}) {
24
+ if (options.transaction instanceof EntityManager) return this.saveOnCallerConnection(options.transaction, entity);
19
25
  return this.repository.save(entity);
20
26
  }
27
+ /**
28
+ * Writes the row on the connection the caller already holds.
29
+ *
30
+ * Serialized per connection, because the after-hooks of one array save run
31
+ * concurrently (typeorm awaits them with Promise.all) and would otherwise
32
+ * put several statements in flight on one client. pg deprecates that in
33
+ * 8.22 and removes it in 9, and typeorm avoids it everywhere it controls
34
+ * the fan-out.
35
+ *
36
+ * `transaction: false` keeps the nested save from opening a transaction of
37
+ * its own. Inside a persist transaction it would not have, but a
38
+ * query-builder insert (the extra-attribute add path) broadcasts its hooks
39
+ * on a runner carrying no transaction, and there each save would otherwise
40
+ * BEGIN and COMMIT one.
41
+ *
42
+ * Deliberately no savepoint: savepoints are a stack per connection, and
43
+ * `startTransaction` issues `SAVEPOINT typeorm_<depth>` and awaits it
44
+ * before incrementing the depth, so concurrent hooks raced it and a
45
+ * RELEASE named a savepoint that was never created. The residual is
46
+ * postgres-only and stated in .agents/architecture.md.
47
+ */ saveOnCallerConnection(manager, entity) {
48
+ const next = (this.transactionQueue.get(manager) || Promise.resolve()).catch(() => void 0).then(() => manager.withRepository(this.repository).save(entity, { transaction: false }));
49
+ this.transactionQueue.set(manager, next.catch(() => void 0));
50
+ return next;
51
+ }
21
52
  async findOneById(id) {
22
53
  return this.repository.findOneBy({ id });
23
54
  }
@@ -60,30 +91,17 @@ var EventRepositoryAdapter = class {
60
91
  const qb = this.repository.createQueryBuilder("event").where("event.name = :name", { name: filter.name }).andWhere("event.createdAt > :since", { since });
61
92
  if (filter.actorName) qb.andWhere("event.actorName = :actorName", { actorName: filter.actorName });
62
93
  if (filter.requestIpAddress) qb.andWhere("event.requestIpAddress = :requestIpAddress", { requestIpAddress: filter.requestIpAddress });
63
- if (typeof filter.realmId !== "undefined") if (filter.realmId === null) qb.andWhere("event.realmId IS NULL");
64
- else qb.andWhere("event.realmId = :realmId", { realmId: filter.realmId });
94
+ if (typeof filter.realmId !== "undefined") {
95
+ if (filter.realmId === null) qb.andWhere("event.realmId IS NULL");
96
+ else qb.andWhere("event.realmId = :realmId", { realmId: filter.realmId });
97
+ }
65
98
  return qb.getCount();
66
99
  }
67
100
  async deleteExpired(now, options = {}) {
68
- const requested = options.batchSize;
69
- const batchSize = typeof requested === "number" && Number.isSafeInteger(requested) && requested > 0 ? requested : EVENT_RETENTION_SWEEP_BATCH_SIZE;
70
- let total = 0;
71
- for (;;) {
72
- const rows = await this.repository.find({
73
- select: { id: true },
74
- where: {
75
- expiring: true,
76
- expiresAt: LessThan(now)
77
- },
78
- take: batchSize
79
- });
80
- if (rows.length === 0) break;
81
- const result = await this.repository.delete({ id: In(rows.map((row) => row.id)) });
82
- total += result.affected ?? rows.length;
83
- if (result.affected === 0) break;
84
- if (rows.length < batchSize) break;
85
- }
86
- return total;
101
+ return deleteInBatches(this.repository, {
102
+ expiring: true,
103
+ expiresAt: LessThan(now)
104
+ }, resolveSweepBatchSize(options.batchSize, EVENT_RETENTION_SWEEP_BATCH_SIZE));
87
105
  }
88
106
  };
89
107
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"repository.mjs","names":["In","LessThan","applyQuery","redactFieldConditions","EVENT_RETENTION_SWEEP_BATCH_SIZE","applyRealmScopeSelect","EventRepositoryAdapter","repository","create","data","save","entity","findOneById","id","findOneBy","findMany","query","options","qb","createQueryBuilder","pagination","owner","andWhere","ownerActorId","actorId","ownerActorType","actorType","realmId","routeRealmId","visibility","constraints","parameters","realmIds","filter","length","push","visibleRealmIds","includes","visibleActorId","visibleActorType","join","entities","total","getManyAndCount","meta","countRecent","since","Date","toISOString","replace","where","name","actorName","requestIpAddress","getCount","deleteExpired","now","requested","batchSize","Number","isSafeInteger","rows","find","select","expiring","expiresAt","take","result","delete","map","row","affected"],"sources":["../../../../../../src/app/modules/database/repositories/event/repository.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Event } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { Repository } from 'typeorm';\nimport { In, LessThan } from 'typeorm';\nimport { applyQuery, redactFieldConditions } from '../query.ts';\nimport type { EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type {\n EventCountRecentFilter,\n EventDeleteExpiredOptions,\n EventFindManyOptions,\n IEventRepository,\n} from '../../../../../core/index.ts';\nimport { EVENT_RETENTION_SWEEP_BATCH_SIZE } from '../../../../../core/index.ts';\nimport { applyRealmScopeSelect } from '../helpers.ts';\n\nexport class EventRepositoryAdapter implements IEventRepository {\n private readonly repository: Repository<Event>;\n\n constructor(repository: Repository<Event>) {\n this.repository = repository;\n }\n\n create(data: Partial<Event>): Event {\n return this.repository.create(data);\n }\n\n async save(entity: Event): Promise<Event> {\n return this.repository.save(entity);\n }\n\n async findOneById(id: string): Promise<Event | null> {\n return this.repository.findOneBy({ id });\n }\n\n async findMany(\n query: IQuery,\n options: EventFindManyOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Event>> {\n const qb = this.repository.createQueryBuilder('event');\n\n const { pagination } = applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'event', ['actorId', 'actorType']);\n\n if (options.owner) {\n // mandatory constraint — not overridable by a rapiq filter\n qb.andWhere('event.actorId = :ownerActorId AND event.actorType = :ownerActorType', {\n ownerActorId: options.owner.actorId,\n ownerActorType: options.owner.actorType,\n });\n }\n\n if (options.realmId) {\n qb.andWhere('event.realmId = :routeRealmId', { routeRealmId: options.realmId });\n }\n\n if (options.visibility) {\n const constraints: string[] = [];\n const parameters: Record<string, unknown> = {};\n const realmIds = options.visibility.realmIds\n .filter((realmId): realmId is string => realmId !== null);\n\n if (realmIds.length > 0) {\n constraints.push('event.realmId IN (:...visibleRealmIds)');\n parameters.visibleRealmIds = realmIds;\n }\n if (options.visibility.realmIds.includes(null)) {\n constraints.push('event.realmId IS NULL');\n }\n if (options.visibility.owner) {\n constraints.push('(event.actorId = :visibleActorId AND event.actorType = :visibleActorType)');\n parameters.visibleActorId = options.visibility.owner.actorId;\n parameters.visibleActorType = options.visibility.owner.actorType;\n }\n\n qb.andWhere(`(${constraints.length > 0 ? constraints.join(' OR ') : '1 = 0'})`, parameters);\n }\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: redactFieldConditions(query, entities),\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n async countRecent(filter: EventCountRecentFilter): Promise<number> {\n // created_at is stamped by the DATABASE server's clock (assumed UTC —\n // the shipped compose files and deployment posture; a non-UTC DB\n // server shifts the window regardless of what we bind), while a bound\n // Date object is serialized by the pg/mysql drivers in the HOST's\n // local timezone — on a non-UTC host that shifts the window by the\n // UTC offset (postgres: `timestamp without time zone` discards the\n // offset marker entirely). Bind a UTC wall-clock literal instead:\n // pg/mysql cast it as a wall-clock timestamp, sqlite compares it\n // lexicographically against the same format `datetime('now')` stores.\n const since = new Date(filter.since).toISOString().replace('T', ' ').replace('Z', '');\n\n const qb = this.repository.createQueryBuilder('event')\n .where('event.name = :name', { name: filter.name })\n .andWhere('event.createdAt > :since', { since });\n\n if (filter.actorName) {\n qb.andWhere('event.actorName = :actorName', { actorName: filter.actorName });\n }\n\n if (filter.requestIpAddress) {\n qb.andWhere('event.requestIpAddress = :requestIpAddress', { requestIpAddress: filter.requestIpAddress });\n }\n\n if (typeof filter.realmId !== 'undefined') {\n if (filter.realmId === null) {\n qb.andWhere('event.realmId IS NULL');\n } else {\n qb.andWhere('event.realmId = :realmId', { realmId: filter.realmId });\n }\n }\n\n return qb.getCount();\n }\n\n async deleteExpired(now: string, options: EventDeleteExpiredOptions = {}): Promise<number> {\n // A non-positive or non-integral size must never reach `take`: typeorm\n // ignores a falsy one, which would silently restore the single\n // unbounded DELETE this batching exists to prevent, and the rest reach\n // the driver as invalid SQL. Fall back to the default instead.\n const requested = options.batchSize;\n const batchSize = typeof requested === 'number' &&\n Number.isSafeInteger(requested) &&\n requested > 0 ?\n requested :\n EVENT_RETENTION_SWEEP_BATCH_SIZE;\n\n let total = 0;\n\n for (;;) {\n const rows = await this.repository.find({\n select: { id: true },\n where: {\n expiring: true,\n expiresAt: LessThan(now),\n },\n take: batchSize,\n });\n\n if (rows.length === 0) {\n break;\n }\n\n const result = await this.repository.delete({ id: In(rows.map((row) => row.id)) });\n\n // A driver that does not report affected rows still made\n // progress, so count the batch rather than returning 0.\n total += result.affected ?? rows.length;\n\n // Another replica's sweep already owns these rows. Stop rather\n // than re-selecting them; the next tick picks up whatever is left.\n if (result.affected === 0) {\n break;\n }\n\n if (rows.length < batchSize) {\n break;\n }\n }\n\n return total;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"repository.mjs","names":["EntityManager","LessThan","applyQuery","redactFieldConditions","EVENT_RETENTION_SWEEP_BATCH_SIZE","applyRealmScopeSelect","deleteInBatches","resolveSweepBatchSize","EventRepositoryAdapter","repository","transactionQueue","WeakMap","create","data","save","entity","options","transaction","saveOnCallerConnection","manager","pending","get","Promise","resolve","next","catch","undefined","then","withRepository","set","findOneById","id","findOneBy","findMany","query","qb","createQueryBuilder","pagination","owner","andWhere","ownerActorId","actorId","ownerActorType","actorType","realmId","routeRealmId","visibility","constraints","parameters","realmIds","filter","length","push","visibleRealmIds","includes","visibleActorId","visibleActorType","join","entities","total","getManyAndCount","meta","countRecent","since","Date","toISOString","replace","where","name","actorName","requestIpAddress","getCount","deleteExpired","now","expiring","expiresAt","batchSize"],"sources":["../../../../../../src/app/modules/database/repositories/event/repository.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Event } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { Repository } from 'typeorm';\nimport { EntityManager, LessThan } from 'typeorm';\nimport { applyQuery, redactFieldConditions } from '../query.ts';\nimport type { EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type {\n EventCountRecentFilter,\n EventDeleteExpiredOptions,\n EventFindManyOptions,\n EventSaveOptions,\n IEventRepository,\n} from '../../../../../core/index.ts';\nimport { EVENT_RETENTION_SWEEP_BATCH_SIZE } from '../../../../../core/index.ts';\nimport { applyRealmScopeSelect, deleteInBatches, resolveSweepBatchSize } from '../helpers.ts';\n\nexport class EventRepositoryAdapter implements IEventRepository {\n private readonly repository: Repository<Event>;\n\n /**\n * One pending audit save per caller connection, keyed by the manager the\n * hook handed over (every hook of one broadcast gets the same object).\n */\n private readonly transactionQueue: WeakMap<EntityManager, Promise<unknown>>;\n\n constructor(repository: Repository<Event>) {\n this.repository = repository;\n this.transactionQueue = new WeakMap();\n }\n\n create(data: Partial<Event>): Event {\n return this.repository.create(data);\n }\n\n async save(entity: Event, options: EventSaveOptions = {}): Promise<Event> {\n // An audit row written from inside a persist transaction rides it: the\n // connection behind the write is still held while the subscriber hooks\n // run, so a save through the DataSource would wait for a second pooled\n // connection and ten concurrent writes deadlock (#3539).\n if (options.transaction instanceof EntityManager) {\n return this.saveOnCallerConnection(options.transaction, entity);\n }\n\n return this.repository.save(entity);\n }\n\n /**\n * Writes the row on the connection the caller already holds.\n *\n * Serialized per connection, because the after-hooks of one array save run\n * concurrently (typeorm awaits them with Promise.all) and would otherwise\n * put several statements in flight on one client. pg deprecates that in\n * 8.22 and removes it in 9, and typeorm avoids it everywhere it controls\n * the fan-out.\n *\n * `transaction: false` keeps the nested save from opening a transaction of\n * its own. Inside a persist transaction it would not have, but a\n * query-builder insert (the extra-attribute add path) broadcasts its hooks\n * on a runner carrying no transaction, and there each save would otherwise\n * BEGIN and COMMIT one.\n *\n * Deliberately no savepoint: savepoints are a stack per connection, and\n * `startTransaction` issues `SAVEPOINT typeorm_<depth>` and awaits it\n * before incrementing the depth, so concurrent hooks raced it and a\n * RELEASE named a savepoint that was never created. The residual is\n * postgres-only and stated in .agents/architecture.md.\n */\n private saveOnCallerConnection(manager: EntityManager, entity: Event): Promise<Event> {\n const pending = this.transactionQueue.get(manager) || Promise.resolve();\n const next = pending\n .catch(() => undefined)\n .then(() => manager\n .withRepository(this.repository)\n .save(entity, { transaction: false }));\n\n // the queue tail must never stay rejected, or it would fail every\n // later row on this connection\n this.transactionQueue.set(manager, next.catch(() => undefined));\n\n return next;\n }\n\n async findOneById(id: string): Promise<Event | null> {\n return this.repository.findOneBy({ id });\n }\n\n async findMany(\n query: IQuery,\n options: EventFindManyOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Event>> {\n const qb = this.repository.createQueryBuilder('event');\n\n const { pagination } = applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'event', ['actorId', 'actorType']);\n\n if (options.owner) {\n // mandatory constraint — not overridable by a rapiq filter\n qb.andWhere('event.actorId = :ownerActorId AND event.actorType = :ownerActorType', {\n ownerActorId: options.owner.actorId,\n ownerActorType: options.owner.actorType,\n });\n }\n\n if (options.realmId) {\n qb.andWhere('event.realmId = :routeRealmId', { routeRealmId: options.realmId });\n }\n\n if (options.visibility) {\n const constraints: string[] = [];\n const parameters: Record<string, unknown> = {};\n const realmIds = options.visibility.realmIds\n .filter((realmId): realmId is string => realmId !== null);\n\n if (realmIds.length > 0) {\n constraints.push('event.realmId IN (:...visibleRealmIds)');\n parameters.visibleRealmIds = realmIds;\n }\n if (options.visibility.realmIds.includes(null)) {\n constraints.push('event.realmId IS NULL');\n }\n if (options.visibility.owner) {\n constraints.push('(event.actorId = :visibleActorId AND event.actorType = :visibleActorType)');\n parameters.visibleActorId = options.visibility.owner.actorId;\n parameters.visibleActorType = options.visibility.owner.actorType;\n }\n\n qb.andWhere(`(${constraints.length > 0 ? constraints.join(' OR ') : '1 = 0'})`, parameters);\n }\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: redactFieldConditions(query, entities),\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n async countRecent(filter: EventCountRecentFilter): Promise<number> {\n // created_at is stamped by the DATABASE server's clock (assumed UTC —\n // the shipped compose files and deployment posture; a non-UTC DB\n // server shifts the window regardless of what we bind), while a bound\n // Date object is serialized by the pg/mysql drivers in the HOST's\n // local timezone — on a non-UTC host that shifts the window by the\n // UTC offset (postgres: `timestamp without time zone` discards the\n // offset marker entirely). Bind a UTC wall-clock literal instead:\n // pg/mysql cast it as a wall-clock timestamp, sqlite compares it\n // lexicographically against the same format `datetime('now')` stores.\n const since = new Date(filter.since).toISOString().replace('T', ' ').replace('Z', '');\n\n const qb = this.repository.createQueryBuilder('event')\n .where('event.name = :name', { name: filter.name })\n .andWhere('event.createdAt > :since', { since });\n\n if (filter.actorName) {\n qb.andWhere('event.actorName = :actorName', { actorName: filter.actorName });\n }\n\n if (filter.requestIpAddress) {\n qb.andWhere('event.requestIpAddress = :requestIpAddress', { requestIpAddress: filter.requestIpAddress });\n }\n\n if (typeof filter.realmId !== 'undefined') {\n if (filter.realmId === null) {\n qb.andWhere('event.realmId IS NULL');\n } else {\n qb.andWhere('event.realmId = :realmId', { realmId: filter.realmId });\n }\n }\n\n return qb.getCount();\n }\n\n async deleteExpired(now: string, options: EventDeleteExpiredOptions = {}): Promise<number> {\n return deleteInBatches(\n this.repository,\n {\n expiring: true,\n expiresAt: LessThan(now),\n },\n resolveSweepBatchSize(options.batchSize, EVENT_RETENTION_SWEEP_BATCH_SIZE),\n );\n }\n}\n"],"mappings":"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"}