@lenne.tech/nest-server 12.0.0 → 12.1.0

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 (693) hide show
  1. package/.claude/rules/architecture.md +6 -1
  2. package/.claude/rules/better-auth.md +46 -0
  3. package/.claude/rules/configurable-features.md +3 -2
  4. package/.claude/rules/package-management.md +24 -2
  5. package/.claude/rules/persistence.md +100 -0
  6. package/.claude/rules/role-system.md +9 -0
  7. package/.claude/rules/testing.md +116 -18
  8. package/CLAUDE.md +21 -2
  9. package/FRAMEWORK-API.md +6 -4
  10. package/README.md +106 -34
  11. package/dist/core/common/decorators/unified-field.decorator.d.ts +2 -1
  12. package/dist/core/common/decorators/unified-field.decorator.js +4 -1
  13. package/dist/core/common/decorators/unified-field.decorator.js.map +1 -1
  14. package/dist/core/common/filters/mongoose-cast-error.filter.d.ts +7 -5
  15. package/dist/core/common/filters/mongoose-cast-error.filter.js +3 -2
  16. package/dist/core/common/filters/mongoose-cast-error.filter.js.map +1 -1
  17. package/dist/core/common/helpers/db.helper.d.ts +2 -1
  18. package/dist/core/common/helpers/db.helper.js +32 -26
  19. package/dist/core/common/helpers/db.helper.js.map +1 -1
  20. package/dist/core/common/helpers/decorator.helper.d.ts +1 -1
  21. package/dist/core/common/helpers/filter.helper.d.ts +2 -1
  22. package/dist/core/common/helpers/filter.helper.js.map +1 -1
  23. package/dist/core/common/helpers/gridfs.helper.d.ts +4 -4
  24. package/dist/core/common/helpers/gridfs.helper.js +14 -6
  25. package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
  26. package/dist/core/common/helpers/id.helper.d.ts +4 -1
  27. package/dist/core/common/helpers/id.helper.js +10 -4
  28. package/dist/core/common/helpers/id.helper.js.map +1 -1
  29. package/dist/core/common/helpers/model.helper.js +5 -5
  30. package/dist/core/common/helpers/model.helper.js.map +1 -1
  31. package/dist/core/common/helpers/service.helper.js +3 -3
  32. package/dist/core/common/helpers/service.helper.js.map +1 -1
  33. package/dist/core/common/interfaces/server-options.interface.d.ts +18 -2
  34. package/dist/core/common/interfaces/service-options.interface.d.ts +2 -2
  35. package/dist/core/common/models/core-persistence.model.d.ts +1 -2
  36. package/dist/core/common/models/core-persistence.model.js +3 -3
  37. package/dist/core/common/models/core-persistence.model.js.map +1 -1
  38. package/dist/core/common/persistence/core-persistence.lifecycle.d.ts +9 -0
  39. package/dist/core/common/persistence/core-persistence.lifecycle.js +38 -0
  40. package/dist/core/common/persistence/core-persistence.lifecycle.js.map +1 -0
  41. package/dist/core/common/persistence/core-persistence.module.d.ts +9 -0
  42. package/dist/core/common/persistence/core-persistence.module.js +76 -0
  43. package/dist/core/common/persistence/core-persistence.module.js.map +1 -0
  44. package/dist/core/common/persistence/data-source.config.d.ts +33 -0
  45. package/dist/core/common/persistence/data-source.config.js +151 -0
  46. package/dist/core/common/persistence/data-source.config.js.map +1 -0
  47. package/dist/core/common/persistence/data-source.runtime.d.ts +45 -0
  48. package/dist/core/common/persistence/data-source.runtime.js +278 -0
  49. package/dist/core/common/persistence/data-source.runtime.js.map +1 -0
  50. package/dist/core/common/persistence/data-store.interface.d.ts +73 -0
  51. package/dist/core/common/persistence/data-store.interface.js +2 -0
  52. package/dist/core/common/persistence/data-store.interface.js.map +1 -0
  53. package/dist/core/common/persistence/expiry-sweep.d.ts +12 -0
  54. package/dist/core/common/persistence/expiry-sweep.js +55 -0
  55. package/dist/core/common/persistence/expiry-sweep.js.map +1 -0
  56. package/dist/core/common/persistence/id-format.d.ts +3 -0
  57. package/dist/core/common/persistence/id-format.js +21 -0
  58. package/dist/core/common/persistence/id-format.js.map +1 -0
  59. package/dist/core/common/persistence/infrastructure-locks.d.ts +13 -0
  60. package/dist/core/common/persistence/infrastructure-locks.js +35 -0
  61. package/dist/core/common/persistence/infrastructure-locks.js.map +1 -0
  62. package/dist/core/common/persistence/inject-store.decorator.d.ts +1 -0
  63. package/dist/core/common/persistence/inject-store.decorator.js +6 -0
  64. package/dist/core/common/persistence/inject-store.decorator.js.map +1 -0
  65. package/dist/core/common/persistence/lock-store.interface.d.ts +5 -0
  66. package/dist/core/common/persistence/lock-store.interface.js +2 -0
  67. package/dist/core/common/persistence/lock-store.interface.js.map +1 -0
  68. package/dist/core/common/persistence/model-descriptor.interface.d.ts +36 -0
  69. package/dist/core/common/persistence/model-descriptor.interface.js +2 -0
  70. package/dist/core/common/persistence/model-descriptor.interface.js.map +1 -0
  71. package/dist/core/common/persistence/model-metadata.registry.d.ts +14 -0
  72. package/dist/core/common/persistence/model-metadata.registry.js +194 -0
  73. package/dist/core/common/persistence/model-metadata.registry.js.map +1 -0
  74. package/dist/core/common/persistence/mongo/collection-name.d.ts +2 -0
  75. package/dist/core/common/persistence/mongo/collection-name.js +73 -0
  76. package/dist/core/common/persistence/mongo/collection-name.js.map +1 -0
  77. package/dist/core/common/persistence/mongo/declared-schema.view.d.ts +11 -0
  78. package/dist/core/common/persistence/mongo/declared-schema.view.js +292 -0
  79. package/dist/core/common/persistence/mongo/declared-schema.view.js.map +1 -0
  80. package/dist/core/common/persistence/mongo/hex-object-id.d.ts +13 -0
  81. package/dist/core/common/persistence/mongo/hex-object-id.js +54 -0
  82. package/dist/core/common/persistence/mongo/hex-object-id.js.map +1 -0
  83. package/dist/core/common/persistence/mongo/model-declarations.d.ts +35 -0
  84. package/dist/core/common/persistence/mongo/model-declarations.js +80 -0
  85. package/dist/core/common/persistence/mongo/model-declarations.js.map +1 -0
  86. package/dist/core/common/persistence/mongo/mongo-packages.d.ts +15 -0
  87. package/dist/core/common/persistence/mongo/mongo-packages.js +66 -0
  88. package/dist/core/common/persistence/mongo/mongo-packages.js.map +1 -0
  89. package/dist/core/common/persistence/mongo/mongoose-compat.d.ts +22 -0
  90. package/dist/core/common/persistence/mongo/mongoose-compat.js +65 -0
  91. package/dist/core/common/persistence/mongo/mongoose-compat.js.map +1 -0
  92. package/dist/core/common/persistence/mongo/no-mongo-connection.module.d.ts +2 -0
  93. package/dist/core/common/persistence/mongo/no-mongo-connection.module.js +19 -0
  94. package/dist/core/common/persistence/mongo/no-mongo-connection.module.js.map +1 -0
  95. package/dist/core/common/persistence/mongo-lock-store.d.ts +21 -0
  96. package/dist/core/common/persistence/mongo-lock-store.js +72 -0
  97. package/dist/core/common/persistence/mongo-lock-store.js.map +1 -0
  98. package/dist/core/common/persistence/mongoose-data-store.d.ts +33 -0
  99. package/dist/core/common/persistence/mongoose-data-store.js +187 -0
  100. package/dist/core/common/persistence/mongoose-data-store.js.map +1 -0
  101. package/dist/core/common/persistence/neutral-populate.d.ts +6 -0
  102. package/dist/core/common/persistence/neutral-populate.js +72 -0
  103. package/dist/core/common/persistence/neutral-populate.js.map +1 -0
  104. package/dist/core/common/persistence/persisted-model.decorator.d.ts +6 -0
  105. package/dist/core/common/persistence/persisted-model.decorator.js +24 -0
  106. package/dist/core/common/persistence/persisted-model.decorator.js.map +1 -0
  107. package/dist/core/common/persistence/persistence-runtime.registry.d.ts +61 -0
  108. package/dist/core/common/persistence/persistence-runtime.registry.js +47 -0
  109. package/dist/core/common/persistence/persistence-runtime.registry.js.map +1 -0
  110. package/dist/core/common/persistence/persistence.tokens.d.ts +1 -0
  111. package/dist/core/common/persistence/persistence.tokens.js +4 -0
  112. package/dist/core/common/persistence/persistence.tokens.js.map +1 -0
  113. package/dist/core/common/persistence/policies/audit.policy.d.ts +8 -0
  114. package/dist/core/common/persistence/policies/audit.policy.js +37 -0
  115. package/dist/core/common/persistence/policies/audit.policy.js.map +1 -0
  116. package/dist/core/common/persistence/policies/password.policy.d.ts +3 -0
  117. package/dist/core/common/persistence/policies/password.policy.js +46 -0
  118. package/dist/core/common/persistence/policies/password.policy.js.map +1 -0
  119. package/dist/core/common/persistence/policies/role-guard.policy.d.ts +3 -0
  120. package/dist/core/common/persistence/policies/role-guard.policy.js +46 -0
  121. package/dist/core/common/persistence/policies/role-guard.policy.js.map +1 -0
  122. package/dist/core/common/persistence/policies/system-role.policy.d.ts +5 -0
  123. package/dist/core/common/persistence/policies/system-role.policy.js +46 -0
  124. package/dist/core/common/persistence/policies/system-role.policy.js.map +1 -0
  125. package/dist/core/common/persistence/policies/tenant.policy.d.ts +19 -0
  126. package/dist/core/common/persistence/policies/tenant.policy.js +120 -0
  127. package/dist/core/common/persistence/policies/tenant.policy.js.map +1 -0
  128. package/dist/core/common/persistence/routed-model.guard.d.ts +4 -0
  129. package/dist/core/common/persistence/routed-model.guard.js +73 -0
  130. package/dist/core/common/persistence/routed-model.guard.js.map +1 -0
  131. package/dist/core/common/persistence/sql/mysql/mysql-data-store.d.ts +46 -0
  132. package/dist/core/common/persistence/sql/mysql/mysql-data-store.js +350 -0
  133. package/dist/core/common/persistence/sql/mysql/mysql-data-store.js.map +1 -0
  134. package/dist/core/common/persistence/sql/mysql/mysql-executor.d.ts +13 -0
  135. package/dist/core/common/persistence/sql/mysql/mysql-executor.js +194 -0
  136. package/dist/core/common/persistence/sql/mysql/mysql-executor.js.map +1 -0
  137. package/dist/core/common/persistence/sql/mysql/mysql-lock-store.d.ts +11 -0
  138. package/dist/core/common/persistence/sql/mysql/mysql-lock-store.js +55 -0
  139. package/dist/core/common/persistence/sql/mysql/mysql-lock-store.js.map +1 -0
  140. package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.d.ts +36 -0
  141. package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js +288 -0
  142. package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js.map +1 -0
  143. package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.d.ts +19 -0
  144. package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js +328 -0
  145. package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js.map +1 -0
  146. package/dist/core/common/persistence/sql/mysql/mysql-session.d.ts +13 -0
  147. package/dist/core/common/persistence/sql/mysql/mysql-session.js +85 -0
  148. package/dist/core/common/persistence/sql/mysql/mysql-session.js.map +1 -0
  149. package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.d.ts +9 -0
  150. package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.js +264 -0
  151. package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.js.map +1 -0
  152. package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.d.ts +20 -0
  153. package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.js +519 -0
  154. package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.js.map +1 -0
  155. package/dist/core/common/persistence/sql/postgres/postgres-lock-store.d.ts +11 -0
  156. package/dist/core/common/persistence/sql/postgres/postgres-lock-store.js +44 -0
  157. package/dist/core/common/persistence/sql/postgres/postgres-lock-store.js.map +1 -0
  158. package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.d.ts +42 -0
  159. package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js +220 -0
  160. package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js.map +1 -0
  161. package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.d.ts +12 -0
  162. package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js +315 -0
  163. package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js.map +1 -0
  164. package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.d.ts +5 -0
  165. package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.js +225 -0
  166. package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.js.map +1 -0
  167. package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.d.ts +13 -0
  168. package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.js +484 -0
  169. package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.js.map +1 -0
  170. package/dist/core/common/persistence/sql/sql-cast.d.ts +2 -0
  171. package/dist/core/common/persistence/sql/sql-cast.js +194 -0
  172. package/dist/core/common/persistence/sql/sql-cast.js.map +1 -0
  173. package/dist/core/common/persistence/sql/sql-data-store.d.ts +79 -0
  174. package/dist/core/common/persistence/sql/sql-data-store.js +592 -0
  175. package/dist/core/common/persistence/sql/sql-data-store.js.map +1 -0
  176. package/dist/core/common/persistence/sql/sql-dialect.d.ts +20 -0
  177. package/dist/core/common/persistence/sql/sql-dialect.js +38 -0
  178. package/dist/core/common/persistence/sql/sql-dialect.js.map +1 -0
  179. package/dist/core/common/persistence/sql/sql-errors.d.ts +17 -0
  180. package/dist/core/common/persistence/sql/sql-errors.js +25 -0
  181. package/dist/core/common/persistence/sql/sql-errors.js.map +1 -0
  182. package/dist/core/common/persistence/sql/sql-executor.factory.d.ts +11 -0
  183. package/dist/core/common/persistence/sql/sql-executor.factory.js +199 -0
  184. package/dist/core/common/persistence/sql/sql-executor.factory.js.map +1 -0
  185. package/dist/core/common/persistence/sql/sql-executor.interface.d.ts +32 -0
  186. package/dist/core/common/persistence/sql/sql-executor.interface.js +2 -0
  187. package/dist/core/common/persistence/sql/sql-executor.interface.js.map +1 -0
  188. package/dist/core/common/persistence/sql/sql-naming.d.ts +15 -0
  189. package/dist/core/common/persistence/sql/sql-naming.js +90 -0
  190. package/dist/core/common/persistence/sql/sql-naming.js.map +1 -0
  191. package/dist/core/common/persistence/sql/sql-schema.shared.d.ts +25 -0
  192. package/dist/core/common/persistence/sql/sql-schema.shared.js +69 -0
  193. package/dist/core/common/persistence/sql/sql-schema.shared.js.map +1 -0
  194. package/dist/core/common/persistence/sql/sql-session.d.ts +6 -0
  195. package/dist/core/common/persistence/sql/sql-session.js +78 -0
  196. package/dist/core/common/persistence/sql/sql-session.js.map +1 -0
  197. package/dist/core/common/persistence/sql/where-shared.d.ts +18 -0
  198. package/dist/core/common/persistence/sql/where-shared.js +93 -0
  199. package/dist/core/common/persistence/sql/where-shared.js.map +1 -0
  200. package/dist/core/common/persistence/store-guards.d.ts +10 -0
  201. package/dist/core/common/persistence/store-guards.js +49 -0
  202. package/dist/core/common/persistence/store-guards.js.map +1 -0
  203. package/dist/core/common/persistence/store-upsert.d.ts +2 -0
  204. package/dist/core/common/persistence/store-upsert.js +20 -0
  205. package/dist/core/common/persistence/store-upsert.js.map +1 -0
  206. package/dist/core/common/persistence/unavailable-store.d.ts +2 -0
  207. package/dist/core/common/persistence/unavailable-store.js +53 -0
  208. package/dist/core/common/persistence/unavailable-store.js.map +1 -0
  209. package/dist/core/common/persistence/unsupported-capability.error.d.ts +3 -0
  210. package/dist/core/common/persistence/unsupported-capability.error.js +4 -0
  211. package/dist/core/common/persistence/unsupported-capability.error.js.map +1 -0
  212. package/dist/core/common/plugins/mongoose-audit-fields.plugin.js +24 -68
  213. package/dist/core/common/plugins/mongoose-audit-fields.plugin.js.map +1 -1
  214. package/dist/core/common/plugins/mongoose-id.plugin.js +3 -0
  215. package/dist/core/common/plugins/mongoose-id.plugin.js.map +1 -1
  216. package/dist/core/common/plugins/mongoose-password.plugin.d.ts +1 -3
  217. package/dist/core/common/plugins/mongoose-password.plugin.js +2 -45
  218. package/dist/core/common/plugins/mongoose-password.plugin.js.map +1 -1
  219. package/dist/core/common/plugins/mongoose-role-guard.plugin.js +5 -46
  220. package/dist/core/common/plugins/mongoose-role-guard.plugin.js.map +1 -1
  221. package/dist/core/common/plugins/mongoose-system-role.plugin.js +2 -43
  222. package/dist/core/common/plugins/mongoose-system-role.plugin.js.map +1 -1
  223. package/dist/core/common/plugins/mongoose-tenant.plugin.js +10 -70
  224. package/dist/core/common/plugins/mongoose-tenant.plugin.js.map +1 -1
  225. package/dist/core/common/scalars/upload.scalar.js +1 -1
  226. package/dist/core/common/scalars/upload.scalar.js.map +1 -1
  227. package/dist/core/common/services/core-cron-jobs.initializer.js +1 -1
  228. package/dist/core/common/services/core-cron-jobs.initializer.js.map +1 -1
  229. package/dist/core/common/services/core-cron-jobs.service.d.ts +1 -0
  230. package/dist/core/common/services/core-cron-jobs.service.js +23 -14
  231. package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
  232. package/dist/core/common/services/crud.service.d.ts +4 -1
  233. package/dist/core/common/services/crud.service.js +132 -23
  234. package/dist/core/common/services/crud.service.js.map +1 -1
  235. package/dist/core/common/services/model-doc.service.js +1 -1
  236. package/dist/core/common/services/model-doc.service.js.map +1 -1
  237. package/dist/core/common/services/module.service.d.ts +9 -2
  238. package/dist/core/common/services/module.service.js +51 -6
  239. package/dist/core/common/services/module.service.js.map +1 -1
  240. package/dist/core/common/types/field-selection.type.d.ts +1 -1
  241. package/dist/core/common/types/id.type.d.ts +4 -4
  242. package/dist/core/common/types/object-id-like.type.d.ts +3 -0
  243. package/dist/core/common/types/object-id-like.type.js +2 -0
  244. package/dist/core/common/types/object-id-like.type.js.map +1 -0
  245. package/dist/core/common/types/populate-config.type.d.ts +1 -1
  246. package/dist/core/common/types/string-or-object-id.type.d.ts +2 -2
  247. package/dist/core/modules/ai/core-ai.constants.d.ts +4 -0
  248. package/dist/core/modules/ai/core-ai.constants.js +4 -0
  249. package/dist/core/modules/ai/core-ai.constants.js.map +1 -1
  250. package/dist/core/modules/ai/core-ai.module.js +21 -17
  251. package/dist/core/modules/ai/core-ai.module.js.map +1 -1
  252. package/dist/core/modules/ai/models/core-ai-budget-limit.model.d.ts +2 -92
  253. package/dist/core/modules/ai/models/core-ai-budget-limit.model.js +1 -1
  254. package/dist/core/modules/ai/models/core-ai-budget-limit.model.js.map +1 -1
  255. package/dist/core/modules/ai/models/core-ai-connection-preference.model.d.ts +2 -87
  256. package/dist/core/modules/ai/models/core-ai-connection-preference.model.js +1 -1
  257. package/dist/core/modules/ai/models/core-ai-connection-preference.model.js.map +1 -1
  258. package/dist/core/modules/ai/models/core-ai-connection.model.d.ts +2 -177
  259. package/dist/core/modules/ai/models/core-ai-connection.model.js +1 -1
  260. package/dist/core/modules/ai/models/core-ai-connection.model.js.map +1 -1
  261. package/dist/core/modules/ai/models/core-ai-conversation.model.d.ts +2 -92
  262. package/dist/core/modules/ai/models/core-ai-conversation.model.js +3 -4
  263. package/dist/core/modules/ai/models/core-ai-conversation.model.js.map +1 -1
  264. package/dist/core/modules/ai/models/core-ai-interaction.model.d.ts +2 -120
  265. package/dist/core/modules/ai/models/core-ai-interaction.model.js +2 -3
  266. package/dist/core/modules/ai/models/core-ai-interaction.model.js.map +1 -1
  267. package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.d.ts +3 -0
  268. package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.js +21 -0
  269. package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.js.map +1 -0
  270. package/dist/core/modules/ai/models/core-ai-mode.model.d.ts +2 -102
  271. package/dist/core/modules/ai/models/core-ai-mode.model.js +1 -1
  272. package/dist/core/modules/ai/models/core-ai-mode.model.js.map +1 -1
  273. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.d.ts +2 -97
  274. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js +1 -1
  275. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js.map +1 -1
  276. package/dist/core/modules/ai/models/core-ai-prompt.model.d.ts +2 -112
  277. package/dist/core/modules/ai/models/core-ai-prompt.model.js +1 -1
  278. package/dist/core/modules/ai/models/core-ai-prompt.model.js.map +1 -1
  279. package/dist/core/modules/ai/models/core-ai-slot.model.d.ts +2 -112
  280. package/dist/core/modules/ai/models/core-ai-slot.model.js +1 -1
  281. package/dist/core/modules/ai/models/core-ai-slot.model.js.map +1 -1
  282. package/dist/core/modules/ai/models/core-ai-tool-grant.model.d.ts +2 -97
  283. package/dist/core/modules/ai/models/core-ai-tool-grant.model.js +1 -1
  284. package/dist/core/modules/ai/models/core-ai-tool-grant.model.js.map +1 -1
  285. package/dist/core/modules/ai/models/core-ai-tool-policy.model.d.ts +2 -103
  286. package/dist/core/modules/ai/models/core-ai-tool-policy.model.js +1 -1
  287. package/dist/core/modules/ai/models/core-ai-tool-policy.model.js.map +1 -1
  288. package/dist/core/modules/ai/services/core-ai-budget.service.d.ts +3 -1
  289. package/dist/core/modules/ai/services/core-ai-budget.service.js +15 -5
  290. package/dist/core/modules/ai/services/core-ai-budget.service.js.map +1 -1
  291. package/dist/core/modules/ai/services/core-ai-connection-preference.service.d.ts +1 -1
  292. package/dist/core/modules/ai/services/core-ai-connection-preference.service.js +6 -10
  293. package/dist/core/modules/ai/services/core-ai-connection-preference.service.js.map +1 -1
  294. package/dist/core/modules/ai/services/core-ai-connection.service.d.ts +1 -1
  295. package/dist/core/modules/ai/services/core-ai-connection.service.js +20 -42
  296. package/dist/core/modules/ai/services/core-ai-connection.service.js.map +1 -1
  297. package/dist/core/modules/ai/services/core-ai-conversation.service.d.ts +1 -1
  298. package/dist/core/modules/ai/services/core-ai-conversation.service.js +28 -29
  299. package/dist/core/modules/ai/services/core-ai-conversation.service.js.map +1 -1
  300. package/dist/core/modules/ai/services/core-ai-interaction.service.d.ts +1 -1
  301. package/dist/core/modules/ai/services/core-ai-interaction.service.js +3 -4
  302. package/dist/core/modules/ai/services/core-ai-interaction.service.js.map +1 -1
  303. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.d.ts +8 -0
  304. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js +70 -18
  305. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js.map +1 -1
  306. package/dist/core/modules/ai/services/core-ai-mode.service.d.ts +1 -1
  307. package/dist/core/modules/ai/services/core-ai-mode.service.js +3 -7
  308. package/dist/core/modules/ai/services/core-ai-mode.service.js.map +1 -1
  309. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.d.ts +8 -1
  310. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js +32 -26
  311. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js.map +1 -1
  312. package/dist/core/modules/ai/services/core-ai-prompt.service.d.ts +1 -1
  313. package/dist/core/modules/ai/services/core-ai-prompt.service.js +10 -13
  314. package/dist/core/modules/ai/services/core-ai-prompt.service.js.map +1 -1
  315. package/dist/core/modules/ai/services/core-ai-slot.service.d.ts +1 -1
  316. package/dist/core/modules/ai/services/core-ai-slot.service.js +14 -25
  317. package/dist/core/modules/ai/services/core-ai-slot.service.js.map +1 -1
  318. package/dist/core/modules/ai/services/core-ai-tool-grant.service.d.ts +1 -1
  319. package/dist/core/modules/ai/services/core-ai-tool-grant.service.js +6 -18
  320. package/dist/core/modules/ai/services/core-ai-tool-grant.service.js.map +1 -1
  321. package/dist/core/modules/ai/services/core-ai-tool-policy.service.d.ts +1 -1
  322. package/dist/core/modules/ai/services/core-ai-tool-policy.service.js +4 -8
  323. package/dist/core/modules/ai/services/core-ai-tool-policy.service.js.map +1 -1
  324. package/dist/core/modules/api-token/core-api-token.model.js +1 -1
  325. package/dist/core/modules/api-token/core-api-token.model.js.map +1 -1
  326. package/dist/core/modules/api-token/core-api-token.module.js +3 -2
  327. package/dist/core/modules/api-token/core-api-token.module.js.map +1 -1
  328. package/dist/core/modules/api-token/core-api-token.service.d.ts +8 -2
  329. package/dist/core/modules/api-token/core-api-token.service.js +106 -39
  330. package/dist/core/modules/api-token/core-api-token.service.js.map +1 -1
  331. package/dist/core/modules/auth/core-auth.module.js +2 -0
  332. package/dist/core/modules/auth/core-auth.module.js.map +1 -1
  333. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js +1 -2
  334. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js.map +1 -1
  335. package/dist/core/modules/auth/guards/role-guard.token.d.ts +1 -0
  336. package/dist/core/modules/auth/guards/role-guard.token.js +2 -0
  337. package/dist/core/modules/auth/guards/role-guard.token.js.map +1 -0
  338. package/dist/core/modules/auth/services/core-auth.service.js +4 -2
  339. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  340. package/dist/core/modules/better-auth/better-auth-sql.helper.d.ts +6 -0
  341. package/dist/core/modules/better-auth/better-auth-sql.helper.js +113 -0
  342. package/dist/core/modules/better-auth/better-auth-sql.helper.js.map +1 -0
  343. package/dist/core/modules/better-auth/better-auth-token.service.d.ts +3 -1
  344. package/dist/core/modules/better-auth/better-auth-token.service.js +15 -24
  345. package/dist/core/modules/better-auth/better-auth-token.service.js.map +1 -1
  346. package/dist/core/modules/better-auth/better-auth.config.d.ts +7 -0
  347. package/dist/core/modules/better-auth/better-auth.config.js +16 -5
  348. package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
  349. package/dist/core/modules/better-auth/better-auth.types.d.ts +1 -1
  350. package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +1 -0
  351. package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +6 -1
  352. package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
  353. package/dist/core/modules/better-auth/core-better-auth-challenge.service.js +30 -15
  354. package/dist/core/modules/better-auth/core-better-auth-challenge.service.js.map +1 -1
  355. package/dist/core/modules/better-auth/core-better-auth-mongo.users.d.ts +10 -0
  356. package/dist/core/modules/better-auth/core-better-auth-mongo.users.js +24 -0
  357. package/dist/core/modules/better-auth/core-better-auth-mongo.users.js.map +1 -0
  358. package/dist/core/modules/better-auth/core-better-auth-sql.registry.d.ts +3 -0
  359. package/dist/core/modules/better-auth/core-better-auth-sql.registry.js +8 -0
  360. package/dist/core/modules/better-auth/core-better-auth-sql.registry.js.map +1 -0
  361. package/dist/core/modules/better-auth/core-better-auth-sql.store.d.ts +71 -0
  362. package/dist/core/modules/better-auth/core-better-auth-sql.store.js +190 -0
  363. package/dist/core/modules/better-auth/core-better-auth-sql.store.js.map +1 -0
  364. package/dist/core/modules/better-auth/core-better-auth-user.mapper.d.ts +24 -1
  365. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +308 -32
  366. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
  367. package/dist/core/modules/better-auth/core-better-auth.module.d.ts +2 -0
  368. package/dist/core/modules/better-auth/core-better-auth.module.js +54 -32
  369. package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
  370. package/dist/core/modules/better-auth/core-better-auth.service.d.ts +7 -2
  371. package/dist/core/modules/better-auth/core-better-auth.service.js +61 -9
  372. package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
  373. package/dist/core/modules/file/core-file-info.model.d.ts +1 -2
  374. package/dist/core/modules/file/core-file-info.model.js +2 -2
  375. package/dist/core/modules/file/core-file-info.model.js.map +1 -1
  376. package/dist/core/modules/file/core-file.service.d.ts +5 -3
  377. package/dist/core/modules/file/core-file.service.js +16 -9
  378. package/dist/core/modules/file/core-file.service.js.map +1 -1
  379. package/dist/core/modules/file/file-metadata.helper.d.ts +1 -1
  380. package/dist/core/modules/file/file-metadata.helper.js +2 -2
  381. package/dist/core/modules/file/file-metadata.helper.js.map +1 -1
  382. package/dist/core/modules/file/file-metadata.models.d.ts +35 -0
  383. package/dist/core/modules/file/file-metadata.models.js +20 -0
  384. package/dist/core/modules/file/file-metadata.models.js.map +1 -0
  385. package/dist/core/modules/file/file-metadata.store.d.ts +6 -0
  386. package/dist/core/modules/file/file-metadata.store.js +77 -0
  387. package/dist/core/modules/file/file-metadata.store.js.map +1 -0
  388. package/dist/core/modules/file/file-storage.helper.d.ts +1 -0
  389. package/dist/core/modules/file/file-storage.helper.js +34 -0
  390. package/dist/core/modules/file/file-storage.helper.js.map +1 -1
  391. package/dist/core/modules/file/filesystem-file.helper.d.ts +1 -1
  392. package/dist/core/modules/file/filesystem-file.helper.js +4 -4
  393. package/dist/core/modules/file/filesystem-file.helper.js.map +1 -1
  394. package/dist/core/modules/file/s3-file.helper.d.ts +1 -1
  395. package/dist/core/modules/file/s3-file.helper.js +5 -5
  396. package/dist/core/modules/file/s3-file.helper.js.map +1 -1
  397. package/dist/core/modules/health-check/core-health-check.module.js +12 -2
  398. package/dist/core/modules/health-check/core-health-check.module.js.map +1 -1
  399. package/dist/core/modules/health-check/core-health-check.service.d.ts +4 -3
  400. package/dist/core/modules/health-check/core-health-check.service.js +26 -5
  401. package/dist/core/modules/health-check/core-health-check.service.js.map +1 -1
  402. package/dist/core/modules/hub/core-hub.controller.d.ts +1 -0
  403. package/dist/core/modules/hub/core-hub.controller.js +10 -0
  404. package/dist/core/modules/hub/core-hub.controller.js.map +1 -1
  405. package/dist/core/modules/hub/core-hub.service.js +1 -1
  406. package/dist/core/modules/hub/core-hub.service.js.map +1 -1
  407. package/dist/core/modules/hub/helpers/hub-client-js.helper.js +23 -0
  408. package/dist/core/modules/hub/helpers/hub-client-js.helper.js.map +1 -1
  409. package/dist/core/modules/hub/hub-action-messages.d.ts +2 -0
  410. package/dist/core/modules/hub/hub-action-messages.js +2 -0
  411. package/dist/core/modules/hub/hub-action-messages.js.map +1 -1
  412. package/dist/core/modules/hub/hub-nav.js +1 -0
  413. package/dist/core/modules/hub/hub-nav.js.map +1 -1
  414. package/dist/core/modules/hub/interfaces/hub-panels.interface.d.ts +17 -1
  415. package/dist/core/modules/hub/services/core-hub-db.service.d.ts +6 -1
  416. package/dist/core/modules/hub/services/core-hub-db.service.js +16 -14
  417. package/dist/core/modules/hub/services/core-hub-db.service.js.map +1 -1
  418. package/dist/core/modules/hub/services/core-hub-migrations.service.d.ts +5 -0
  419. package/dist/core/modules/hub/services/core-hub-migrations.service.js +74 -1
  420. package/dist/core/modules/hub/services/core-hub-migrations.service.js.map +1 -1
  421. package/dist/core/modules/hub/services/core-hub-sources.service.d.ts +2 -1
  422. package/dist/core/modules/hub/services/core-hub-sources.service.js +32 -0
  423. package/dist/core/modules/hub/services/core-hub-sources.service.js.map +1 -1
  424. package/dist/core/modules/hub/services/hub-query-profiler.service.js +1 -1
  425. package/dist/core/modules/hub/services/hub-query-profiler.service.js.map +1 -1
  426. package/dist/core/modules/migrate/cli/migrate-cli.d.ts +2 -0
  427. package/dist/core/modules/migrate/cli/migrate-cli.js +35 -1
  428. package/dist/core/modules/migrate/cli/migrate-cli.js.map +1 -1
  429. package/dist/core/modules/migrate/index.d.ts +3 -0
  430. package/dist/core/modules/migrate/index.js +3 -0
  431. package/dist/core/modules/migrate/index.js.map +1 -1
  432. package/dist/core/modules/migrate/migration-runner.d.ts +2 -2
  433. package/dist/core/modules/migrate/migration-runner.js.map +1 -1
  434. package/dist/core/modules/migrate/migration-state-store.interface.d.ts +16 -0
  435. package/dist/core/modules/migrate/migration-state-store.interface.js +2 -0
  436. package/dist/core/modules/migrate/migration-state-store.interface.js.map +1 -0
  437. package/dist/core/modules/migrate/migration.helper.d.ts +3 -2
  438. package/dist/core/modules/migrate/migration.helper.js +21 -6
  439. package/dist/core/modules/migrate/migration.helper.js.map +1 -1
  440. package/dist/core/modules/migrate/mongo-state-store.d.ts +5 -12
  441. package/dist/core/modules/migrate/mongo-state-store.js +30 -24
  442. package/dist/core/modules/migrate/mongo-state-store.js.map +1 -1
  443. package/dist/core/modules/migrate/sql-migration.helper.d.ts +4 -0
  444. package/dist/core/modules/migrate/sql-migration.helper.js +34 -0
  445. package/dist/core/modules/migrate/sql-migration.helper.js.map +1 -0
  446. package/dist/core/modules/migrate/sql-state-store.d.ts +24 -0
  447. package/dist/core/modules/migrate/sql-state-store.js +129 -0
  448. package/dist/core/modules/migrate/sql-state-store.js.map +1 -0
  449. package/dist/core/modules/system-setup/core-system-setup.service.d.ts +8 -0
  450. package/dist/core/modules/system-setup/core-system-setup.service.js +41 -25
  451. package/dist/core/modules/system-setup/core-system-setup.service.js.map +1 -1
  452. package/dist/core/modules/tenant/core-tenant-member.model.js +1 -1
  453. package/dist/core/modules/tenant/core-tenant-member.model.js.map +1 -1
  454. package/dist/core/modules/tenant/core-tenant-member.store.d.ts +2 -0
  455. package/dist/core/modules/tenant/core-tenant-member.store.js +6 -0
  456. package/dist/core/modules/tenant/core-tenant-member.store.js.map +1 -0
  457. package/dist/core/modules/tenant/core-tenant.guard.d.ts +8 -3
  458. package/dist/core/modules/tenant/core-tenant.guard.js +57 -28
  459. package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -1
  460. package/dist/core/modules/tenant/core-tenant.module.js +3 -2
  461. package/dist/core/modules/tenant/core-tenant.module.js.map +1 -1
  462. package/dist/core/modules/tenant/core-tenant.service.d.ts +3 -1
  463. package/dist/core/modules/tenant/core-tenant.service.js +48 -28
  464. package/dist/core/modules/tenant/core-tenant.service.js.map +1 -1
  465. package/dist/core/modules/tus/core-tus.service.d.ts +1 -1
  466. package/dist/core/modules/tus/core-tus.service.js +8 -7
  467. package/dist/core/modules/tus/core-tus.service.js.map +1 -1
  468. package/dist/core/modules/tus/tus.module.js +1 -1
  469. package/dist/core/modules/tus/tus.module.js.map +1 -1
  470. package/dist/core/modules/user/core-user.model.d.ts +1 -1
  471. package/dist/core/modules/user/core-user.model.js +1 -1
  472. package/dist/core/modules/user/core-user.model.js.map +1 -1
  473. package/dist/core/modules/user/core-user.service.d.ts +3 -1
  474. package/dist/core/modules/user/core-user.service.js +71 -16
  475. package/dist/core/modules/user/core-user.service.js.map +1 -1
  476. package/dist/core.module.js +39 -5
  477. package/dist/core.module.js.map +1 -1
  478. package/dist/index.d.ts +26 -0
  479. package/dist/index.js +26 -0
  480. package/dist/index.js.map +1 -1
  481. package/dist/server/common/models/persistence.model.d.ts +1 -1
  482. package/dist/server/common/models/persistence.model.js +3 -3
  483. package/dist/server/common/models/persistence.model.js.map +1 -1
  484. package/dist/server/modules/file/file-info.model.d.ts +1 -77
  485. package/dist/server/modules/file/file-info.model.js +1 -1
  486. package/dist/server/modules/file/file-info.model.js.map +1 -1
  487. package/dist/server/modules/file/file.service.js +1 -1
  488. package/dist/server/modules/file/file.service.js.map +1 -1
  489. package/dist/server/modules/user/user.model.d.ts +2 -186
  490. package/dist/server/modules/user/user.model.js +4 -5
  491. package/dist/server/modules/user/user.model.js.map +1 -1
  492. package/dist/server/modules/user/user.module.js +4 -3
  493. package/dist/server/modules/user/user.module.js.map +1 -1
  494. package/dist/server/modules/user/user.service.d.ts +1 -1
  495. package/dist/server/modules/user/user.service.js +5 -8
  496. package/dist/server/modules/user/user.service.js.map +1 -1
  497. package/dist/test/test.helper.js +2 -2
  498. package/dist/test/test.helper.js.map +1 -1
  499. package/dist/types/graphql-upload.d.ts +10 -7
  500. package/docs/REQUEST-LIFECYCLE.md +6 -3
  501. package/docs/choosing-a-database.md +107 -0
  502. package/docs/native-driver-security.md +29 -0
  503. package/docs/security-overrides.md +15 -6
  504. package/migration-guides/12.0.x-to-12.1.x.md +255 -0
  505. package/package.json +75 -29
  506. package/src/core/common/decorators/unified-field.decorator.ts +11 -1
  507. package/src/core/common/filters/mongoose-cast-error.filter.ts +12 -6
  508. package/src/core/common/helpers/db.helper.ts +40 -25
  509. package/src/core/common/helpers/decorator.helper.ts +1 -1
  510. package/src/core/common/helpers/filter.helper.ts +2 -1
  511. package/src/core/common/helpers/gridfs.helper.ts +28 -9
  512. package/src/core/common/helpers/id.helper.ts +21 -4
  513. package/src/core/common/helpers/model.helper.ts +5 -6
  514. package/src/core/common/helpers/service.helper.ts +3 -3
  515. package/src/core/common/interfaces/server-options.interface.ts +118 -10
  516. package/src/core/common/interfaces/service-options.interface.ts +2 -2
  517. package/src/core/common/models/core-persistence.model.ts +3 -3
  518. package/src/core/common/persistence/core-persistence.lifecycle.ts +47 -0
  519. package/src/core/common/persistence/core-persistence.module.ts +109 -0
  520. package/src/core/common/persistence/data-source.config.ts +271 -0
  521. package/src/core/common/persistence/data-source.runtime.ts +351 -0
  522. package/src/core/common/persistence/data-store.interface.ts +155 -0
  523. package/src/core/common/persistence/expiry-sweep.ts +105 -0
  524. package/src/core/common/persistence/id-format.ts +43 -0
  525. package/src/core/common/persistence/infrastructure-locks.ts +66 -0
  526. package/src/core/common/persistence/inject-store.decorator.ts +16 -0
  527. package/src/core/common/persistence/lock-store.interface.ts +17 -0
  528. package/src/core/common/persistence/model-descriptor.interface.ts +90 -0
  529. package/src/core/common/persistence/model-metadata.registry.ts +285 -0
  530. package/src/core/common/persistence/mongo/collection-name.ts +87 -0
  531. package/src/core/common/persistence/mongo/declared-schema.view.ts +378 -0
  532. package/src/core/common/persistence/mongo/hex-object-id.ts +75 -0
  533. package/src/core/common/persistence/mongo/model-declarations.ts +135 -0
  534. package/src/core/common/persistence/mongo/mongo-packages.ts +130 -0
  535. package/src/core/common/persistence/mongo/mongoose-compat.ts +129 -0
  536. package/src/core/common/persistence/mongo/no-mongo-connection.module.ts +18 -0
  537. package/src/core/common/persistence/mongo-lock-store.ts +121 -0
  538. package/src/core/common/persistence/mongoose-data-store.ts +232 -0
  539. package/src/core/common/persistence/neutral-populate.ts +98 -0
  540. package/src/core/common/persistence/persisted-model.decorator.ts +61 -0
  541. package/src/core/common/persistence/persistence-runtime.registry.ts +152 -0
  542. package/src/core/common/persistence/persistence.tokens.ts +9 -0
  543. package/src/core/common/persistence/policies/audit.policy.ts +80 -0
  544. package/src/core/common/persistence/policies/password.policy.ts +69 -0
  545. package/src/core/common/persistence/policies/role-guard.policy.ts +74 -0
  546. package/src/core/common/persistence/policies/system-role.policy.ts +90 -0
  547. package/src/core/common/persistence/policies/tenant.policy.ts +245 -0
  548. package/src/core/common/persistence/routed-model.guard.ts +107 -0
  549. package/src/core/common/persistence/sql/mysql/mysql-data-store.ts +503 -0
  550. package/src/core/common/persistence/sql/mysql/mysql-executor.ts +281 -0
  551. package/src/core/common/persistence/sql/mysql/mysql-lock-store.ts +87 -0
  552. package/src/core/common/persistence/sql/mysql/mysql-schema.compiler.ts +424 -0
  553. package/src/core/common/persistence/sql/mysql/mysql-schema.migrator.ts +453 -0
  554. package/src/core/common/persistence/sql/mysql/mysql-session.ts +131 -0
  555. package/src/core/common/persistence/sql/mysql/mysql-update.compiler.ts +379 -0
  556. package/src/core/common/persistence/sql/mysql/mysql-where.compiler.ts +686 -0
  557. package/src/core/common/persistence/sql/postgres/postgres-lock-store.ts +76 -0
  558. package/src/core/common/persistence/sql/postgres/postgres-schema.compiler.ts +328 -0
  559. package/src/core/common/persistence/sql/postgres/postgres-schema.migrator.ts +448 -0
  560. package/src/core/common/persistence/sql/postgres/postgres-update.compiler.ts +310 -0
  561. package/src/core/common/persistence/sql/postgres/postgres-where.compiler.ts +638 -0
  562. package/src/core/common/persistence/sql/sql-cast.ts +227 -0
  563. package/src/core/common/persistence/sql/sql-data-store.ts +762 -0
  564. package/src/core/common/persistence/sql/sql-dialect.ts +85 -0
  565. package/src/core/common/persistence/sql/sql-errors.ts +49 -0
  566. package/src/core/common/persistence/sql/sql-executor.factory.ts +282 -0
  567. package/src/core/common/persistence/sql/sql-executor.interface.ts +57 -0
  568. package/src/core/common/persistence/sql/sql-naming.ts +133 -0
  569. package/src/core/common/persistence/sql/sql-schema.shared.ts +105 -0
  570. package/src/core/common/persistence/sql/sql-session.ts +158 -0
  571. package/src/core/common/persistence/sql/where-shared.ts +118 -0
  572. package/src/core/common/persistence/store-guards.ts +73 -0
  573. package/src/core/common/persistence/store-upsert.ts +36 -0
  574. package/src/core/common/persistence/unavailable-store.ts +63 -0
  575. package/src/core/common/persistence/unsupported-capability.error.ts +7 -0
  576. package/src/core/common/plugins/mongoose-audit-fields.plugin.ts +33 -74
  577. package/src/core/common/plugins/mongoose-id.plugin.ts +9 -0
  578. package/src/core/common/plugins/mongoose-password.plugin.ts +6 -62
  579. package/src/core/common/plugins/mongoose-role-guard.plugin.ts +11 -63
  580. package/src/core/common/plugins/mongoose-system-role.plugin.ts +7 -78
  581. package/src/core/common/plugins/mongoose-tenant.plugin.ts +23 -144
  582. package/src/core/common/scalars/upload.scalar.ts +8 -3
  583. package/src/core/common/services/core-cron-jobs.initializer.ts +1 -1
  584. package/src/core/common/services/core-cron-jobs.service.ts +33 -22
  585. package/src/core/common/services/crud.service.ts +166 -35
  586. package/src/core/common/services/model-doc.service.ts +1 -1
  587. package/src/core/common/services/module.service.ts +78 -6
  588. package/src/core/common/types/field-selection.type.ts +1 -1
  589. package/src/core/common/types/id.type.ts +2 -2
  590. package/src/core/common/types/object-id-like.type.ts +11 -0
  591. package/src/core/common/types/populate-config.type.ts +1 -1
  592. package/src/core/common/types/string-or-object-id.type.ts +2 -2
  593. package/src/core/modules/ai/README.md +15 -2
  594. package/src/core/modules/ai/core-ai.constants.ts +10 -0
  595. package/src/core/modules/ai/core-ai.module.ts +32 -17
  596. package/src/core/modules/ai/models/core-ai-budget-limit.model.ts +2 -2
  597. package/src/core/modules/ai/models/core-ai-connection-preference.model.ts +2 -2
  598. package/src/core/modules/ai/models/core-ai-connection.model.ts +2 -2
  599. package/src/core/modules/ai/models/core-ai-conversation.model.ts +8 -4
  600. package/src/core/modules/ai/models/core-ai-interaction.model.ts +3 -3
  601. package/src/core/modules/ai/models/core-ai-mcp-oauth.models.ts +46 -0
  602. package/src/core/modules/ai/models/core-ai-mode.model.ts +2 -2
  603. package/src/core/modules/ai/models/core-ai-prompt-hint.model.ts +2 -2
  604. package/src/core/modules/ai/models/core-ai-prompt.model.ts +2 -2
  605. package/src/core/modules/ai/models/core-ai-slot.model.ts +2 -2
  606. package/src/core/modules/ai/models/core-ai-tool-grant.model.ts +2 -2
  607. package/src/core/modules/ai/models/core-ai-tool-policy.model.ts +2 -2
  608. package/src/core/modules/ai/services/core-ai-budget.service.ts +22 -4
  609. package/src/core/modules/ai/services/core-ai-connection-preference.service.ts +6 -13
  610. package/src/core/modules/ai/services/core-ai-connection.service.ts +34 -44
  611. package/src/core/modules/ai/services/core-ai-conversation.service.ts +31 -29
  612. package/src/core/modules/ai/services/core-ai-interaction.service.ts +3 -3
  613. package/src/core/modules/ai/services/core-ai-mcp-oauth.service.ts +93 -20
  614. package/src/core/modules/ai/services/core-ai-mode.service.ts +3 -6
  615. package/src/core/modules/ai/services/core-ai-prompt-hint.service.ts +43 -26
  616. package/src/core/modules/ai/services/core-ai-prompt.service.ts +15 -12
  617. package/src/core/modules/ai/services/core-ai-slot.service.ts +20 -24
  618. package/src/core/modules/ai/services/core-ai-tool-grant.service.ts +17 -27
  619. package/src/core/modules/ai/services/core-ai-tool-policy.service.ts +7 -10
  620. package/src/core/modules/api-token/core-api-token.model.ts +1 -1
  621. package/src/core/modules/api-token/core-api-token.module.ts +4 -2
  622. package/src/core/modules/api-token/core-api-token.service.ts +118 -43
  623. package/src/core/modules/auth/core-auth.module.ts +2 -0
  624. package/src/core/modules/auth/guards/legacy-auth-rate-limit.guard.ts +4 -3
  625. package/src/core/modules/auth/guards/role-guard.token.ts +7 -0
  626. package/src/core/modules/auth/services/core-auth.service.ts +16 -2
  627. package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +1 -1
  628. package/src/core/modules/better-auth/README.md +10 -1
  629. package/src/core/modules/better-auth/better-auth-sql.helper.ts +191 -0
  630. package/src/core/modules/better-auth/better-auth-token.service.ts +26 -35
  631. package/src/core/modules/better-auth/better-auth.config.ts +43 -7
  632. package/src/core/modules/better-auth/better-auth.types.ts +1 -1
  633. package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +13 -1
  634. package/src/core/modules/better-auth/core-better-auth-challenge.service.ts +36 -18
  635. package/src/core/modules/better-auth/core-better-auth-mongo.users.ts +35 -0
  636. package/src/core/modules/better-auth/core-better-auth-sql.registry.ts +20 -0
  637. package/src/core/modules/better-auth/core-better-auth-sql.store.ts +309 -0
  638. package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +418 -40
  639. package/src/core/modules/better-auth/core-better-auth.module.ts +71 -35
  640. package/src/core/modules/better-auth/core-better-auth.service.ts +81 -12
  641. package/src/core/modules/file/README.md +16 -3
  642. package/src/core/modules/file/core-file-info.model.ts +2 -2
  643. package/src/core/modules/file/core-file.service.ts +27 -18
  644. package/src/core/modules/file/file-metadata.helper.ts +7 -3
  645. package/src/core/modules/file/file-metadata.models.ts +44 -0
  646. package/src/core/modules/file/file-metadata.store.ts +109 -0
  647. package/src/core/modules/file/file-storage.helper.ts +47 -2
  648. package/src/core/modules/file/filesystem-file.helper.ts +11 -8
  649. package/src/core/modules/file/s3-file.helper.ts +11 -7
  650. package/src/core/modules/health-check/core-health-check.module.ts +16 -2
  651. package/src/core/modules/health-check/core-health-check.service.ts +25 -3
  652. package/src/core/modules/hub/README.md +20 -11
  653. package/src/core/modules/hub/core-hub.controller.ts +5 -0
  654. package/src/core/modules/hub/core-hub.service.ts +1 -1
  655. package/src/core/modules/hub/helpers/hub-client-js.helper.ts +23 -0
  656. package/src/core/modules/hub/hub-action-messages.ts +6 -0
  657. package/src/core/modules/hub/hub-nav.ts +1 -0
  658. package/src/core/modules/hub/interfaces/hub-panels.interface.ts +8 -1
  659. package/src/core/modules/hub/services/core-hub-db.service.ts +35 -17
  660. package/src/core/modules/hub/services/core-hub-migrations.service.ts +96 -2
  661. package/src/core/modules/hub/services/core-hub-sources.service.ts +47 -1
  662. package/src/core/modules/hub/services/hub-query-profiler.service.ts +1 -1
  663. package/src/core/modules/migrate/README.md +54 -0
  664. package/src/core/modules/migrate/cli/migrate-cli.ts +44 -3
  665. package/src/core/modules/migrate/index.ts +3 -0
  666. package/src/core/modules/migrate/migration-runner.ts +3 -2
  667. package/src/core/modules/migrate/migration-state-store.interface.ts +24 -0
  668. package/src/core/modules/migrate/migration.helper.ts +35 -10
  669. package/src/core/modules/migrate/mongo-state-store.ts +64 -65
  670. package/src/core/modules/migrate/sql-migration.helper.ts +48 -0
  671. package/src/core/modules/migrate/sql-state-store.ts +198 -0
  672. package/src/core/modules/system-setup/README.md +14 -2
  673. package/src/core/modules/system-setup/core-system-setup.service.ts +77 -45
  674. package/src/core/modules/tenant/README.md +9 -2
  675. package/src/core/modules/tenant/core-tenant-member.model.ts +1 -1
  676. package/src/core/modules/tenant/core-tenant-member.store.ts +13 -0
  677. package/src/core/modules/tenant/core-tenant.guard.ts +77 -24
  678. package/src/core/modules/tenant/core-tenant.module.ts +6 -3
  679. package/src/core/modules/tenant/core-tenant.service.ts +59 -42
  680. package/src/core/modules/tus/core-tus.service.ts +11 -12
  681. package/src/core/modules/tus/tus.module.ts +1 -1
  682. package/src/core/modules/user/core-user.model.ts +2 -2
  683. package/src/core/modules/user/core-user.service.ts +98 -20
  684. package/src/core.module.ts +60 -5
  685. package/src/index.ts +26 -0
  686. package/src/server/common/models/persistence.model.ts +4 -4
  687. package/src/server/modules/file/file-info.model.ts +1 -1
  688. package/src/server/modules/file/file.service.ts +1 -1
  689. package/src/server/modules/user/user.model.ts +10 -5
  690. package/src/server/modules/user/user.module.ts +9 -3
  691. package/src/server/modules/user/user.service.ts +9 -11
  692. package/src/test/test.helper.ts +2 -2
  693. package/src/types/graphql-upload.d.ts +10 -7
