@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
@@ -0,0 +1,191 @@
1
+ import { getAuthTables } from 'better-auth/db';
2
+ import { getMigrations } from 'better-auth/db/migration';
3
+
4
+ import { DataSourceConfigError } from '../../common/persistence/data-source.config.js';
5
+ import { generateId } from '../../common/persistence/id-format.js';
6
+ import { type IamSqlStorage, registerForeignColumns } from '../../common/persistence/persistence-runtime.registry.js';
7
+ import { columnName, quoteIdentifier } from '../../common/persistence/sql/sql-naming.js';
8
+
9
+ /** The table Better-Auth shares with the user model — created and owned by the framework */
10
+ const USERS_TABLE = 'users';
11
+
12
+ /**
13
+ * Better-Auth's own fields of the user row that the user model does not declare. Their columns are Better-Auth's, not
14
+ * left-overs of a removed field: the framework's schema evolution must not report them at every boot.
15
+ */
16
+ registerForeignColumns(USERS_TABLE, ['email_verified', 'image', 'name']);
17
+
18
+ /** Postgres column type of a Better-Auth field, for a column the framework adds before Better-Auth's migration */
19
+ const SQL_TYPES: Record<string, string> = {
20
+ boolean: 'boolean',
21
+ date: 'timestamptz',
22
+ json: 'jsonb',
23
+ number: 'integer',
24
+ 'number[]': 'jsonb',
25
+ string: 'text',
26
+ 'string[]': 'jsonb',
27
+ };
28
+
29
+ /** The tables Better-Auth's own options name (models of plugins come from the plugins) */
30
+ const CORE_MODELS = ['user', 'session', 'account', 'verification'] as const;
31
+
32
+ type Options = Record<string, any>;
33
+
34
+ /**
35
+ * Better-Auth on a SQL data source: its built-in Kysely adapter on the given `pg` pool (Better-Auth recognises the
36
+ * pool and builds its own Kysely instance — the core imports no Kysely), ids in the framework's format, and every table
37
+ * and column named the way the framework names it.
38
+ *
39
+ * Naming is not cosmetic. Better-Auth and the user model share ONE row per user in `users`: the framework creates that
40
+ * table from the user model, its column for a field is `columnName(field)` (`firstName` → `first_name`), and Better-Auth
41
+ * must address exactly those columns — a second, camelCase `firstName` column would split one value in two. Applying the
42
+ * same rule to every name Better-Auth uses (the stored name it has on MongoDB, snake-cased) covers the user model's
43
+ * fields, Better-Auth's own tables and every plugin's tables, the project's plugins included, with no list to maintain.
44
+ * On MongoDB nothing of this applies: the stored names stay exactly as they are.
45
+ *
46
+ * Plugins are copied, never changed: a plugin object a project passes may also serve an instance on MongoDB in the same
47
+ * process, which must keep its names.
48
+ */
49
+ export function withSqlStorage(options: Options, pool: unknown): Options {
50
+ const sqlOptions: Options = {
51
+ ...options,
52
+ advanced: {
53
+ ...options.advanced,
54
+ // ObjectId-hex, generated in the application: the id the framework gives every other row, so a user created by
55
+ // Better-Auth and one created through the user service are indistinguishable (plan §3.5)
56
+ database: { ...options.advanced?.database, generateId: () => generateId() },
57
+ },
58
+ database: pool,
59
+ plugins: (options.plugins ?? []).map((plugin: Options) =>
60
+ plugin?.schema ? { ...plugin, schema: snakeCaseSchema(plugin.schema) } : plugin,
61
+ ),
62
+ };
63
+ const tables = getAuthTables(sqlOptions as any) as Record<
64
+ string,
65
+ { fields: Record<string, Options>; modelName: string }
66
+ >;
67
+ for (const model of CORE_MODELS) {
68
+ const own = (sqlOptions[model] ?? {}) as Options;
69
+ const fields: Record<string, string> = {};
70
+ for (const [key, field] of Object.entries(tables[model]?.fields ?? {})) {
71
+ fields[key] = columnName(field.fieldName ?? key);
72
+ }
73
+ sqlOptions[model] = {
74
+ ...own,
75
+ additionalFields: own.additionalFields ? snakeCaseFields(own.additionalFields) : undefined,
76
+ fields,
77
+ modelName: columnName(own.modelName ?? tables[model]?.modelName ?? model),
78
+ };
79
+ }
80
+ return sqlOptions;
81
+ }
82
+
83
+ /** A plugin's schema with its tables and columns named like the framework's */
84
+ function snakeCaseSchema(schema: Record<string, Options>): Record<string, Options> {
85
+ return Object.fromEntries(
86
+ Object.entries(schema).map(([key, table]) => [
87
+ key,
88
+ {
89
+ ...table,
90
+ fields: snakeCaseFields(table.fields ?? {}),
91
+ // A plugin's entry for a core table only adds fields; the table's name is Better-Auth's own option
92
+ ...((CORE_MODELS as readonly string[]).includes(key) ? {} : { modelName: columnName(table.modelName ?? key) }),
93
+ },
94
+ ]),
95
+ );
96
+ }
97
+
98
+ function snakeCaseFields(fields: Record<string, Options>): Record<string, Options> {
99
+ return Object.fromEntries(
100
+ Object.entries(fields).map(([key, field]) => [key, { ...field, fieldName: columnName(field.fieldName ?? key) }]),
101
+ );
102
+ }
103
+
104
+ /** The tables Better-Auth's options declare that Better-Auth owns: all of them but the shared `users` table */
105
+ export function betterAuthOwnedTables(options: Options): string[] {
106
+ const tables = getAuthTables(options as any) as Record<string, { modelName: string }>;
107
+ return [...new Set(Object.values(tables).map((table) => table.modelName))].filter((name) => name !== USERS_TABLE);
108
+ }
109
+
110
+ /**
111
+ * Bring Better-Auth's tables up to date before the instance exists (it validates its schema as it starts): Better-Auth's
112
+ * own migrator, run as the owner under the framework's schema lock. It only creates tables and adds columns — on `users`
113
+ * the ones the user model does not declare (`name`, `email_verified`, `image`); it never drops or alters a column.
114
+ * Without an owner connection it only checks, and a pending change stops the boot like a framework table would.
115
+ */
116
+ export async function applyBetterAuthSchema(options: Options, storage: IamSqlStorage): Promise<void> {
117
+ await storage.applySchema(async (pool, asOwner) => {
118
+ const nullable = asOwner ? await addRequiredUserColumnsAsNullable(options, pool as PgPool) : new Set<string>();
119
+ const { runMigrations, toBeAdded, toBeCreated } = await getMigrations({
120
+ ...options,
121
+ database: pool,
122
+ logger: withoutNullabilityWarnings(options.logger, nullable),
123
+ } as any);
124
+ if (asOwner) {
125
+ await runMigrations();
126
+ return;
127
+ }
128
+ const pending = [...toBeCreated, ...toBeAdded].map((change: { table: string }) => change.table);
129
+ if (pending.length) {
130
+ throw new DataSourceConfigError(
131
+ `Better-Auth's tables in "${storage.source}" are not up to date (${[...new Set(pending)].join(', ')}), and ` +
132
+ 'without database.ownerUrl the application role may only verify them — configure the owner, or migrate them',
133
+ );
134
+ }
135
+ }, betterAuthOwnedTables(options));
136
+ }
137
+
138
+ interface PgPool {
139
+ query(text: string, params?: unknown[]): Promise<{ rows: any[] }>;
140
+ }
141
+
142
+ /**
143
+ * A field Better-Auth declares required without a default (`name`) becomes a NOT NULL column when Better-Auth adds it —
144
+ * and every user the FRAMEWORK creates (legacy sign-up, user service, system setup) would then fail to insert, because the
145
+ * user model knows nothing of it. On MongoDB such a user simply has no `name`. So the framework adds these columns
146
+ * first, nullable like every column it creates (the database does not enforce `required`, as on MongoDB); Better-Auth
147
+ * then finds them and adds nothing. Returns every required user column that is nullable by the framework's design.
148
+ */
149
+ async function addRequiredUserColumnsAsNullable(options: Options, pool: PgPool): Promise<Set<string>> {
150
+ const users = (getAuthTables(options as any) as Record<string, any>).user;
151
+ const { rows } = await pool.query(
152
+ 'SELECT column_name FROM information_schema.columns WHERE table_schema = current_schema() AND table_name = $1',
153
+ [users.modelName],
154
+ );
155
+ const existing = new Set(rows.map((row) => row.column_name as string));
156
+ const nullable = new Set<string>();
157
+ for (const [key, field] of Object.entries(users.fields as Record<string, any>)) {
158
+ const column = field.fieldName ?? key;
159
+ if (field.required === false) {
160
+ continue;
161
+ }
162
+ // Every column the framework created for a field is nullable — the user model's `email` and timestamps included
163
+ nullable.add(column);
164
+ if (field.defaultValue === undefined && !existing.has(column) && SQL_TYPES[field.type]) {
165
+ await pool.query(
166
+ `ALTER TABLE ${quoteIdentifier(users.modelName)} ADD COLUMN IF NOT EXISTS ${quoteIdentifier(column)} ${SQL_TYPES[field.type]}`,
167
+ );
168
+ }
169
+ }
170
+ return nullable;
171
+ }
172
+
173
+ /**
174
+ * Better-Auth's logger, minus the warning that a required user column is nullable — for the columns the framework made
175
+ * nullable on purpose; every other message (a type mismatch, an unsafe change) is still reported
176
+ */
177
+ function withoutNullabilityWarnings(logger: Options | undefined, columns: Set<string>): Options | undefined {
178
+ if (!columns.size || typeof logger?.log !== 'function') {
179
+ return logger;
180
+ }
181
+ return {
182
+ ...logger,
183
+ log: (level: string, message: string, ...args: unknown[]) => {
184
+ const column = /^Column "([^"]+)" on table "users" stays nullable/.exec(String(message))?.[1];
185
+ if (level === 'warn' && column && columns.has(column)) {
186
+ return;
187
+ }
188
+ logger.log(level, message, ...args);
189
+ },
190
+ };
191
+ }
@@ -1,8 +1,10 @@
1
1
  import { Injectable, Logger, Optional } from '@nestjs/common';
