@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
@@ -3,7 +3,8 @@ import { ModuleRef } from '@nestjs/core';
3
3
  import { FileStore } from '@tus/file-store';
4
4
  import { Server, Upload } from '@tus/server';
5
5
  import * as fs from 'fs';
6
- import { type Connection, mongo } from 'mongoose';
6
+ import type { Connection } from 'mongoose';
7
+ import type { mongo } from 'mongoose';
7
8
  import * as path from 'path';
8
9
  import { Readable } from 'stream';
9
10
 
@@ -14,13 +15,10 @@ import { ConfigService } from '../../common/services/config.service.js';
14
15
  import { CoreRedisService } from '../../common/services/core-redis.service.js';
15
16
  import { CoreS3Service } from '../../common/services/core-s3.service.js';
16
17
  import { getTenantContextResolver } from '../../common/services/core-tenant-context.registry.js';
18
+ import { fileMetadataCollection } from '../file/file-metadata.store.js';
17
19
  import { resolveFileStorage } from '../file/file-storage.helper.js';
18
- import {
19
- DEFAULT_FILESYSTEM_DIR,
20
- FILESYSTEM_FILES_COLLECTION,
21
- FilesystemFileHelper,
22
- } from '../file/filesystem-file.helper.js';
23
- import { S3_FILES_COLLECTION, S3FileHelper } from '../file/s3-file.helper.js';
20
+ import { DEFAULT_FILESYSTEM_DIR, FilesystemFileHelper } from '../file/filesystem-file.helper.js';
21
+ import { S3FileHelper } from '../file/s3-file.helper.js';
24
22
  import { TUS_FILE_ID_HEADER, TUS_OWNER_METADATA_KEY, TUS_TENANT_METADATA_KEY } from './tus.constants.js';
25
23
  import { TusRedisLocker } from './tus-redis-locker.js';