@@ -1,9 +1,9 @@
1
1
  import { Injectable, Logger, Optional } from '@nestjs/common';
2
- import { InjectConnection } from '@nestjs/mongoose';
2
+ import { InjectConnection } from '../../common/persistence/mongo/mongoose-compat.js';
3
3
  import * as bcrypt from 'bcrypt';
4
4
  import { randomBytes, scrypt, ScryptOptions } from 'crypto';
5
5
  import { sha256 } from 'js-sha256';
6
- import { ObjectId } from 'mongodb';
6
+ import type { ObjectId } from 'mongodb';
7
7
  import type { Connection } from 'mongoose';
8
8
 
9
9
  // Promisify Node.js crypto.scrypt
@@ -19,6 +19,9 @@ const scryptPromise = (password: string, salt: string, keylen: number, options:
19
19
  import { RoleEnum } from '../../common/enums/role.enum.js';
20
20
  import { maskEmail } from '../../common/helpers/logging.helper.js';
21
21
  import { legacyCredentialAccountIssuer } from './core-better-auth-account-issuer.helper.js';
22
+ import { getBetterAuthSqlStore } from './core-better-auth-sql.registry.js';
23
+ import type { BetterAuthSqlStore } from './core-better-auth-sql.store.js';
24
+ import { isValidObjectId, newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
22
25
 
23
26
  /**
24
27
  * Interface for Better-Auth session user
@@ -183,7 +186,8 @@ export class CoreBetterAuthUserMapper {
183
186
  }
184
187
 
185
188
  // If no database connection, return user with default roles
186
- if (!this.connection) {
189
+ const sql = getBetterAuthSqlStore();
190
+ if (!this.connection && !sql) {
187
191
  this.logger.warn('No database connection available - using default role mapping');
188
192
  return this.createMappedUser({
189
193
  email: sessionUser.email,
@@ -217,10 +221,12 @@ export class CoreBetterAuthUserMapper {
217
221
 
218
222
  // Look up the user in our database by email OR iamId
219
223
  // This ensures we find the user regardless of which system they signed up with
220
- const userCollection = this.connection.collection('users');
221
- const dbUser = await userCollection.findOne({
222
- $or: [{ email: sessionUser.email }, { iamId: sessionUser.id }],
223
- });
224
+ // (on SQL, Better-Auth's user id IS the row's id — one row per user)
225
+ const dbUser = sql
226
+ ? await sql.findUser({ email: sessionUser.email, iamId: sessionUser.id, id: sessionUser.id })
227
+ : await this.connection?.collection('users').findOne({
228
+ $or: [{ email: sessionUser.email }, { iamId: sessionUser.id }],
229
+ });
224
230
 
225
231
  if (dbUser) {
226
232
  // User exists in our database - use their roles and verified status
@@ -230,14 +236,14 @@ export class CoreBetterAuthUserMapper {
230
236
 
231
237
  // Cache only the minimal data needed (not the full document)
232
238
  if (CoreBetterAuthUserMapper.USER_CACHE_TTL_MS > 0) {
233
- this.cacheUserData(sessionUser.id, { id: dbUser._id.toString(), roles, verified });
239
+ this.cacheUserData(sessionUser.id, { id: String(dbUser._id ?? dbUser.id), roles, verified });
234
240
  }
235
241
 
236
242
  return this.createMappedUser({
237
243
  email: sessionUser.email,
238
244
  emailVerified: sessionUser.emailVerified,
239
245
  iamId: sessionUser.id,
240
- id: dbUser._id.toString(),
246
+ id: String(dbUser._id ?? dbUser.id),
241
247
  image: sessionUser.image,
242
248
  name: sessionUser.name,
243
249
  roles,
@@ -344,6 +350,10 @@ export class CoreBetterAuthUserMapper {
344
350
  * @returns true if sync was successful, false otherwise
345
351
  */
346
352
  async syncPasswordToLegacy(iamUserId: string, userEmail: string, plainPassword?: string): Promise<boolean> {
353
+ const sql = getBetterAuthSqlStore();
354
+ if (sql) {
355
+ return this.syncPasswordToLegacyOnSql(sql, iamUserId, userEmail, plainPassword);
356
+ }
347
357
  if (!this.connection) {
348
358
  this.logger.warn('No database connection available - cannot sync password to legacy');
349
359
  return false;
@@ -403,6 +413,10 @@ export class CoreBetterAuthUserMapper {
403
413
  * @returns true if sync was successful, false otherwise
404
414
  */
405
415
  async syncPasswordChangeToIam(userEmail: string, plainPassword: string): Promise<boolean> {
416
+ const sql = getBetterAuthSqlStore();
417
+ if (sql) {
418
+ return this.syncPasswordChangeToIamOnSql(sql, userEmail, plainPassword);
419
+ }
406
420
  if (!this.connection) {
407
421
  this.logger.warn('No database connection available - cannot sync password to IAM');
408
422
  return false;
@@ -466,6 +480,10 @@ export class CoreBetterAuthUserMapper {
466
480
  * @returns true if account was created, false otherwise
467
481
  */
468
482
  async migrateAccountToIam(userEmail: string, plainPassword?: string): Promise<boolean> {
483
+ const sql = getBetterAuthSqlStore();
484
+ if (sql) {
485
+ return this.migrateAccountToIamOnSql(sql, userEmail, plainPassword);
486
+ }
469
487
  if (!this.connection) {
470
488
  return false;
471
489
  }
@@ -665,6 +683,10 @@ export class CoreBetterAuthUserMapper {
665
683
  if (!sessionUser?.email) {
666
684
  return null;
667
685
  }
686
+ const sql = getBetterAuthSqlStore();
687
+ if (sql) {
688
+ return this.linkOrCreateUserOnSql(sql, sessionUser, additionalData);
689
+ }
668
690
 
669
691
  // Cannot sync without database connection
670
692
  if (!this.connection) {
@@ -680,34 +702,7 @@ export class CoreBetterAuthUserMapper {
680
702
  $or: [{ email: sessionUser.email }, { iamId: sessionUser.id }],
681
703
  });
682
704
 
683
- // Process additionalData to convert termsAndPrivacyAccepted to timestamp
684
- const processedAdditionalData = { ...additionalData };
685
- if (processedAdditionalData?.termsAndPrivacyAccepted === true) {
686
- processedAdditionalData.termsAndPrivacyAcceptedAt = new Date();
687
- delete processedAdditionalData.termsAndPrivacyAccepted;
688
- } else {
689
- delete processedAdditionalData?.termsAndPrivacyAccepted;
690
- }
691
-
692
- const updateData: Record<string, any> = {
693
- email: sessionUser.email,
694
- ...(sessionUser.name && { firstName: sessionUser.name.split(' ')[0] }),
695
- ...(sessionUser.name &&
696
- sessionUser.name.includes(' ') && {
697
- lastName: sessionUser.name.split(' ').slice(1).join(' '),
698
- }),
699
- ...(sessionUser.emailVerified !== undefined && { verified: sessionUser.emailVerified }),
700
- // Deliberately NOT `avatar: sessionUser.image`. `image` is a Better-Auth BUILT-IN column,
701
- // so it is client-writable through `POST /iam/update-user` — it is not covered by
702
- // PROTECTED_INPUT_FALSE_KEYS, which only locks the fields this framework adds. Copying it
703
- // here wrote an attacker-chosen value into `avatar` through a NATIVE driver update, past
704
- // both the `S_NO_ONE` input restriction on the field and every Mongoose plugin. Since the
705
- // avatar endpoint deletes the file the previous value points at, that turned "set your own
706
- // image" into "delete any file in the store". The avatar upload is the only writer.
707
- iamId: sessionUser.id,
708
- updatedAt: new Date(),
709
- ...processedAdditionalData,
710
- };
705
+ const updateData = this.linkedUserFields(sessionUser, existingUser, additionalData);
711
706
 
712
707
  // Build the update query
713
708
  const updateQuery: Record<string, any> = {
@@ -740,6 +735,96 @@ export class CoreBetterAuthUserMapper {
740
735
  }
741
736
  }
742
737
 
738
+ /**
739
+ * The fields `linkOrCreateUser()` writes onto the app user, on MongoDB and on SQL alike
740
+ */
741
+ protected linkedUserFields(
742
+ sessionUser: BetterAuthSessionUser,
743
+ existingUser: null | Record<string, any> | undefined,
744
+ additionalData?: Record<string, any>,
745
+ ): Record<string, any> {
746
+ // Process additionalData to convert termsAndPrivacyAccepted to timestamp
747
+ const processedAdditionalData = { ...additionalData };
748
+ if (processedAdditionalData?.termsAndPrivacyAccepted === true) {
749
+ processedAdditionalData.termsAndPrivacyAcceptedAt = new Date();
750
+ delete processedAdditionalData.termsAndPrivacyAccepted;
751
+ } else {
752
+ delete processedAdditionalData?.termsAndPrivacyAccepted;
753
+ }
754
+
755
+ // Reverse-sync the Better-Auth name into firstName/lastName ONLY when it actually
756
+ // differs from the stored combination. The split is lossy (first word vs. rest), so an
757
+ // unconditional overwrite would clobber locally maintained names on EVERY sign-in —
758
+ // e.g. firstName "Anna Maria" / lastName "von Berg" would mutate to "Anna" / "Maria von
759
+ // Berg" although nothing changed on the Better-Auth side.
760
+ const existingFullName = [existingUser?.firstName, existingUser?.lastName].filter(Boolean).join(' ');
761
+ const nameChangedInIam = !!sessionUser.name && sessionUser.name !== existingFullName;
762
+
763
+ return {
764
+ email: sessionUser.email,
765
+ ...(sessionUser.name && nameChangedInIam && { firstName: sessionUser.name.split(' ')[0] }),
766
+ ...(sessionUser.name &&
767
+ nameChangedInIam &&
768
+ sessionUser.name.includes(' ') && {
769
+ lastName: sessionUser.name.split(' ').slice(1).join(' '),
770
+ }),
771
+ ...(sessionUser.emailVerified !== undefined && { verified: sessionUser.emailVerified }),
772
+ // Deliberately NOT `avatar: sessionUser.image`. `image` is a Better-Auth BUILT-IN column,
773
+ // so it is client-writable through `POST /iam/update-user` — it is not covered by
774
+ // PROTECTED_INPUT_FALSE_KEYS, which only locks the fields this framework adds. Copying it
775
+ // here wrote an attacker-chosen value into `avatar` through a NATIVE driver update, past
776
+ // both the `S_NO_ONE` input restriction on the field and every Mongoose plugin. Since the
777
+ // avatar endpoint deletes the file the previous value points at, that turned "set your own
778
+ // image" into "delete any file in the store". The avatar upload is the only writer.
779
+ iamId: sessionUser.id,
780
+ updatedAt: new Date(),
781
+ ...processedAdditionalData,
782
+ };
783
+ }
784
+
785
+ // ===================================================================================================================
786
+ // Name Sync
787
+ // ===================================================================================================================
788
+
789
+ /**
790
+ * Syncs a name change from Legacy Auth to Better-Auth (IAM)
791
+ *
792
+ * When a user changes their firstName/lastName in Legacy Auth (e.g. via PATCH /users/:id),
793
+ * the Better-Auth `name` field on the shared users document must follow. Without this sync,
794
+ * the next sign-in reverse-syncs the STALE Better-Auth name back into firstName/lastName
795
+ * (see linkOrCreateUser), silently discarding the user's edit.
796
+ *
797
+ * @param userEmail - The user's current email address (lookup key on the shared collection)
798
+ * @param name - The new display name (typically `firstName lastName`). May be empty: a cleared
799
+ * name must reach the Better-Auth side too, or the next sign-in writes the old one back.
800
+ * @returns true if sync was successful, false otherwise
801
+ */
802
+ async syncNameChangeFromLegacy(userEmail: string, name: string): Promise<boolean> {
803
+ const sql = getBetterAuthSqlStore();
804
+ if (sql) {
805
+ return this.syncNameChangeFromLegacyOnSql(sql, userEmail, name);
806
+ }
807
+ if (!this.connection) {
808
+ this.logger.warn('No database connection available - cannot sync name change');
809
+ return false;
810
+ }
811
+
812
+ try {
813
+ const usersCollection = this.connection.collection('users');
814
+ const result = await usersCollection.updateOne({ email: userEmail }, { $set: { name, updatedAt: new Date() } });
815
+ if (result.matchedCount === 0) {
816
+ return false;
817
+ }
818
+ this.logger.debug(`Synced name change from Legacy to IAM for ${maskEmail(userEmail)}`);
819
+ return true;
820
+ } catch (error) {
821
+ this.logger.error(
822
+ `Error syncing name change from Legacy: ${error instanceof Error ? error.message : 'Unknown error'}`,
823
+ );
824
+ return false;
825
+ }
826
+ }
827
+
743
828
  // ===================================================================================================================
744
829
  // Email Sync
745
830
  // ===================================================================================================================
@@ -759,6 +844,10 @@ export class CoreBetterAuthUserMapper {
759
844
  * @returns true if sync was successful, false otherwise
760
845
  */
761
846
  async syncEmailChangeFromLegacy(oldEmail: string, newEmail: string): Promise<boolean> {
847
+ const sql = getBetterAuthSqlStore();
848
+ if (sql) {
849
+ return this.syncEmailChangeFromLegacyOnSql(sql, oldEmail, newEmail);
850
+ }
762
851
  if (!this.connection) {
763
852
  this.logger.warn('No database connection available - cannot sync email change');
764
853
  return false;
@@ -805,6 +894,10 @@ export class CoreBetterAuthUserMapper {
805
894
  * @returns true if sync was successful, false otherwise
806
895
  */
807
896
  async syncEmailChangeFromIam(userId: string, newEmail: string): Promise<boolean> {
897
+ const sql = getBetterAuthSqlStore();
898
+ if (sql) {
899
+ return this.syncEmailChangeFromIamOnSql(sql, userId, newEmail);
900
+ }
808
901
  if (!this.connection) {
809
902
  this.logger.warn('No database connection available - cannot sync email change');
810
903
  return false;
@@ -857,6 +950,10 @@ export class CoreBetterAuthUserMapper {
857
950
  success: boolean;
858
951
  userDeleted: boolean;
859
952
  }> {
953
+ const sql = getBetterAuthSqlStore();
954
+ if (sql) {
955
+ return this.deleteUserFromBothSystemsOnSql(sql, userIdentifier);
956
+ }
860
957
  if (!this.connection) {
861
958
  this.logger.warn('No database connection available - cannot delete user');
862
959
  return { accountsDeleted: 0, sessionsDeleted: 0, success: false, userDeleted: false };
@@ -879,8 +976,8 @@ export class CoreBetterAuthUserMapper {
879
976
  }
880
977
 
881
978
  // Try by MongoDB _id
882
- if (!user && ObjectId.isValid(userIdentifier)) {
883
- user = await usersCollection.findOne({ _id: new ObjectId(userIdentifier) });
979
+ if (!user && isValidObjectId(userIdentifier)) {
980
+ user = await usersCollection.findOne({ _id: newObjectId(userIdentifier) });
884
981
  }
885
982
 
886
983
  if (!user) {
@@ -931,6 +1028,10 @@ export class CoreBetterAuthUserMapper {
931
1028
  sessionsDeleted: number;
932
1029
  success: boolean;
933
1030
  }> {
1031
+ const sql = getBetterAuthSqlStore();
1032
+ if (sql) {
1033
+ return this.cleanupIamDataForDeletedUserOnSql(sql, String(userId));
1034
+ }
934
1035
  if (!this.connection) {
935
1036
  this.logger.warn('No database connection available - cannot cleanup IAM data');
936
1037
  return { accountsDeleted: 0, sessionsDeleted: 0, success: false };
@@ -940,7 +1041,7 @@ export class CoreBetterAuthUserMapper {
940
1041
  const accountCollection = this.connection.collection('account');
941
1042
  const sessionCollection = this.connection.collection('session');
942
1043
 
943
- const userObjectId = typeof userId === 'string' ? new ObjectId(userId) : userId;
1044
+ const userObjectId = typeof userId === 'string' ? newObjectId(userId) : userId;
944
1045
 
945
1046
  // Delete Better-Auth sessions
946
1047
  const sessionsResult = await sessionCollection.deleteMany({ userId: userObjectId });
@@ -971,6 +1072,10 @@ export class CoreBetterAuthUserMapper {
971
1072
  * @returns true if cleanup was successful, false otherwise
972
1073
  */
973
1074
  async cleanupLegacyDataForDeletedIamUser(iamUserId: string): Promise<boolean> {
1075
+ const sql = getBetterAuthSqlStore();
1076
+ if (sql) {
1077
+ return this.cleanupLegacyDataForDeletedIamUserOnSql(sql, iamUserId);
1078
+ }
974
1079
  if (!this.connection) {
975
1080
  this.logger.warn('No database connection available - cannot cleanup Legacy data');
976
1081
  return false;
@@ -1015,6 +1120,10 @@ export class CoreBetterAuthUserMapper {
1015
1120
  // A caller that only needs the counts — the boot-time deprecation warning does — should
1016
1121
  // not pay for a field it discards.
1017
1122
  const includePendingEmails = options?.includePendingEmails !== false;
1123
+ const sql = getBetterAuthSqlStore();
1124
+ if (sql) {
1125
+ return this.getMigrationStatusOnSql(sql, includePendingEmails);
1126
+ }
1018
1127
  if (!this.connection) {
1019
1128
  this.logger.warn('No database connection available - cannot get migration status');
1020
1129
  return {
@@ -1155,4 +1264,273 @@ export class CoreBetterAuthUserMapper {
1155
1264
  };
1156
1265
  }
1157
1266
  }
1267
+
1268
+ // ===================================================================================================================
1269
+ // SQL data source — Better-Auth and the user model share ONE row per user in `users`, and Better-Auth's user id IS
1270
+ // that row's id (see BetterAuthSqlStore). Same behaviour as the MongoDB paths above; only the access differs.
1271
+ // ===================================================================================================================
1272
+
1273
+ protected async syncPasswordToLegacyOnSql(
1274
+ sql: BetterAuthSqlStore,
1275
+ iamUserId: string,
1276
+ userEmail: string,
1277
+ plainPassword?: string,
1278
+ ): Promise<boolean> {
1279
+ if (!plainPassword) {
1280
+ return false;
1281
+ }
1282
+ try {
1283
+ // bcrypt(sha256(password)), as on MongoDB; the password policy keeps a bcrypt value as it is
1284
+ const bcryptHash = await bcrypt.hash(this.normalizePasswordForIam(plainPassword), 10);
1285
+ return !!(await sql.updateUser({ email: userEmail, iamId: iamUserId }, { password: bcryptHash }));
1286
+ } catch (error) {
1287
+ this.logger.error(
1288
+ `Error syncing password to legacy: ${error instanceof Error ? error.message : 'Unknown error'}`,
1289
+ );
1290
+ return false;
1291
+ }
1292
+ }
1293
+
1294
+ protected async syncPasswordChangeToIamOnSql(
1295
+ sql: BetterAuthSqlStore,
1296
+ userEmail: string,
1297
+ plainPassword: string,
1298
+ ): Promise<boolean> {
1299
+ if (!plainPassword) {
1300
+ return false;
1301
+ }
1302
+ try {
1303
+ const user = await sql.findUser({ email: userEmail });
1304
+ if (!user || !(await sql.findCredentialAccount(user.id))) {
1305
+ return false;
1306
+ }
1307
+ await sql.updateCredentialPassword(user.id, await this.hashPasswordForBetterAuth(plainPassword));
1308
+ return true;
1309
+ } catch (error) {
1310
+ this.logger.error(`Error syncing password to IAM: ${error instanceof Error ? error.message : 'Unknown error'}`);
1311
+ return false;
1312
+ }
1313
+ }
1314
+
1315
+ protected async migrateAccountToIamOnSql(
1316
+ sql: BetterAuthSqlStore,
1317
+ userEmail: string,
1318
+ plainPassword?: string,
1319
+ ): Promise<boolean> {
1320
+ try {
1321
+ const legacyUser = await sql.findUser({ email: userEmail });
1322
+ if (!legacyUser?.password) {
1323
+ return false;
1324
+ }
1325
+ // FAST PATH, as on MongoDB: an existing credential account means the user is migrated already
1326
+ if (await sql.findCredentialAccount(legacyUser.id)) {
1327
+ return true;
1328
+ }
1329
+ if (!plainPassword) {
1330
+ return false;
1331
+ }
1332
+ const directMatch = await bcrypt.compare(plainPassword, legacyUser.password);
1333
+ const sha256Match = !directMatch ? await bcrypt.compare(sha256(plainPassword), legacyUser.password) : false;
1334
+ if (!directMatch && !sha256Match) {
1335
+ this.logger.warn(`Migration password verification failed for ${maskEmail(userEmail)}`);
1336
+ return false;
1337
+ }
1338
+ if (!legacyUser.iamId) {
1339
+ // The row IS Better-Auth's user already: link it by its own id instead of minting a second one
1340
+ await sql.updateUser({ id: legacyUser.id }, { iamId: legacyUser.id });
1341
+ await sql.updateIamUser(legacyUser.id, {
1342
+ emailVerified: legacyUser.verified === true,
1343
+ name: [legacyUser.firstName, legacyUser.lastName].filter(Boolean).join(' ') || undefined,
1344
+ });
1345
+ }
1346
+ const credentialIssuer = legacyCredentialAccountIssuer();
1347
+ await sql.createAccount({
1348
+ accountId: legacyUser.id,
1349
+ ...(credentialIssuer ? { issuer: credentialIssuer } : {}),
1350
+ password: await this.hashPasswordForBetterAuth(plainPassword),
1351
+ providerId: 'credential',
1352
+ userId: legacyUser.id,
1353
+ });
1354
+ return true;
1355
+ } catch (error) {
1356
+ this.logger.error(`Error migrating account to IAM: ${error instanceof Error ? error.message : 'Unknown error'}`);
1357
+ return false;
1358
+ }
1359
+ }
1360
+
1361
+ protected async linkOrCreateUserOnSql(
1362
+ sql: BetterAuthSqlStore,
1363
+ sessionUser: BetterAuthSessionUser,
1364
+ additionalData?: Record<string, any>,
1365
+ ): Promise<null | SyncedUserDocument> {
1366
+ try {
1367
+ const match = { email: sessionUser.email, iamId: sessionUser.id, id: sessionUser.id };
1368
+ const existingUser = await sql.findUser(match);
1369
+ if (!existingUser) {
1370
+ // Better-Auth writes the row itself (same table): a missing one is a user Better-Auth does not know either
1371
+ this.logger.warn(`Better-Auth user ${maskEmail(sessionUser.email)} has no row in the users table`);
1372
+ return null;
1373
+ }
1374
+ const synced = await sql.updateUser(
1375
+ { id: existingUser.id },
1376
+ this.linkedUserFields(sessionUser, existingUser, additionalData),
1377
+ );
1378
+ return synced ? ({ ...synced, _id: synced.id } as SyncedUserDocument) : null;
1379
+ } catch (error) {
1380
+ this.logger.error(`Error syncing Better-Auth user: ${error instanceof Error ? error.message : 'Unknown error'}`);
1381
+ return null;
1382
+ }
1383
+ }
1384
+
1385
+ protected async syncNameChangeFromLegacyOnSql(
1386
+ sql: BetterAuthSqlStore,
1387
+ userEmail: string,
1388
+ name: string,
1389
+ ): Promise<boolean> {
1390
+ try {
1391
+ const user = await sql.findUser({ email: userEmail });
1392
+ if (!user) {
1393
+ return false;
1394
+ }
1395
+ // `name` is Better-Auth's field, not the user model's: written through Better-Auth's adapter
1396
+ await sql.updateIamUser(user.id, { name });
1397
+ this.logger.debug(`Synced name change from Legacy to IAM for ${maskEmail(userEmail)}`);
1398
+ return true;
1399
+ } catch (error) {
1400
+ this.logger.error(
1401
+ `Error syncing name change from Legacy: ${error instanceof Error ? error.message : 'Unknown error'}`,
1402
+ );
1403
+ return false;
1404
+ }
1405
+ }
1406
+
1407
+ protected async syncEmailChangeFromLegacyOnSql(
1408
+ sql: BetterAuthSqlStore,
1409
+ oldEmail: string,
1410
+ newEmail: string,
1411
+ ): Promise<boolean> {
1412
+ try {
1413
+ const user = (await sql.findUser({ email: newEmail })) ?? (await sql.findUser({ email: oldEmail }));
1414
+ if (!user) {
1415
+ return false;
1416
+ }
1417
+ await sql.deleteSessions(user.id);
1418
+ this.logger.debug(`Invalidated sessions for email change: ${maskEmail(oldEmail)} → ${maskEmail(newEmail)}`);
1419
+ return true;
1420
+ } catch (error) {
1421
+ this.logger.error(
1422
+ `Error syncing email change from Legacy: ${error instanceof Error ? error.message : 'Unknown error'}`,
1423
+ );
1424
+ return false;
1425
+ }
1426
+ }
1427
+
1428
+ protected async syncEmailChangeFromIamOnSql(
1429
+ sql: BetterAuthSqlStore,
1430
+ userId: string,
1431
+ newEmail: string,
1432
+ ): Promise<boolean> {
1433
+ try {
1434
+ return !!(await sql.updateUser({ iamId: userId, id: userId }, { email: newEmail, refreshTokens: {} }));
1435
+ } catch (error) {
1436
+ this.logger.error(
1437
+ `Error syncing email change from IAM: ${error instanceof Error ? error.message : 'Unknown error'}`,
1438
+ );
1439
+ return false;
1440
+ }
1441
+ }
1442
+
1443
+ protected async deleteUserFromBothSystemsOnSql(
1444
+ sql: BetterAuthSqlStore,
1445
+ userIdentifier: string,
1446
+ ): Promise<{ accountsDeleted: number; sessionsDeleted: number; success: boolean; userDeleted: boolean }> {
1447
+ try {
1448
+ const user =
1449
+ (await sql.findUser({ email: userIdentifier })) ??
1450
+ (await sql.findUser({ iamId: userIdentifier })) ??
1451
+ (await sql.findUser({ id: userIdentifier }));
1452
+ if (!user) {
1453
+ return { accountsDeleted: 0, sessionsDeleted: 0, success: false, userDeleted: false };
1454
+ }
1455
+ const sessionsDeleted = await sql.deleteSessions(user.id);
1456
+ const accountsDeleted = await sql.deleteAccounts(user.id);
1457
+ await sql.deleteUser(user.id);
1458
+ this.logger.log(
1459
+ `Deleted user ${maskEmail(user.email)}: user=true, accounts=${accountsDeleted}, sessions=${sessionsDeleted}`,
1460
+ );
1461
+ return { accountsDeleted, sessionsDeleted, success: true, userDeleted: true };
1462
+ } catch (error) {
1463
+ this.logger.error(`Error deleting user: ${error instanceof Error ? error.message : 'Unknown error'}`);
1464
+ return { accountsDeleted: 0, sessionsDeleted: 0, success: false, userDeleted: false };
1465
+ }
1466
+ }
1467
+
1468
+ protected async cleanupIamDataForDeletedUserOnSql(
1469
+ sql: BetterAuthSqlStore,
1470
+ userId: string,
1471
+ ): Promise<{ accountsDeleted: number; sessionsDeleted: number; success: boolean }> {
1472
+ try {
1473
+ const sessionsDeleted = await sql.deleteSessions(userId);
1474
+ const accountsDeleted = await sql.deleteAccounts(userId);
1475
+ return { accountsDeleted, sessionsDeleted, success: true };
1476
+ } catch (error) {
1477
+ this.logger.error(`Error cleaning up IAM data: ${error instanceof Error ? error.message : 'Unknown error'}`);
1478
+ return { accountsDeleted: 0, sessionsDeleted: 0, success: false };
1479
+ }
1480
+ }
1481
+
1482
+ protected async cleanupLegacyDataForDeletedIamUserOnSql(
1483
+ sql: BetterAuthSqlStore,
1484
+ iamUserId: string,
1485
+ ): Promise<boolean> {
1486
+ try {
1487
+ const user = await sql.findUser({ iamId: iamUserId, id: iamUserId });
1488
+ if (!user) {
1489
+ return false;
1490
+ }
1491
+ await sql.deleteUser(user.id);
1492
+ return true;
1493
+ } catch (error) {
1494
+ this.logger.error(`Error cleaning up Legacy data: ${error instanceof Error ? error.message : 'Unknown error'}`);
1495
+ return false;
1496
+ }
1497
+ }
1498
+
1499
+ protected async getMigrationStatusOnSql(
1500
+ sql: BetterAuthSqlStore,
1501
+ includePendingEmails: boolean,
1502
+ ): Promise<MigrationStatus> {
1503
+ try {
1504
+ const counts = await sql.migrationCounts(includePendingEmails ? 100 : 0);
1505
+ const totalUsers = counts.total;
1506
+ const usersWithIamId = counts.withIamId;
1507
+ const usersWithIamAccount = counts.withIamAccount;
1508
+ const fullyMigratedUsers = counts.fullyMigrated;
1509
+ const pendingMigrationUsers = totalUsers - fullyMigratedUsers;
1510
+ const migrationPercentage = totalUsers > 0 ? Math.round((fullyMigratedUsers / totalUsers) * 100 * 100) / 100 : 0;
1511
+ const pendingUserEmails = counts.pendingEmails;
1512
+ return {
1513
+ canDisableLegacyAuth: totalUsers > 0 && fullyMigratedUsers === totalUsers,
1514
+ fullyMigratedUsers,
1515
+ migrationPercentage,
1516
+ pendingMigrationUsers,
1517
+ pendingUserEmails,
1518
+ totalUsers,
1519
+ usersWithIamAccount,
1520
+ usersWithIamId,
1521
+ };
1522
+ } catch (error) {
1523
+ this.logger.error(`Error getting migration status: ${error instanceof Error ? error.message : 'Unknown error'}`);
1524
+ return {
1525
+ canDisableLegacyAuth: false,
1526
+ fullyMigratedUsers: 0,
1527
+ migrationPercentage: 0,
1528
+ pendingMigrationUsers: 0,
1529
+ pendingUserEmails: [],
1530
+ totalUsers: 0,
1531
+ usersWithIamAccount: 0,
1532
+ usersWithIamId: 0,
1533
+ };
1534
+ }
1535
+ }
1158
1536
  }