2
- import { InjectConnection } from '@nestjs/mongoose';
3
- import { type Connection, Types } from 'mongoose';
2
+ import { InjectConnection } from '../../common/persistence/mongo/mongoose-compat.js';
3
+ import type { Connection } from 'mongoose';
4
4
 
5
5
  import { BetterAuthenticatedUser } from './better-auth.types.js';
6
+ import { BetterAuthMongoUsers, type IamUserLookup } from './core-better-auth-mongo.users.js';
7
+ import { getBetterAuthSqlStore } from './core-better-auth-sql.registry.js';
6
8
  import { CoreBetterAuthService } from './core-better-auth.service.js';
7
9
 
8
10
  /**
@@ -95,7 +97,7 @@ export class BetterAuthTokenService {
95
97
  * @returns User object with hasRole method, or null if verification fails
96
98
  */
97
99
  async verifyAndLoadUser(token: string): Promise<BetterAuthenticatedUser | null> {
98
- if (!this.betterAuthService || !this.connection) {
100
+ if (!this.betterAuthService || !this.users()) {
99
101
  return null;
100
102
  }
101
103
 
@@ -152,10 +154,19 @@ export class BetterAuthTokenService {
152
154
  }
153
155
  return roles.some((role) => userRoles.includes(role));
154
156
  },
155
- id: (user._id as Types.ObjectId)?.toString() || (user.id as string),
157
+ // The row's id as a string, whatever the database: MongoDB's `_id`, the column `id` on SQL
158
+ id: user._id?.toString() || (user.id as string),
156
159
  } as BetterAuthenticatedUser;