26
24
  import {
@@ -29,6 +27,7 @@ import {
29
27
  normalizeTusConfig,
30
28
  parseExpirationTime,
31
29
  } from './interfaces/tus-config.interface.js';
30
+ import { createGridFsBucket } from '../../common/persistence/mongo/mongoose-compat.js';
32
31
 
33
32
  /**
34
33
  * Optional dependencies of CoreTusService.
@@ -141,8 +140,8 @@ export class CoreTusService implements OnModuleDestroy, OnModuleInit {
141
140
  return;
142
141
  }
143
142
 
144
- // Initialize GridFS bucket
145
- this.files = new mongo.GridFSBucket(this.connection.db, { bucketName: 'fs' });
143
+ // Initialize GridFS bucket — where MongoDB is connected; finished uploads go to GridFS only on that driver
144
+ this.files = this.connection?.db ? createGridFsBucket(this.connection.db, { bucketName: 'fs' }) : undefined;
146
145
 
147
146
  // Ensure upload directory exists
148
147
  const uploadDir = this.config.uploadDir || DEFAULT_TUS_CONFIG.uploadDir;
@@ -233,7 +232,7 @@ export class CoreTusService implements OnModuleDestroy, OnModuleInit {
233
232
  if (this.canCopyWithinS3(upload)) {
234
233
  const fileInfo = await S3FileHelper.copyFile(
235
234
  this.options.s3Service,
236
- this.connection.db.collection(S3_FILES_COLLECTION),
235
+ fileMetadataCollection(this.connection, 's3'),
237
236
  {
238
237
  contentLength: upload.size,
239
238
  contentType,
@@ -260,14 +259,14 @@ export class CoreTusService implements OnModuleDestroy, OnModuleInit {
260
259
  if (this.fileStorageDriver === 'filesystem') {
261
260
  fileInfo = await FilesystemFileHelper.writeFile(
262
261
  this.fileStorageDir,
263
- this.connection.db.collection(FILESYSTEM_FILES_COLLECTION),
262
+ fileMetadataCollection(this.connection, 'filesystem'),
264
263
  { body: readStream, contentType, filename, metadata: fileMetadata },
265
264
  );
266
265
  this.logger.debug(`Upload ${upload.id} migrated to the filesystem as ${fileInfo._id} (filename: ${filename})`);
267
266
  } else if (this.s3FileStorage) {
268
267
  fileInfo = await S3FileHelper.writeFile(
269
268
  this.options.s3Service,
270
- this.connection.db.collection(S3_FILES_COLLECTION),
269
+ fileMetadataCollection(this.connection, 's3'),
271
270
  // Streamed with the length TUS already knows, so a multi-GB resumable upload is never
272
271
  // materialised in memory.
273
272
  { body: readStream, contentLength: upload.size, contentType, filename, metadata: fileMetadata },
@@ -1,7 +1,7 @@
1
1
  import { DynamicModule, Global, Logger, Module, OnModuleInit, Type } from '@nestjs/common';
2
2
  import { PATH_METADATA } from '@nestjs/common/constants';
3
3
  import { ModuleRef } from '@nestjs/core';
4
- import { getConnectionToken } from '@nestjs/mongoose';
4
+ import { getConnectionToken } from '../../common/persistence/mongo/mongoose-compat.js';
5
5
  import type { Connection } from 'mongoose';
6
6
 
7
7
  import { ITusConfig } from '../../common/interfaces/server-options.interface.js';
@@ -1,7 +1,7 @@
1
1
  import { ObjectType } from '@nestjs/graphql';
2
- import { Schema as MongooseSchema, Prop, raw } from '@nestjs/mongoose';
2
+ import { Prop, raw, Schema as MongooseSchema } from '../../common/persistence/mongo/mongoose-compat.js';
3
3
  import { ApiExtraModels, ApiProperty } from '@nestjs/swagger';
4
- import { Document } from 'mongoose';
4
+ import type { Document } from 'mongoose';
5
5
 
6
6
  import { Restricted } from '../../common/decorators/restricted.decorator.js';
7
7
  import { UnifiedField } from '../../common/decorators/unified-field.decorator.js';
@@ -2,7 +2,7 @@ import { BadRequestException, Logger, NotFoundException, UnprocessableEntityExce
2
2
  import bcrypt from 'bcrypt';
3
3
  import * as crypto from 'crypto';
4
4
  import { sha256 } from 'js-sha256';
5
- import { Document, Model } from 'mongoose';
5
+ import type { Document, Model } from 'mongoose';
6
6
 
7
7
  import { looksLikeSystemRole, SYSTEM_ROLE_PREFIX } from '../../common/enums/role.enum.js';
8
8
  import { accessDeniedException } from '../../common/exceptions/access-denied.exception.js';
@@ -11,6 +11,7 @@ import { revalidateWsConnectionsOf } from '../../common/helpers/graphql-ws-conne
11
11
  import { maskEmail } from '../../common/helpers/logging.helper.js';
12
12
  import { assignPlain, isQueryableString, prepareServiceOptionsForCreate } from '../../common/helpers/input.helper.js';
13
13
  import { ServiceOptions } from '../../common/interfaces/service-options.interface.js';
14
+ import { isWellFormedId } from '../../common/persistence/id-format.js';
14
15
  import { ConfigService } from '../../common/services/config.service.js';
15
16
  import { CrudService } from '../../common/services/crud.service.js';
16
17
  import { ErrorCode } from '../error-code/error-codes.js';
@@ -125,7 +126,9 @@ export abstract class CoreUserService<
125
126
  // window exists on a freshly deployed production database. The index
126
127
  // remains the backstop for truly concurrent duplicate requests.
127
128
  if (data.input?.email) {
128
- const existing = await this.mainDbModel.findOne({ email: data.input.email }).lean().exec();
129
+ const existing = this.usesNeutralStore
130
+ ? await this.dataStore.findOne({ email: data.input.email })
131
+ : await this.mainDbModel.findOne({ email: data.input.email }).lean().exec();
129
132
  if (existing) {
130
133
  throw new BadRequestException('Email address already in use');
131
134
  }
@@ -133,15 +136,19 @@ export abstract class CoreUserService<
133
136
 
134
137
  // Create user with verification token
135
138
  const currentUserId = serviceOptions?.currentUser?._id;
136
- const createdUser = new this.mainDbModel({
139
+ const fields = {
137
140
  ...data.input,
138
141
  createdBy: currentUserId,
139
142
  updatedBy: currentUserId,
140
143
  verificationToken: crypto.randomBytes(32).toString('hex'),
141
- });
144
+ };
145
+ const createdUser = this.usesNeutralStore ? undefined : new this.mainDbModel(fields);
142
146
 
143
147
  // Distinguish between different error messages when saving
144
148
  try {
149
+ if (!createdUser) {
150
+ return await this.dataStore.insert(fields);
151
+ }
145
152
  await createdUser.save();
146
153
  } catch (error) {
147
154
  if (error?.errors?.email?.kind === 'unique' || error?.code === 11000) {
@@ -158,11 +165,27 @@ export abstract class CoreUserService<
158
165
  );
159
166
  }
160
167
 
168
+ /**
169
+ * The stored user matching `where`: the Mongoose document on MongoDB — what this service always worked with — and
170
+ * the plain record when the user model is routed to a SQL store
171
+ */
172
+ protected async findStoredUser(where: Record<string, unknown>): Promise<any> {
173
+ return this.usesNeutralStore ? this.dataStore.findOne(where) : this.mainDbModel.findOne(where).exec();
174
+ }
175
+
176
+ /** Write `changes` to a stored user (as `findStoredUser()` returned it) and return it as stored afterwards */
177
+ protected async saveStoredUser(stored: any, changes: Record<string, unknown>): Promise<any> {
178
+ if (this.usesNeutralStore) {
179
+ return this.dataStore.updateById(stored.id, changes as any);
180
+ }
181
+ return assignPlain(stored, changes).save();
182
+ }
183
+
161
184
  /**
162
185
  * Get user via email
163
186
  */
164
187
  async getViaEmail(email: string, serviceOptions?: ServiceOptions): Promise<TUser> {
165
- const dbObject = await this.mainDbModel.findOne({ email }).exec();
188
+ const dbObject = await this.findStoredUser({ email });
166
189
  if (!dbObject) {
167
190
  throw new NotFoundException(`No user found with email: ${email}`);
168
191
  }
@@ -181,6 +204,10 @@ export abstract class CoreUserService<
181
204
  * @returns User object or null if not found
182
205
  */
183
206
  async getByIdOrIamId(idOrIamId: string): Promise<null | TUser> {
207
+ if (this.usesNeutralStore) {
208
+ const byId = isWellFormedId(String(idOrIamId)) ? await this.dataStore.findById(String(idOrIamId)) : null;
209
+ return (byId ?? (await this.dataStore.findOne({ iamId: idOrIamId }))) as null | TUser;
210
+ }
184
211
  try {
185
212
  // First, try to find by MongoDB _id
186
213
  const byId = await this.mainDbModel.findById(idOrIamId).exec();
@@ -204,7 +231,7 @@ export abstract class CoreUserService<
204
231
  return false;
205
232
  }
206
233
 
207
- const user = await this.mainDbModel.findOne({ verificationToken: token }).exec();
234
+ const user = await this.findStoredUser({ verificationToken: token });
208
235
 
209
236
  if (!user) {
210
237
  throw new NotFoundException(`No user found with verify token: ${token}`);
@@ -222,7 +249,7 @@ export abstract class CoreUserService<
222
249
  throw new NotFoundException(ErrorCode.INVALID_TOKEN);
223
250
  }
224
251
 
225
- const dbObject = await this.mainDbModel.findOne({ verificationToken: token }).exec();
252
+ const dbObject = await this.findStoredUser({ verificationToken: token });
226
253
  if (!dbObject) {
227
254
  throw new NotFoundException(`No user found with verify token: ${token}`);
228
255
  }
@@ -238,6 +265,9 @@ export abstract class CoreUserService<
238
265
  return this.process(
239
266
  async () => {
240
267
  // Update and return user
268
+ if (this.usesNeutralStore) {
269
+ return this.dataStore.updateById(dbObject.id, { verified: true, verifiedAt: new Date() } as any);
270
+ }
241
271
  await this.mainDbModel.updateOne({ _id: dbObject.id }, { verified: true, verifiedAt: new Date() }).exec();
242
272
  // Return the updated user
243
273
  return await this.mainDbModel.findById(dbObject.id).exec();
@@ -262,7 +292,7 @@ export abstract class CoreUserService<
262
292
  throw new NotFoundException(ErrorCode.LINK_INVALID_OR_EXPIRED);
263
293
  }
264
294
 
265
- const dbObject = await this.mainDbModel.findOne({ passwordResetToken: token }).exec();
295
+ const dbObject = await this.findStoredUser({ passwordResetToken: token });
266
296
 
267
297
  // An EXPIRED token is answered exactly like an unknown one — same exception, same 404. The
268
298
  // distinction would tell a caller holding a stale token that it was once real and belongs to a
@@ -270,12 +300,15 @@ export abstract class CoreUserService<
270
300
  if (dbObject && this.isPasswordResetTokenExpired(dbObject.passwordResetTokenExpiresAt)) {
271
301
  // Burn it on sight rather than leaving it to be retried. It is worthless now, and a value
272
302
  // that stays in the row is one a later change could start honouring again.
273
- await this.mainDbModel
274
- // `$unset`, not `$set: null` — a null still counts as present, so it would keep an entry
275
- // in the partial index the token field carries and grow it by one per user who ever
276
- // requested a reset.
277
- .updateOne({ _id: dbObject._id }, { $unset: { passwordResetToken: 1, passwordResetTokenExpiresAt: 1 } })
278
- .exec();
303
+ // `$unset`, not `$set: null` — a null still counts as present, so it would keep an entry
304
+ // in the partial index the token field carries and grow it by one per user who ever
305
+ // requested a reset.
306
+ const burn = { $unset: { passwordResetToken: 1 as const, passwordResetTokenExpiresAt: 1 as const } };
307
+ if (this.usesNeutralStore) {
308
+ await this.dataStore.updateById(dbObject.id, burn);
309
+ } else {
310
+ await this.mainDbModel.updateOne({ _id: dbObject._id }, burn).exec();
311
+ }
279
312
  this.userServiceLogger.debug(`Rejected an expired password-reset token for ${maskEmail(dbObject.email)}`);
280
313
  }
281
314
 
@@ -325,7 +358,7 @@ export abstract class CoreUserService<
325
358
  }
326
359
 
327
360
  // Update Legacy Auth password
328
- const updatedUser = await assignPlain(dbObject, {
361
+ const updatedUser = await this.saveStoredUser(dbObject, {
329
362
  password: await bcrypt.hash(newPassword, 10),
330
363
  passwordResetToken: null,
331
364
  passwordResetTokenExpiresAt: null,
@@ -338,7 +371,7 @@ export abstract class CoreUserService<
338
371
  // Without this, "the reset now lands in both stores" would still leave the account
339
372
  // reachable with the credential the reset was meant to retire.
340
373
  refreshTokens: {},
341
- }).save();
374
+ });
342
375
 
343
376
  // Sync password to Better-Auth (IAM) if mapper is available
344
377
  // This ensures users can sign in via IAM after password reset
@@ -455,7 +488,7 @@ export abstract class CoreUserService<
455
488
  }
456
489
 
457
490
  // Get user
458
- const dbObject = await this.mainDbModel.findOne({ email }).exec();
491
+ const dbObject = await this.findStoredUser({ email });
459
492
  if (!dbObject) {
460
493
  const preventEnumeration =
461
494
  this.configService.getFastButReadOnly('auth')?.passwordReset?.preventUserEnumeration !== false;
@@ -478,6 +511,12 @@ export abstract class CoreUserService<
478
511
  const user = await this.process(
479
512
  async () => {
480
513
  // Set reset token and return
514
+ if (this.usesNeutralStore) {
515
+ return this.dataStore.updateById(dbObject.id, {
516
+ passwordResetToken: token,
517
+ passwordResetTokenExpiresAt: expiresAt,
518
+ } as any);
519
+ }
481
520
  dbObject.passwordResetToken = token;
482
521
  dbObject.passwordResetTokenExpiresAt = expiresAt;
483
522
 
@@ -646,7 +685,9 @@ export abstract class CoreUserService<
646
685
  // Update and return user
647
686
  return this.process(
648
687
  async () => {
649
- const user = await this.mainDbModel.findByIdAndUpdate(userId, { roles }).exec();
688
+ const user = this.usesNeutralStore
689
+ ? await this.dataStore.updateById(String(userId), { roles } as any)
690
+ : await this.mainDbModel.findByIdAndUpdate(userId, { roles }).exec();
650
691
 
651
692
  // Invalidate BetterAuth user cache so changed roles take effect immediately
652
693
  if (this.options?.betterAuthUserMapper && (user as any)?.iamId) {
@@ -680,7 +721,9 @@ export abstract class CoreUserService<
680
721
  */
681
722
  override async update(id: string, input: TUserInput, serviceOptions?: ServiceOptions): Promise<TUser> {
682
723
  // Get the current user before update to detect email changes
683
- const oldUser = (await this.mainDbModel.findById(id).lean().exec()) as null | TUser;
724
+ const oldUser = (
725
+ this.usesNeutralStore ? await this.dataStore.findById(id) : await this.mainDbModel.findById(id).lean().exec()
726
+ ) as null | TUser;
684
727
  const oldEmail = oldUser?.email;
685
728
 
686
729
  this.assertCredentialChangeAllowed(oldUser, input, serviceOptions);
@@ -710,6 +753,37 @@ export abstract class CoreUserService<
710
753
  }
711
754
  }
712
755
 
756
+ // Sync name change to IAM if firstName/lastName was changed and mapper is available.
757
+ // Without this, the next sign-in reverse-syncs the STALE Better-Auth `name` back into
758
+ // firstName/lastName (linkOrCreateUser), silently discarding the user's edit.
759
+ if (this.options?.betterAuthUserMapper && (input.firstName !== undefined || input.lastName !== undefined)) {
760
+ // The names come from the STORED record, not from `updatedUser`: that one went through the
761
+ // output pipeline, which strips every field the caller may not read. A caller allowed to
762
+ // edit one name field but not to read the other would otherwise sync a truncated name.
763
+ const stored = (
764
+ this.usesNeutralStore
765
+ ? await this.dataStore.findById(id, { select: ['email', 'firstName', 'lastName'] })
766
+ : await this.mainDbModel.findById(id).select('email firstName lastName').lean().exec()
767
+ ) as null | TUser;
768
+ // An emptied name is synced as well. Skipping it left the old Better-Auth `name` in place,
769
+ // and the next IAM sign-in wrote it back into the fields the user had just cleared.
770
+ const fullName = [stored?.firstName, stored?.lastName].filter(Boolean).join(' ');
771
+ const currentEmail = stored?.email ?? oldEmail;
772
+ if (currentEmail) {
773
+ try {
774
+ const synced = await this.options.betterAuthUserMapper.syncNameChangeFromLegacy(currentEmail, fullName);
775
+ if (synced) {
776
+ this.userServiceLogger.debug(`Synced name change from Legacy to IAM for user ${maskEmail(currentEmail)}`);
777
+ }
778
+ } catch (error) {
779
+ this.userServiceLogger.warn(
780
+ `Failed to sync name change to IAM for ${maskEmail(currentEmail)}: ${error instanceof Error ? error.message : 'Unknown error'}`,
781
+ );
782
+ // Don't throw - name sync failure shouldn't block the update
783
+ }
784
+ }
785
+ }
786
+
713
787
  // Sync password change to IAM if password was changed and mapper is available
714
788
  if (this.options?.betterAuthUserMapper && passwordForIamSync && oldUser?.email) {
715
789
  try {
@@ -815,7 +889,11 @@ export abstract class CoreUserService<
815
889
  */
816
890
  override async delete(id: string, serviceOptions?: ServiceOptions): Promise<TUser> {
817
891
  // Get the user before deletion to cleanup IAM data
818
- const user = (await this.mainDbModel.findById(id).lean().exec()) as null | (TUser & { _id: any });
892
+ const user = (
893
+ this.usesNeutralStore
894
+ ? await this.dataStore.findById(id).then((record) => record && { ...record, _id: record.id })
895
+ : await this.mainDbModel.findById(id).lean().exec()
896
+ ) as null | (TUser & { _id: any });
819
897
 
820
898
  // Perform the deletion
821
899
  const deletedUser = await super.delete(id, serviceOptions);
@@ -10,10 +10,8 @@ import {
10
10
  } from '@nestjs/common';
11
11
  import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE, DiscoveryModule } from '@nestjs/core';
12
12
  import { GraphQLModule } from '@nestjs/graphql';
13
- import { MongooseModule } from '@nestjs/mongoose';
14
13
  import type { Context } from 'graphql-ws';
15
- import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js';
16
- import mongoose from 'mongoose';
14
+ import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
17
15
 
18
16
  import { MongooseCastErrorFilter } from './core/common/filters/mongoose-cast-error.filter.js';
19
17
  import { merge } from './core/common/helpers/config.helper.js';
@@ -40,6 +38,19 @@ import {
40
38
  } from './core/common/interfaces/server-options.interface.js';
41
39
  import { RequestContextMiddleware } from './core/common/middleware/request-context.middleware.js';
42
40
  import { SecurityHeadersMiddleware } from './core/common/middlewares/security-headers.middleware.js';
41
+ import { CorePersistenceLifecycle } from './core/common/persistence/core-persistence.lifecycle.js';
42
+ import { CorePersistenceModule } from './core/common/persistence/core-persistence.module.js';
43
+ import {
44
+ assertDataSourcesSupported,
45
+ DataSourceConfigError,
46
+ hasSqlSource,
47
+ usesMongoDb,
48
+ resolveDataSources,
49
+ } from './core/common/persistence/data-source.config.js';
50
+ import { DataSourceRuntime } from './core/common/persistence/data-source.runtime.js';
51
+ import { requireMongoPackages } from './core/common/persistence/mongo/mongo-packages.js';
52
+ import { NoMongoConnectionModule } from './core/common/persistence/mongo/no-mongo-connection.module.js';
53
+ import { setPersistenceRuntime } from './core/common/persistence/persistence-runtime.registry.js';
43
54
  import { MapAndValidatePipe } from './core/common/pipes/map-and-validate.pipe.js';
44
55
  import { ComplexityPlugin } from './core/common/plugins/complexity.plugin.js';
45
56
  import { mongooseIdPlugin } from './core/common/plugins/mongoose-id.plugin.js';
@@ -65,6 +76,7 @@ import { CoreBetterAuthModule } from './core/modules/better-auth/core-better-aut
65
76
  import { CoreBetterAuthService } from './core/modules/better-auth/core-better-auth.service.js';
66
77
  import { ErrorCodeModule } from './core/modules/error-code/error-code.module.js';
67
78
  import { CoreFileAccessAuditInitializer } from './core/modules/file/core-file-access-audit.initializer.js';
79
+ import { FILE_METADATA_MODELS } from './core/modules/file/file-metadata.models.js';
68
80
  import { applyFileRoles, warnOnPresignedDownloadsWithRestrictedRoles } from './core/modules/file/file-roles.helper.js';
69
81
  import { CoreHealthCheckModule } from './core/modules/health-check/core-health-check.module.js';
70
82
  import { CoreHubModule } from './core/modules/hub/core-hub.module.js';
@@ -267,6 +279,25 @@ export class CoreModule implements NestModule {
267
279
  options,
268
280
  );
269
281
 
282
+ // Resolve where models are stored, and refuse what this version cannot wire before anything connects.
283
+ // `explicitMongoose` separates a project's own mongoose config from the fallback URI merged in above.
284
+ const dataSources = resolveDataSources({
285
+ database: options?.database,
286
+ explicitMongoose: !!options?.mongoose,
287
+ mongooseUri: config.mongoose?.uri,
288
+ });
289
+ assertDataSourcesSupported(dataSources);
290
+ // A MongoDB default source set through `database` is the database Mongoose connects to. Without this the
291
+ // URL passed the guard and the connection still used the fallback URI — another database, silently.
292
+ const defaultSource = dataSources.defaultSource ? dataSources.sources[dataSources.defaultSource] : undefined;
293
+ if (defaultSource?.driver === 'mongodb') {
294
+ config.mongoose.uri = defaultSource.url;
295
+ }
296
+ // A SQL source routes the models registered with CorePersistenceModule.forFeature() to it; without one, nothing
297
+ // is installed and every model keeps its Mongoose store
298
+ const sqlSources = hasSqlSource(dataSources);
299
+ setPersistenceRuntime(sqlSources ? new DataSourceRuntime(dataSources) : undefined);
300
+
270
301
  // Wrap connectionFactory to add security plugins (password hashing, role guard)
271
302
  const originalConnectionFactory = config.mongoose?.options?.connectionFactory;
272
303
  config.mongoose.options = config.mongoose.options || {};
@@ -345,6 +376,9 @@ export class CoreModule implements NestModule {
345
376
  TemplateService,
346
377
  MailjetService,
347
378
  ];
379
+ if (sqlSources) {
380
+ providers.push(CorePersistenceLifecycle);
381
+ }
348
382
 
349
383
  // Add ComplexityPlugin only if not in Vitest (Vitest has dual GraphQL loading issue) and GraphQL is enabled
350
384
  if (!process.env.VITEST && isGraphQlEnabled) {
@@ -410,10 +444,17 @@ export class CoreModule implements NestModule {
410
444
  providers.push(ModelDocService);
411
445
  }
412
446
 
447
+ // MongoDB is connected only where a source uses it — the `mongoose` configuration, or `database` naming MongoDB (or
448
+ // absent, which keeps today's single MongoDB). A project on PostgreSQL alone connects to no MongoDB and needs none
449
+ // of its libraries (optional peers since 12.1.0); configured without them, the boot fails with what to install.
450
+ const mongoPackages = usesMongoDb(dataSources)
451
+ ? requireMongoPackages('The MongoDB data source (the `mongoose` configuration, or `database` naming MongoDB)')
452
+ : undefined;
453
+
413
454
  // Set strict query to false by default
414
455
  // See: https://github.com/Automattic/mongoose/issues/10763
415
456
  // and: https://mongoosejs.com/docs/guide.html#strictQuery
416
- mongoose.set('strictQuery', config.mongoose.strictQuery || false);
457
+ mongoPackages?.mongoose.set('strictQuery', config.mongoose.strictQuery || false);
417
458
 
418
459
  // Opt the MongoDB driver into command monitoring only when the Hub query profiler is enabled
419
460
  // (zero cost otherwise). An explicit `monitorCommands: false` by the consumer wins — the profiler
@@ -427,7 +468,14 @@ export class CoreModule implements NestModule {
427
468
 
428
469
  // DiscoveryModule: CoreFileAccessAuditInitializer needs the registered controller/resolver
429
470
  // classes, which only exist once Nest has built its route table.
430
- const imports: any[] = [DiscoveryModule, MongooseModule.forRoot(config.mongoose.uri, config.mongoose.options)];
471
+ const imports: any[] = [
472
+ DiscoveryModule,
473
+ mongoPackages
474
+ ? mongoPackages.nestMongoose.MongooseModule.forRoot(config.mongoose.uri, config.mongoose.options)
475
+ : NoMongoConnectionModule,
476
+ // The metadata of S3 and filesystem files, routed like every model: on a SQL default source it lives in tables
477
+ CorePersistenceModule.forFeature(FILE_METADATA_MODELS),
478
+ ];
431
479
 
432
480
  if (isGraphQlEnabled && config.graphQl) {
433
481
  imports.push(
@@ -518,6 +566,13 @@ export class CoreModule implements NestModule {
518
566
  // IAM-only mode: enabled unless explicitly disabled
519
567
  // Legacy mode: enabled only if explicitly enabled
520
568
  const isBetterAuthEnabled = isIamOnlyMode ? !isExplicitlyDisabled : isExplicitlyEnabled;
569
+ // Better-Auth keeps its users in a database; `database: false` has none to give it
570
+ if (dataSources.disabled && isBetterAuthEnabled) {
571
+ throw new DataSourceConfigError(
572
+ '`database: false` runs without a database, and Better-Auth keeps its users in one — set `betterAuth: false` ' +
573
+ 'or configure a data source',
574
+ );
575
+ }
521
576
 
522
577
  const isAutoRegister = typeof betterAuthConfig === 'object' && betterAuthConfig?.autoRegister === true;
523
578
  // autoRegister: false means the project imports its own BetterAuthModule separately
package/src/index.ts CHANGED
@@ -83,6 +83,29 @@ export * from './core/common/middlewares/security-headers.middleware.js';
83
83
  export * from './core/common/models/core-model.model.js';
84
84
  export * from './core/common/models/core-persistence.model.js';
85
85
  export * from './core/common/models/pagination-info.model.js';
86
+ export * from './core/common/persistence/core-persistence.module.js';
87
+ export * from './core/common/persistence/data-source.config.js';
88
+ export * from './core/common/persistence/data-store.interface.js';
89
+ export * from './core/common/persistence/id-format.js';
90
+ export * from './core/common/persistence/inject-store.decorator.js';
91
+ export * from './core/common/persistence/lock-store.interface.js';
92
+ export * from './core/common/persistence/model-descriptor.interface.js';
93
+ export * from './core/common/persistence/model-metadata.registry.js';
94
+ export * from './core/common/persistence/mongo/mongo-packages.js';
95
+ export * from './core/common/persistence/mongo/mongoose-compat.js';
96
+ export * from './core/common/persistence/mongo-lock-store.js';
97
+ export * from './core/common/persistence/mongoose-data-store.js';
98
+ export * from './core/common/persistence/persisted-model.decorator.js';
99
+ export * from './core/common/persistence/persistence.tokens.js';
100
+ export * from './core/common/persistence/persistence-runtime.registry.js';
101
+ export * from './core/common/persistence/unsupported-capability.error.js';
102
+ export * from './core/common/persistence/sql/mysql/mysql-data-store.js';
103
+ export * from './core/common/persistence/sql/mysql/mysql-lock-store.js';
104
+ export * from './core/common/persistence/sql/postgres/postgres-lock-store.js';
105
+ export * from './core/common/persistence/sql/sql-data-store.js';
106
+ export * from './core/common/persistence/sql/sql-errors.js';
107
+ export * from './core/common/persistence/sql/sql-executor.factory.js';
108
+ export * from './core/common/persistence/sql/sql-executor.interface.js';
86
109
  export * from './core/common/pipes/check-input.pipe.js';
87
110
  export * from './core/common/pipes/map-and-validate.pipe.js';
88
111
  export * from './core/common/plugins/complexity.plugin.js';
@@ -122,6 +145,7 @@ export * from './core/common/types/id.type.js';
122
145
  export * from './core/common/types/ids.type.js';
123
146
  export * from './core/common/types/is-one-of.type.js';
124
147
  export * from './core/common/types/maybe-promise.type.js';
148
+ export * from './core/common/types/object-id-like.type.js';
125
149
  export * from './core/common/types/plain-input.type.js';
126
150
  export * from './core/common/types/plain-object-deep.type.js';
127
151
  export * from './core/common/types/plain-object.type.js';
@@ -204,6 +228,8 @@ export * from './core/modules/file/core-file.controller.js';
204
228
  export * from './core/modules/file/core-file.resolver.js';
205
229
  export * from './core/modules/file/core-file.service.js';
206
230
  export * from './core/modules/file/file-access.helper.js';
231
+ export * from './core/modules/file/file-metadata.models.js';
232
+ export * from './core/modules/file/file-metadata.store.js';
207
233
  export * from './core/modules/file/file-roles.helper.js';
208
234
  export * from './core/modules/file/file-storage.helper.js';
209
235
  export * from './core/modules/file/filesystem-file.helper.js';
@@ -1,12 +1,12 @@
1
1
  import { ObjectType } from '@nestjs/graphql';
2
2
  import { ApiExtraModels } from '@nestjs/swagger';
3
- import { Types } from 'mongoose';
4
- import mongoose from 'mongoose';
3
+ import type { Types } from 'mongoose';
5
4
 
6
5
  import { Restricted } from '../../../core/common/decorators/restricted.decorator.js';
7
6
  import { UnifiedField } from '../../../core/common/decorators/unified-field.decorator.js';
8
7
  import { RoleEnum } from '../../../core/common/enums/role.enum.js';
9
8
  import { CorePersistenceModel } from '../../../core/common/models/core-persistence.model.js';
9
+ import { objectIdType } from '../../../core/common/persistence/mongo/mongoose-compat.js';
10
10
  import { User } from '../../modules/user/user.model.js';
11
11
 
12
12
  /**
@@ -33,7 +33,7 @@ export abstract class PersistenceModel extends CorePersistenceModel {
33
33
  @UnifiedField({
34
34
  description: 'ID of the user who created the object',
35
35
  isOptional: true,
36
- mongoose: { ref: 'User', type: mongoose.Schema.Types.ObjectId },
36
+ mongoose: { ref: 'User', type: objectIdType() },
37
37
  roles: RoleEnum.ADMIN,
38
38
  swaggerApiOptions: { type: String },
39
39
  type: () => User,
@@ -48,7 +48,7 @@ export abstract class PersistenceModel extends CorePersistenceModel {
48
48
  @UnifiedField({
49
49
  description: 'ID of the user who updated the object',
50
50
  isOptional: true,
51
- mongoose: { ref: 'User', type: mongoose.Schema.Types.ObjectId },
51
+ mongoose: { ref: 'User', type: objectIdType() },
52
52
  roles: RoleEnum.ADMIN,
53
53
  swaggerApiOptions: { type: User },
54
54
  type: () => User,
@@ -1,5 +1,5 @@
1
1
  import { ObjectType } from '@nestjs/graphql';
2
- import { Schema as MongooseSchema, SchemaFactory } from '@nestjs/mongoose';
2
+ import { Schema as MongooseSchema, SchemaFactory } from '../../../core/common/persistence/mongo/mongoose-compat.js';
3
3
 
4
4
  import { Restricted } from '../../../core/common/decorators/restricted.decorator.js';
5
5
  import { RoleEnum } from '../../../core/common/enums/role.enum.js';
@@ -1,5 +1,5 @@
1
1
  import { Injectable, Optional } from '@nestjs/common';
2
- import { InjectConnection } from '@nestjs/mongoose';
2
+ import { InjectConnection } from '../../../core/common/persistence/mongo/mongoose-compat.js';
3
3
  import type { Connection } from 'mongoose';
4
4
 
5
5
  import { RoleEnum } from '../../../core/common/enums/role.enum.js';
@@ -1,7 +1,12 @@
1
1
  import { ObjectType } from '@nestjs/graphql';
2
- import { Schema as MongooseSchema, Prop, SchemaFactory } from '@nestjs/mongoose';
2
+ import {
3
+ objectIdType,
4
+ Prop,
5
+ Schema as MongooseSchema,
6
+ SchemaFactory,
7
+ } from '../../../core/common/persistence/mongo/mongoose-compat.js';
3
8
  import { IsEmail } from 'class-validator';
4
- import { Document, Schema } from 'mongoose';
9
+ import type { Document } from 'mongoose';
5
10
 
6
11
  import { Restricted } from '../../../core/common/decorators/restricted.decorator.js';
7
12
  import { Translatable } from '../../../core/common/decorators/translatable.decorator.js';
@@ -48,7 +53,7 @@ export class User extends CoreUserModel implements PersistenceModel {
48
53
  @UnifiedField({
49
54
  description: 'ID of the user who created the object',
50
55
  isOptional: true,
51
- mongoose: { ref: 'User', type: Schema.Types.ObjectId },
56
+ mongoose: { ref: 'User', type: objectIdType() },
52
57
  roles: RoleEnum.S_EVERYONE,
53
58
  type: () => String,
54
59
  })
@@ -96,13 +101,13 @@ export class User extends CoreUserModel implements PersistenceModel {
96
101
  @UnifiedField({
97
102
  description: 'ID of the user who last updated the object',
98
103
  isOptional: true,
99
- mongoose: { ref: 'User', type: Schema.Types.ObjectId },
104
+ mongoose: { ref: 'User', type: objectIdType() },
100
105
  roles: RoleEnum.S_USER,
101
106
  type: () => String,
102
107
  })
103
108
  updatedBy: string = undefined;
104
109
 
105
- @Prop({ default: {}, type: Schema.Types.Mixed })
110
+ @Prop({ default: {}, type: Object })
106
111
  @Restricted(RoleEnum.S_EVERYONE)
107
112
  _translations?: Record<string, Partial<User>> = undefined;
108
113
 
@@ -1,7 +1,7 @@
1
1
  import { forwardRef, Module } from '@nestjs/common';
2
- import { MongooseModule } from '@nestjs/mongoose';
3
2
  import { PubSub } from 'graphql-subscriptions';
4
3
 
4
+ import { CorePersistenceModule } from '../../../core/common/persistence/core-persistence.module.js';
5
5
  import { ConfigService } from '../../../core/common/services/config.service.js';
6
6
  import { CoreRedisPubSub } from '../../../core/common/services/core-redis-pubsub.js';
7
7
  import { CoreRedisService } from '../../../core/common/services/core-redis.service.js';
@@ -12,15 +12,21 @@ import { User, UserSchema } from './user.model.js';
12
12
  import { UserResolver } from './user.resolver.js';
13
13
  import { UserService } from './user.service.js';
14
14
 
15
+ /**
16
+ * The user model, registered database-neutrally: `@InjectModel()` keeps working, and `database` in the configuration
17
+ * decides whether users are stored in MongoDB or a SQL database (`CorePersistenceModule`)
18
+ */
19
+ const UserPersistence = CorePersistenceModule.forFeature([{ model: User, name: User.name, schema: UserSchema }]);
20
+
15
21
  /**
16
22
  * User module
17
23
  */
18
24
  @Module({
19
25
  controllers: [AvatarController, UserController],
20
- exports: [MongooseModule, UserResolver, UserService, 'USER_CLASS'],
26
+ exports: [UserPersistence, UserResolver, UserService, 'USER_CLASS'],
21
27
  // forwardRef: FileModule already imports UserModule, and the avatar upload now
22
28
  // needs FileService to reach the central storage — so the two reference each other.
23
- imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]), forwardRef(() => FileModule)],
29
+ imports: [UserPersistence, forwardRef(() => FileModule)],
24
30
  providers: [
25
31
  UserResolver,
26
32
  ConfigService,