157
160
  }
158
161
 
162
+ /**
163
+ * Where the app user is looked up: the SQL store when Better-Auth runs on SQL, MongoDB otherwise. Ids stay strings
164
+ * here — only the MongoDB lookup knows what an ObjectId is.
165
+ */
166
+ protected users(): IamUserLookup | undefined {
167
+ return getBetterAuthSqlStore() ?? (this.connection ? new BetterAuthMongoUsers(this.connection) : undefined);
168
+ }
169
+
159
170
  /**
160
171
  * Loads a user from JWT payload using direct MongoDB query.
161
172
  *
@@ -166,23 +177,14 @@ export class BetterAuthTokenService {
166
177
  [key: string]: unknown;
167
178
  sub: string;
168
179
  }): Promise<BetterAuthenticatedUser | null> {
169
- if (!this.connection) {
180
+ const users = this.users();
181
+ if (!users) {
170
182
  return null;
171
183
  }
172
184
 
173
185
  try {
174
- const usersCollection = this.connection.collection('users');
175
- let user: null | Record<string, unknown> = null;
176
-
177
- // Try to find by MongoDB _id first
178
- if (Types.ObjectId.isValid(payload.sub)) {
179
- user = await usersCollection.findOne({ _id: new Types.ObjectId(payload.sub) });
180
- }
181
-
182
- // If not found, try by iamId
183
- if (!user) {
184
- user = await usersCollection.findOne({ iamId: payload.sub });
185
- }
186
+ // By the row's id first, then by iamId
187
+ const user = (await users.findUser({ id: payload.sub })) ?? (await users.findUser({ iamId: payload.sub }));
186
188
 
187
189
  if (!user) {
188
190
  return null;
@@ -207,28 +209,17 @@ export class BetterAuthTokenService {
207
209
  email?: string;
208
210
  id?: string;
209
211
  }): Promise<BetterAuthenticatedUser | null> {
210
- if (!this.connection || !sessionUser) {
212
+ const users = this.users();
213
+ if (!users || !sessionUser) {
211
214
  return null;
212
215
  }
213
216
 
214
217
  try {
215
- const usersCollection = this.connection.collection('users');
216
- let user: null | Record<string, unknown> = null;
217
-
218
- // Try to find by email (most reliable)
219
- if (sessionUser.email) {
220
- user = await usersCollection.findOne({ email: sessionUser.email });
221
- }
222
-
223
- // If not found by email, try by iamId
224
- if (!user && sessionUser.id) {
225
- user = await usersCollection.findOne({ iamId: sessionUser.id });
226
- }
227
-
228
- // If still not found, try by _id (if the ID looks like a MongoDB ObjectId)
229
- if (!user && sessionUser.id && Types.ObjectId.isValid(sessionUser.id)) {
230
- user = await usersCollection.findOne({ _id: new Types.ObjectId(sessionUser.id) });
231
- }
218
+ // By email (most reliable), then by iamId, then by the row's id
219
+ const user =
220
+ (await users.findUser({ email: sessionUser.email })) ??
221
+ (await users.findUser({ iamId: sessionUser.id })) ??
222
+ (await users.findUser({ id: sessionUser.id }));
232
223
 
233
224
  if (!user) {
234
225
  return null;
@@ -1,7 +1,6 @@
1
1
  import { passkey } from '@better-auth/passkey';
2
2
  import { Logger } from '@nestjs/common';
3
3
  import { betterAuth, BetterAuthPlugin } from 'better-auth';
4
- import { mongodbAdapter } from 'better-auth/adapters/mongodb';
5
4
  import { jwt, openAPI, twoFactor } from 'better-auth/plugins';
6
5
  import * as crypto from 'crypto';
7
6
  import * as fs from 'fs';
@@ -13,7 +12,9 @@ import { revalidateWsConnectionsOf } from '../../common/helpers/graphql-ws-conne
13
12
  import { IBetterAuth, ICorsConfig } from '../../common/interfaces/server-options.interface.js';
14
13
  import { ConfigService } from '../../common/services/config.service.js';
15
14
  import { detectCookiePrefixDrift, resolveBetterAuthCookiePrefix } from './better-auth-cookie-prefix.helper.js';
15
+ import { withSqlStorage } from './better-auth-sql.helper.js';
16
16
  import { projectProvidesOpenApiPlugin } from './core-better-auth-openapi.helper.js';
17
+ import { requireBetterAuthMongoAdapter } from '../../common/persistence/mongo/mongo-packages.js';
17
18
 
18
19
  /**
19
20
  * Type for better-auth instance with plugins
@@ -155,7 +156,7 @@ export interface CreateBetterAuthOptions {
155
156
  * MongoDB database instance
156
157
  * Note: Uses 'any' type to handle version incompatibilities between
157
158
  * mongoose's bundled mongodb types and the project's mongodb package.
158
- * At runtime, this is a mongodb.Db instance.
159
+ * At runtime, this is a mongodb.Db instance. Unused when `sqlPool` is set.
159
160
  */
160
161
  db: any;
161
162
 
@@ -230,6 +231,13 @@ export interface CreateBetterAuthOptions {
230
231
  * Used for local environment defaults.
231
232
  */
232
233
  serverEnv?: string;
234
+
235
+ /**
236
+ * The `pg` pool of the SQL data source the `users` table lives in (the application role's pool of the configured
237
+ * engine). Set, Better-Auth runs its built-in Kysely adapter on it instead of MongoDB, with the framework's ids and
238
+ * table and column names — see `withSqlStorage()`.
239
+ */
240
+ sqlPool?: unknown;
233
241
  }
234
242
 
235
243
  /**
@@ -480,7 +488,31 @@ export interface CreateBetterAuthResult {
480
488
  instance: BetterAuthInstance;
481
489
  }
482
490
 
491
+ /** The options `createBetterAuthInstance()` builds, before Better-Auth is constructed from them */
492
+ export interface BetterAuthOptionsResult {
493
+ /** Resolved cookie domain for cross-subdomain cookies, or undefined if disabled */
494
+ cookieDomain: string | undefined;
495
+ /** What `betterAuth()` receives */
496
+ options: Record<string, unknown>;
497
+ }
498
+
483
499
  export function createBetterAuthInstance(options: CreateBetterAuthOptions): CreateBetterAuthResult | null {
500
+ const built = buildBetterAuthOptions(options);
501
+ return built ? instantiateBetterAuth(built) : null;
502
+ }
503
+
504
+ /** Construct Better-Auth from built options — a separate step so a SQL schema can be brought up to date in between */
505
+ export function instantiateBetterAuth(built: BetterAuthOptionsResult): CreateBetterAuthResult {
506
+ // Type assertion needed for maximum flexibility - allows projects to use any Better-Auth option
507
+ return { cookieDomain: built.cookieDomain, instance: betterAuth(built.options as any) };
508
+ }
509
+
510
+ /**
511
+ * Better-Auth's options as `createBetterAuthInstance()` builds them, without constructing Better-Auth: on a SQL data
512
+ * source its tables must exist before the instance does, because Better-Auth validates its schema as it starts and
513
+ * reports every missing table as an error.
514
+ */
515
+ export function buildBetterAuthOptions(options: CreateBetterAuthOptions): BetterAuthOptionsResult | null {
484
516
  const {
485
517
  config,
486
518
  db,
@@ -490,6 +522,7 @@ export function createBetterAuthInstance(options: CreateBetterAuthOptions): Crea
490
522
  sendResetPasswordEmail,
491
523
  sendVerificationEmail,
492
524
  serverEnv,
525
+ sqlPool,
493
526
  } = options;
494
527
 
495
528
  // Return null only if better-auth is explicitly disabled
@@ -615,7 +648,7 @@ export function createBetterAuthInstance(options: CreateBetterAuthOptions): Crea
615
648
  },
616
649
  basePath,
617
650
  baseURL: betterAuthBaseUrl,
618
- database: mongodbAdapter(db),
651
+ database: sqlPool ? undefined : (requireBetterAuthMongoAdapter()(db) as any),
619
652
  // Enable email/password authentication by default (required by Better-Auth 1.x)
620
653
  // Can be disabled by setting config.emailAndPassword.enabled = false
621
654
  emailAndPassword: {
@@ -810,12 +843,14 @@ export function createBetterAuthInstance(options: CreateBetterAuthOptions): Crea
810
843
  finalConfig = betterAuthConfig;
811
844
  }
812
845
 
813
- // Create and return the better-auth instance with resolved metadata
814
- // Type assertion needed for maximum flexibility - allows projects to use any Better-Auth option
846
+ // On SQL the storage is applied last, so the naming also covers fields and plugins `config.options` added
847
+ if (sqlPool) {
848
+ finalConfig = withSqlStorage(finalConfig, sqlPool);
849
+ }
815
850
 
816
851
  return {
817
852
  cookieDomain: crossSubDomain.enabled ? crossSubDomain.domain : undefined,
818
- instance: betterAuth(finalConfig as any),
853
+ options: finalConfig,
819
854
  };
820
855
  }
821
856
 
@@ -1037,7 +1072,8 @@ function buildPlugins(
1037
1072
  passkeyOptions.userVerification = normalizedPasskey.userVerification;
1038
1073
  }
1039
1074
  if (normalizedPasskey.webAuthnChallengeCookie) {
1040
- passkeyOptions.webAuthnChallengeCookie = normalizedPasskey.webAuthnChallengeCookie;
1075
+ // The plugin reads the name from `advanced`; a top-level option is ignored
1076
+ passkeyOptions.advanced = { webAuthnChallengeCookie: normalizedPasskey.webAuthnChallengeCookie };
1041
1077
  }
1042
1078
 
1043
1079
  plugins.push(passkey(passkeyOptions));
@@ -5,7 +5,7 @@
5
5
  * and reduce the need for `as any` casts throughout the codebase.
6
6
  */
7
7
 
8
- import { Types } from 'mongoose';
8
+ import type { Types } from 'mongoose';
9
9
 
10
10
  import { BetterAuthSessionUser } from './core-better-auth-user.mapper.js';
11
11
 
@@ -243,6 +243,17 @@ export class CoreBetterAuthApiMiddleware implements NestMiddleware {
243
243
  return this.cookieHelper;
244
244
  }
245
245
 
246
+ /**
247
+ * The passkey challenge cookie as Better-Auth names it: the configured key under the instance's cookie prefix
248
+ * (`iam.better-auth-passkey` by default). Asked from Better-Auth itself, so the prefix the session cookie follows
249
+ * (`COOKIE_PREFIX`, the base path) applies here too.
250
+ */
251
+ protected async passkeyChallengeCookieName(authInstance: unknown): Promise<string> {
252
+ const key = this.challengeService?.getCookieName() || 'better-auth-passkey';
253
+ const context = await (authInstance as { $context?: Promise<any> }).$context;
254
+ return context?.createAuthCookie?.(key)?.name ?? key;
255
+ }
256
+
246
257
  /**
247
258
  * Check if database challenge storage should be used.
248
259
  * This is checked dynamically because the ChallengeService initializes in onModuleInit.
@@ -312,7 +323,8 @@ export class CoreBetterAuthApiMiddleware implements NestMiddleware {
312
323
 
313
324
  // Get config for cookie signing
314
325
  const config = this.betterAuthService.getConfig();
315
- const cookieName = this.challengeService?.getCookieName() || 'better-auth.better-auth-passkey';
326
+ const cookieName =
327
+ isPasskeyGenerate || isPasskeyVerify ? await this.passkeyChallengeCookieName(authInstance) : '';
316
328
 
317
329
  // For passkey verify requests with DB storage, inject the verificationToken as a cookie
318
330
  let challengeIdToDelete: string | undefined;
@@ -1,11 +1,12 @@
1
1
  import { Injectable, Logger, OnModuleInit, Optional } from '@nestjs/common';
2
- import { InjectConnection } from '@nestjs/mongoose';
2
+ import { InjectConnection } from '../../common/persistence/mongo/mongoose-compat.js';
3
3
  import * as crypto from 'crypto';
4
- import { Collection, Document } from 'mongodb';
4
+ import type { Collection, Document } from 'mongodb';
5
5
  import type { Connection } from 'mongoose';
6
6
 
7
7
  import { IBetterAuth } from '../../common/interfaces/server-options.interface.js';
8
8
  import { ConfigService } from '../../common/services/config.service.js';
9
+ import { getBetterAuthSqlStore } from './core-better-auth-sql.registry.js';
9
10
 
10
11
  /**
11
12
  * WebAuthn challenge mapping document structure.
@@ -104,8 +105,8 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
104
105
 
105
106
  try {
106
107
  if (!this.connection) {
107
- this.logger.warn('MongoDB connection not available, challenge storage disabled');
108
- this.enabled = false;
108
+ // No MongoDB (PostgreSQL alone): the mappings are Better-Auth verification values on the SQL source, reached per
109
+ // call through getBetterAuthSqlStore() — isEnabled() answers from it
109
110
  return;
110
111
  }
111
112
 
@@ -138,7 +139,7 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
138
139
  * Check if database challenge storage is enabled
139
140
  */
140
141
  isEnabled(): boolean {
141
- return this.enabled && this.collection !== null;
142
+ return this.enabled && (this.collection !== null || !!getBetterAuthSqlStore());
142
143
  }
143
144
 
144
145
  /**
@@ -154,7 +155,8 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
154
155
  userId: string,
155
156
  type: 'authentication' | 'registration',
156
157
  ): Promise<string> {
157
- if (!this.collection) {
158
+ const sql = getBetterAuthSqlStore();
159
+ if (!this.collection && !sql) {
158
160
  throw new Error('Challenge storage not initialized');
159
161
  }
160
162
 
@@ -164,6 +166,13 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
164
166
  const now = new Date();
165
167
  const expiresAt = new Date(now.getTime() + this.ttlSeconds * 1000);
166
168
 
169
+ if (sql) {
170
+ // On SQL as one of Better-Auth's verification values: short-lived, with an expiry, never sent to the client
171
+ await sql.storeChallenge(challengeId, { expiresAt, type, userId, verificationToken });
172
+ this.logger.debug(`Stored ${type} challenge mapping for user ${userId.substring(0, 8)}...`);
173
+ return challengeId;
174
+ }
175
+
167
176
  await this.collection.insertOne({
168
177
  challengeId,
169
178
  createdAt: now,
@@ -185,11 +194,12 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
185
194
  * @returns The verificationToken or null if not found/expired
186
195
  */
187
196
  async getVerificationToken(challengeId: string): Promise<null | string> {
188
- if (!this.collection) {
197
+ const sql = getBetterAuthSqlStore();
198
+ if (!this.collection && !sql) {
189
199
  return null;
190
200
  }
191
201
 
192
- const doc = await this.collection.findOne({ challengeId });
202
+ const doc = sql ? await sql.findChallenge(challengeId) : await this.collection.findOne({ challengeId });
193
203
 
194
204
  if (!doc) {
195
205
  this.logger.debug(`Challenge mapping not found: ${challengeId.substring(0, 8)}...`);
@@ -211,11 +221,14 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
211
221
  * @param challengeId - The challenge ID to delete
212
222
  */
213
223
  async deleteChallengeMapping(challengeId: string): Promise<void> {
214
- if (!this.collection) {
224
+ const sql = getBetterAuthSqlStore();
225
+ if (sql) {
226
+ await sql.deleteChallenge(challengeId);
227
+ } else if (!this.collection) {
215
228
  return;
229
+ } else {
230
+ await this.collection.deleteOne({ challengeId });
216
231
  }
217
-
218
- await this.collection.deleteOne({ challengeId });
219
232
  this.logger.debug(`Deleted challenge mapping: ${challengeId.substring(0, 8)}...`);
220
233
  }
221
234
 
@@ -225,13 +238,16 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
225
238
  * @param userId - User ID whose challenge mappings should be deleted
226
239
  */
227
240
  async deleteUserChallengeMappings(userId: string): Promise<void> {
228
- if (!this.collection) {
241
+ const sql = getBetterAuthSqlStore();
242
+ if (!this.collection && !sql) {
229
243
  return;
230
244
  }
231
245
 
232
- const result = await this.collection.deleteMany({ userId });
233
- if (result.deletedCount > 0) {
234
- this.logger.debug(`Deleted ${result.deletedCount} challenge mappings for user ${userId.substring(0, 8)}...`);
246
+ const deletedCount = sql
247
+ ? await sql.deleteUserChallenges(userId)
248
+ : (await this.collection.deleteMany({ userId })).deletedCount;
249
+ if (deletedCount > 0) {
250
+ this.logger.debug(`Deleted ${deletedCount} challenge mappings for user ${userId.substring(0, 8)}...`);
235
251
  }
236
252
  }
237
253
 
@@ -243,14 +259,16 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
243
259
  }
244
260
 
245
261
  /**
246
- * Get the cookie name used by Better Auth for passkey challenges
262
+ * The key of Better-Auth's passkey challenge cookie (`passkey.webAuthnChallengeCookie`, default
263
+ * `better-auth-passkey`). Better-Auth puts its cookie prefix in front of it — the full name is
264
+ * `createAuthCookie(<key>).name` of the instance, as `CoreBetterAuthApiMiddleware` resolves it.
247
265
  */
248
266
  getCookieName(): string {
249
267
  if (!this.configService) {
250
- return 'better-auth.better-auth-passkey';
268
+ return 'better-auth-passkey';
251
269
  }
252
270
  const config = this.configService.get<IBetterAuth>('betterAuth') || {};
253
271
  const passkeyConfig = typeof config.passkey === 'object' ? config.passkey : null;
254
- return passkeyConfig?.webAuthnChallengeCookie || 'better-auth.better-auth-passkey';
272
+ return passkeyConfig?.webAuthnChallengeCookie || 'better-auth-passkey';
255
273
  }
256
274
  }
@@ -0,0 +1,35 @@
1
+ import type { Connection } from 'mongoose';
2
+
3
+ import type { IamUserMatch } from './core-better-auth-sql.store.js';
4
+ import { isValidObjectId, newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
5
+
6
+ /** One way to look the app user up on the per-request auth path — by one key at a time */
7
+ export interface IamUserLookup {
8
+ findUser(match: IamUserMatch): Promise<null | Record<string, unknown>>;
9
+ }
10
+
11
+ /**
12
+ * The app user on MongoDB for the per-request auth path (token service). The one place on that path that knows a
13
+ * MongoDB id is an ObjectId: the services ask by string, and only this class turns an id into a `_id` filter — a
14
+ * string that is no ObjectId finds nobody, as before. On a SQL source `BetterAuthSqlStore` answers instead.
15
+ */
16
+ export class BetterAuthMongoUsers implements IamUserLookup {
17
+ constructor(protected readonly connection: Connection) {}
18
+
19
+ async findUser(match: IamUserMatch): Promise<null | Record<string, unknown>> {
20
+ const or: Record<string, unknown>[] = [];
21
+ if (match.email) {
22
+ or.push({ email: match.email });
23
+ }
24
+ if (match.iamId) {
25
+ or.push({ iamId: match.iamId });
26
+ }
27
+ if (match.id && isValidObjectId(match.id)) {
28
+ or.push({ _id: newObjectId(match.id) });
29
+ }
30
+ if (!or.length) {
31
+ return null;
32
+ }
33
+ return this.connection.collection('users').findOne(or.length === 1 ? or[0] : { $or: or });
34
+ }
35
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The SQL store of Better-Auth's data while Better-Auth runs on a SQL source — `undefined` on MongoDB. Set by
3
+ * `CoreBetterAuthModule` when it creates the instance (every creation sets it, so an application on MongoDB booted
4
+ * after one on SQL in the same process reads `undefined`), read by the user mapper, the token and challenge services,
5
+ * the system setup and the API token service at call time.
6
+ *
7
+ * `import type` only — an import-free leaf, so none of those files imports the module (see
8
+ * `.claude/rules/better-auth.md` §6).
9
+ */
10
+ import type { BetterAuthSqlStore } from './core-better-auth-sql.store.js';
11
+
12
+ let store: BetterAuthSqlStore | undefined;
13
+
14
+ export function setBetterAuthSqlStore(value: BetterAuthSqlStore | undefined): void {
15
+ store = value;
16
+ }
17
+
18
+ export function getBetterAuthSqlStore(): BetterAuthSqlStore | undefined {
19
+ return store;
20
+ }