@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,12 +3,12 @@ import { Type } from '@nestjs/common';
3
3
  import { GqlModuleAsyncOptions } from '@nestjs/graphql';
4
4
  import { JwtModuleOptions } from '@nestjs/jwt';
5
5
  import type { JwtSignOptions } from '@nestjs/jwt';
6
- import { MongooseModuleOptions } from '@nestjs/mongoose';
6
+ import type { MongooseModuleOptions } from '@nestjs/mongoose';
7
7
  import { ServeStaticOptions } from '@nestjs/platform-express/interfaces/serve-static-options.interface';
8
8
  import { CronExpression } from '@nestjs/schedule';
9
9
  import type { DiskHealthIndicatorOptions, MongoosePingCheckSettings } from '@nestjs/terminus';
10
10
  import compression from 'compression';
11
- import { CollationOptions } from 'mongodb';
11
+ import type { CollationOptions } from 'mongodb';
12
12
  import type { Connection } from 'mongoose';
13
13
  import type * as JSONTransport from 'nodemailer/lib/json-transport';
14
14
  import type * as SendmailTransport from 'nodemailer/lib/sendmail-transport';
@@ -17,6 +17,7 @@ import type * as SMTPPool from 'nodemailer/lib/smtp-pool';
17
17
  import * as SMTPTransport from 'nodemailer/lib/smtp-transport';
18
18
  import type * as StreamTransport from 'nodemailer/lib/stream-transport';
19
19
 
20
+ import type { DataStore } from '../persistence/data-store.interface.js';
20
21
  import { Falsy } from '../types/falsy.type.js';
21
22
  import { IHubConfig } from '../../modules/hub/interfaces/hub-config.interface.js';
22
23
  import { IPermissions } from '../../modules/permissions/interfaces/permissions.interface.js';
@@ -799,8 +800,9 @@ export interface IBetterAuthPasskeyConfig {
799
800
  userVerification?: 'discouraged' | 'preferred' | 'required';
800
801
 
801
802
  /**
802
- * Custom cookie name for WebAuthn challenge storage.
803
- * Only used when challengeStorage is 'cookie'.
803
+ * Key of Better-Auth's WebAuthn challenge cookie. Better-Auth puts its cookie prefix in front of it
804
+ * (`iam.better-auth-passkey` by default); with database challenge storage the server reads the token from that
805
+ * cookie and maps it to the `challengeId` it returns instead.
804
806
  * @default 'better-auth-passkey'
805
807
  */
806
808
  webAuthnChallengeCookie?: string;
@@ -1262,8 +1264,10 @@ export interface IFileConfig {
1262
1264
  *
1263
1265
  * **Left unset, it is derived**, most capable first:
1264
1266
  * 1. `'s3'` when `s3.bucket` is configured
1265
- * 2. `'gridfs'` when a database is configured
1266
- * 3. `'filesystem'` when neither is
1267
+ * 2. `'filesystem'` when `database` routes the file metadata to a SQL source — GridFS would put bytes and
1268
+ * metadata into MongoDB. Pod-local: mount `storageDir` as a volume, or configure `s3`
1269
+ * 3. `'gridfs'` when a database is configured
1270
+ * 4. `'filesystem'` when none is
1267
1271
  *
1268
1272
  * A configured-but-unreachable database is an error in its own right (Mongoose
1269
1273
  * fails the boot), never a reason to fall through to the disk.
@@ -1545,7 +1549,10 @@ export interface IMultiTenancy {
1545
1549
  *
1546
1550
  * Return `false` for an inactive tenant; any other value (including `undefined`) counts as active.
1547
1551
  * `context.connection` is the main database connection, for a lookup in the project's own tenant
1548
- * collection. Answers are cached for {@link cacheTtlMs}; after switching a tenant on or off, call
1552
+ * collection; `context.store(modelName)` is the database-neutral alternative for a tenant model registered with
1553
+ * `CorePersistenceModule.forFeature()`, and the one that works when that model is stored in a SQL database. It
1554
+ * throws for a model not registered that way, so a misnamed or missing tenant model refuses the request rather than
1555
+ * counting every tenant as active. Answers are cached for {@link cacheTtlMs}; after switching a tenant on or off, call
1549
1556
  * `CoreTenantGuard.invalidateTenant(tenantId)` (broadcast to every replica when Redis is
1550
1557
  * configured). A function cannot arrive through `NSC__*` / `NEST_SERVER_CONFIG` — set it in
1551
1558
  * `config.env.ts`.
@@ -1553,15 +1560,30 @@ export interface IMultiTenancy {
1553
1560
  * @example
1554
1561
  * ```typescript
1555
1562
  * multiTenancy: {
1556
- * isTenantActive: async (tenantId, { connection }) =>
1557
- * (await connection.collection('tenants').findOne({ _id: new Types.ObjectId(tenantId) }))?.active !== false,
1563
+ * // Any database: the tenant model registered with CorePersistenceModule.forFeature()
1564
+ * isTenantActive: async (tenantId, { store }) => (await store('Tenant').findById(tenantId))?.active !== false,
1565
+ * // MongoDB only
1566
+ * // isTenantActive: async (tenantId, { connection }) =>
1567
+ * // (await connection.collection('tenants').findOne({ _id: new Types.ObjectId(tenantId) }))?.active !== false,
1558
1568
  * }
1559
1569
  * ```
1560
1570
  *
1561
1571
  * @default undefined (every tenant is active)
1562
1572
  * @since 11.42.0
1563
1573
  */
1564
- isTenantActive?: (tenantId: string, context: { connection: Connection }) => boolean | Promise<boolean>;
1574
+ isTenantActive?: (
1575
+ tenantId: string,
1576
+ context: {
1577
+ connection: Connection;
1578
+ /**
1579
+ * The data store of a model registered with `CorePersistenceModule.forFeature()` — the database-neutral lookup,
1580
+ * also when the tenant model lives in a SQL database (`connection` reaches MongoDB only). Throws a
1581
+ * `DataSourceConfigError` for a model that is not registered that way: an `undefined` here would read as
1582
+ * "active" in a hook written with `?.`, and open every deactivated tenant.
1583
+ */
1584
+ store: (modelName: string) => DataStore<any>;
1585
+ },
1586
+ ) => boolean | Promise<boolean>;
1565
1587
  }
1566
1588
 
1567
1589
  /**
@@ -2151,6 +2173,73 @@ export interface IAi {
2151
2173
  systemPrompt?: string;
2152
2174
  }
2153
2175
 
2176
+ /**
2177
+ * Library that executes the framework's SQL on a SQL data source. The framework compiles every query,
2178
+ * policy and schema change itself, so the engine decides only what projects use for native queries —
2179
+ * switching it on the same database is a configuration change.
2180
+ */
2181
+ export type DatabaseSqlEngine = 'drizzle' | 'kysely' | 'typeorm';
2182
+
2183
+ /**
2184
+ * One data source: a connection URL plus, for SQL databases, the engine.
2185
+ */
2186
+ export interface IDatabaseSourceConfig {
2187
+ /**
2188
+ * Connection URL of the role that OWNS the tables — used only to bring the schema up to date at boot, never for
2189
+ * requests. Only valid on SQL URLs. Without it the application role only verifies the schema and the boot stops
2190
+ * while changes are pending (plan §3.9: the application role owns nothing, so row-level security binds it).
2191
+ */
2192
+ ownerUrl?: string;
2193
+
2194
+ /**
2195
+ * SQL engine for this source. Only valid on SQL URLs.
2196
+ * @default the top-level `sqlEngine`, else 'typeorm'
2197
+ */
2198
+ sqlEngine?: DatabaseSqlEngine;
2199
+
2200
+ /**
2201
+ * Connection URL. The scheme selects the database: `mongodb://`, `mongodb+srv://`, `postgres://`,
2202
+ * `postgresql://`, `mysql://`, `mariadb://`.
2203
+ */
2204
+ url: string;
2205
+ }
2206
+
2207
+ /**
2208
+ * Data sources and which model is stored where.
2209
+ *
2210
+ * One default source serves every model; `sources` adds further ones and `models` lists the exceptions.
2211
+ * A model may also name its source in code with `@PersistedModel({ dataSource })`; the configuration
2212
+ * wins, so operations can move a model without a code change.
2213
+ */
2214
+ export interface IDatabaseConfig {
2215
+ /**
2216
+ * Model name → source name, for the models that do not use the default source.
2217
+ */
2218
+ models?: Record<string, string>;
2219
+
2220
+ /**
2221
+ * Owner connection of the default source (see `IDatabaseSourceConfig.ownerUrl`). Needs `url` beside it: an
2222
+ * `NSC__DATABASE__OWNER_URL` replaces a `database` given as a URL string, so the boot refuses `ownerUrl` alone.
2223
+ */
2224
+ ownerUrl?: string;
2225
+
2226
+ /**
2227
+ * Further sources by name, each a URL or a source configuration. The name `default` is reserved.
2228
+ */
2229
+ sources?: Record<string, IDatabaseSourceConfig | string>;
2230
+
2231
+ /**
2232
+ * SQL engine for every SQL source that does not set its own.
2233
+ * @default 'typeorm'
2234
+ */
2235
+ sqlEngine?: DatabaseSqlEngine;
2236
+
2237
+ /**
2238
+ * URL of the default source. Without it, the `mongoose` configuration stays the default source.
2239
+ */
2240
+ url?: string;
2241
+ }
2242
+
2154
2243
  /**
2155
2244
  * Options for the server
2156
2245
  */
@@ -2497,6 +2586,25 @@ export interface IServerOptions {
2497
2586
  CronExpression | CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset | Date | Falsy | string
2498
2587
  >;
2499
2588
 
2589
+ /**
2590
+ * Data sources: where models are stored.
2591
+ *
2592
+ * - absent: the `mongoose` configuration is the only data source — exactly as before
2593
+ * - a URL (`'postgres://…'`): that database is the default source for every model
2594
+ * - an object: a default source plus further `sources` and per-model exceptions (`models`)
2595
+ * - `false`: no database at all
2596
+ *
2597
+ * When this sets a default source and the project ALSO configures `mongoose` explicitly, that
2598
+ * MongoDB becomes the additional source named `mongoose`. Connection URLs are never logged with
2599
+ * their credentials.
2600
+ *
2601
+ * Which databases this version can actually wire is checked at boot; anything it cannot is refused
2602
+ * with a named error before any connection is attempted.
2603
+ *
2604
+ * @default undefined (the `mongoose` configuration)
2605
+ */
2606
+ database?: false | IDatabaseConfig | string;
2607
+
2500
2608
  /**
2501
2609
  * When true, logs a debug message when prepareInput() changes the input type during process().
2502
2610
  * Enable only for debugging — has performance cost due to JSON.stringify on every process() call.
@@ -1,5 +1,5 @@
1
- import { CollationOptions } from 'mongodb';
2
- import { Model, PopulateOptions } from 'mongoose';
1
+ import type { CollationOptions } from 'mongodb';
2
+ import type { Model, PopulateOptions } from 'mongoose';
3
3
 
4
4
  import { FieldSelection } from '../types/field-selection.type.js';
5
5
  import { PrepareInputOptions } from './prepare-input-options.interface.js';
@@ -1,12 +1,12 @@
1
1
  import { ObjectType } from '@nestjs/graphql';
2
- import { Schema } from '@nestjs/mongoose';
3
- import { Types } from 'mongoose';
2
+ import { Schema } from '../persistence/mongo/mongoose-compat.js';
4
3
 
5
4
  import { Restricted } from '../decorators/restricted.decorator.js';
6
5
  import { UnifiedField } from '../decorators/unified-field.decorator.js';
7
6
  import { RoleEnum } from '../enums/role.enum.js';
8
7
  import { getStringIds } from '../helpers/db.helper.js';
9
8
  import { CoreModel } from './core-model.model.js';
9
+ import { newObjectId } from '../persistence/mongo/mongoose-compat.js';
10
10
 
11
11
  /**
12
12
  * Metadata for persistent objects
@@ -33,7 +33,7 @@ export abstract class CorePersistenceModel extends CoreModel {
33
33
 
34
34
  @Restricted(RoleEnum.S_EVERYONE)
35
35
  get _id() {
36
- return new Types.ObjectId(this.id);
36
+ return newObjectId(this.id);
37
37
  }
38
38
 
39
39
  /**
@@ -0,0 +1,47 @@
1
+ import { Injectable, Logger, OnApplicationBootstrap, OnApplicationShutdown, OnModuleInit } from '@nestjs/common';
2
+
3
+ import { type ExpirySweep, scheduleExpirySweep } from './expiry-sweep.js';
4
+ import { getPersistenceRuntime } from './persistence-runtime.registry.js';
5
+
6
+ /**
7
+ * Opens the framework's lease store, releases the owner connections once the application is up, removes expired rows
8
+ * from SQL tables, and closes the connections of every SQL data source on shutdown. Registered by `CoreModule` only
9
+ * when a SQL source is configured; the sources themselves are opened while Nest creates the stores, so a misconfigured
10
+ * one stops the boot.
11
+ */
12
+ @Injectable()
13
+ export class CorePersistenceLifecycle implements OnApplicationBootstrap, OnApplicationShutdown, OnModuleInit {
14
+ protected readonly logger = new Logger('DataSources');
15
+ protected expirySweep?: ExpirySweep;
16
+
17
+ async onModuleInit(): Promise<void> {
18
+ // The lease table of the default source, while the boot's owner connection is still open — and an unsafe
19
+ // application role stops the boot here even when no model of the default source is registered
20
+ await getPersistenceRuntime()?.defaultLockStore();
21
+ }
22
+
23
+ async onApplicationBootstrap(): Promise<void> {
24
+ const runtime = getPersistenceRuntime();
25
+ // Every store exists by now: providers are created before any bootstrap hook runs
26
+ await runtime?.releaseBootConnections();
27
+ if (runtime) {
28
+ // A model's TTL (`expires`, `index: { expireAfterSeconds }`) is a plain index on SQL — this does the deleting
29
+ this.expirySweep = scheduleExpirySweep(
30
+ 'models',
31
+ async () => {
32
+ for (const { deleted, model } of await runtime.sweepExpired()) {
33
+ if (deleted) {
34
+ this.logger.debug(`Removed ${deleted} expired ${model} record(s)`);
35
+ }
36
+ }
37
+ },
38
+ { logger: this.logger },
39
+ );
40
+ }
41
+ }
42
+
43
+ async onApplicationShutdown(): Promise<void> {
44
+ await this.expirySweep?.stop();
45
+ await getPersistenceRuntime()?.close();
46
+ }
47
+ }
@@ -0,0 +1,109 @@
1
+ import { DynamicModule, Module, Provider } from '@nestjs/common';
2
+ import type { ModelDefinition } from '@nestjs/mongoose';
3
+ import { getConnectionToken, getModelToken } from './mongo/mongoose-compat.js';
4
+ import type { Model } from 'mongoose';
5
+
6
+ import { registerModelSchema } from './model-metadata.registry.js';
7
+ import { MongooseDataStore } from './mongoose-data-store.js';
8
+ import { getPersistedModelOptions, getPersistedModelOptionsByName } from './persisted-model.decorator.js';
9
+ import {
10
+ bindStoreToModel,
11
+ getPersistenceRuntime,
12
+ registerDataStore,
13
+ registerPersistedModel,
14
+ } from './persistence-runtime.registry.js';
15
+ import { getStoreToken } from './persistence.tokens.js';
16
+ import { guardRoutedModel, isStandInModel, standInModel } from './routed-model.guard.js';
17
+ import { unavailableStore } from './unavailable-store.js';
18
+
19
+ /**
20
+ * Database-neutral model registration — the counterpart of `MongooseModule.forFeature()`.
21
+ *
22
+ * Registers the models exactly as `MongooseModule.forFeature()` does (so `@InjectModel()` keeps working),
23
+ * records each model's descriptor, and provides a data store per model for `@InjectStore()`.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * @Module({
28
+ * imports: [CorePersistenceModule.forFeature([{ name: Project.name, schema: ProjectSchema }])],
29
+ * providers: [ProjectService],
30
+ * })
31
+ * export class ProjectModule {}
32
+ * ```
33
+ */
34
+ /** A model definition, plus where it is stored when the configuration does not say */
35
+ export interface PersistenceModelDefinition extends ModelDefinition {
36
+ /** Source name (a key of `database.sources`); the configuration's `database.models` wins */
37
+ dataSource?: string;
38
+ /**
39
+ * The model class — its `@PersistedModel({ dataSource })` is read when `dataSource` is not given. Without it, the
40
+ * `@PersistedModel` class named like the model (`name`) is read
41
+ */
42
+ model?: abstract new (...args: any[]) => any;
43
+ }
44
+
45
+ @Module({})
46
+ export class CorePersistenceModule {
47
+ static forFeature(models: PersistenceModelDefinition[]): DynamicModule {
48
+ for (const model of models) {
49
+ registerModelSchema(model.name, model.schema);
50
+ registerPersistedModel({
51
+ declaredSource:
52
+ model.dataSource ??
53
+ (model.model ? getPersistedModelOptions(model.model) : getPersistedModelOptionsByName(model.name))
54
+ ?.dataSource,
55
+ name: model.name,
56
+ schema: model.schema,
57
+ });
58
+ }
59
+ // The Mongoose models, as `MongooseModule.forFeature()` registers them (`createMongooseProviders()` of
60
+ // @nestjs/mongoose) — but without requiring a connection: where no MongoDB is configured (`NoMongoConnectionModule`,
61
+ // or none at all) the token gets a stand-in that refuses data access, and the model runs on its routed store.
62
+ const mongooseModels: Provider[] = models.flatMap((model) => [
63
+ {
64
+ inject: [{ optional: true, token: getConnectionToken() }],
65
+ provide: getModelToken(model.name),
66
+ useFactory: (connection?: null | { model: Function; models: Record<string, unknown> }) =>
67
+ connection
68
+ ? (connection.models[model.name] ?? connection.model(model.name, model.schema, model.collection))
69
+ : standInModel(model.name, model.schema),
70
+ },
71
+ ...(model.discriminators ?? []).map((discriminator) => ({
72
+ inject: [getModelToken(model.name)],
73
+ provide: getModelToken(discriminator.name),
74
+ useFactory: (parent: { discriminator: Function }) =>
75
+ parent.discriminator(discriminator.name, discriminator.schema, discriminator.value),
76
+ })),
77
+ ]);
78
+ const stores: Provider[] = models.map((model) => ({
79
+ inject: [getModelToken(model.name)],
80
+ provide: getStoreToken(model.name),
81
+ // Routed when the store is created, not when the module is declared: feature modules are usually evaluated
82
+ // before `CoreModule.forRoot()` has read the configuration
83
+ useFactory: async (mongooseModel: Model<any>) => {
84
+ const runtime = getPersistenceRuntime();
85
+ const store = runtime
86
+ ? await runtime.resolveStore(model.name, mongooseModel)
87
+ : isStandInModel(mongooseModel)
88
+ ? // No SQL source and no MongoDB connection: the project runs without a database (`database: false`)
89
+ unavailableStore(model.name, 'the project runs without a database (`database: false`)')
90
+ : new MongooseDataStore(mongooseModel);
91
+ registerDataStore(model.name, store);
92
+ bindStoreToModel(mongooseModel, store);
93
+ // A stand-in already refuses, naming the cause; a real Mongoose model of a model routed elsewhere is made to
94
+ if (!store.capabilities.mongoosePopulate && !isStandInModel(mongooseModel)) {
95
+ guardRoutedModel(mongooseModel, store);
96
+ }
97
+ return store;
98
+ },
99
+ }));
100
+ return {
101
+ exports: [
102
+ ...mongooseModels.map((provider) => (provider as { provide: string }).provide),
103
+ ...stores.map((store) => (store as { provide: string }).provide),
104
+ ],
105
+ module: CorePersistenceModule,
106
+ providers: [...mongooseModels, ...stores],
107
+ };
108
+ }
109
+ }
@@ -0,0 +1,271 @@
1
+ import type {
2
+ DatabaseSqlEngine,
3
+ IDatabaseConfig,
4
+ IDatabaseSourceConfig,
5
+ } from '../interfaces/server-options.interface.js';
6
+
7
+ /**
8
+ * Resolution of the `database` configuration into named data sources, and of a model to its source.
9
+ *
10
+ * Pure functions: no connection is opened here. `CoreModule.forRoot()` resolves once at boot and refuses,
11
+ * before anything connects, what the running version cannot wire (`assertDataSourcesSupported`).
12
+ */
13
+
14
+ export type DatabaseDriver = 'mariadb' | 'mongodb' | 'mysql' | 'postgres';
15
+
16
+ export interface ResolvedDataSource {
17
+ driver: DatabaseDriver;
18
+ name: string;
19
+ /** Present on SQL sources that configure the owner connection */
20
+ ownerUrl?: string;
21
+ /** Present on SQL sources only */
22
+ sqlEngine?: DatabaseSqlEngine;
23
+ url: string;
24
+ }
25
+
26
+ export interface ResolvedDataSources {
27
+ /** Name of the default source; `undefined` when no database is configured */
28
+ defaultSource: string | undefined;
29
+ /** `database: false` — the project runs without any database */
30
+ disabled: boolean;
31
+ /** Configured exceptions: model name → source name */
32
+ modelSources: Record<string, string>;
33
+ sources: Record<string, ResolvedDataSource>;
34
+ }
35
+
36
+ export interface ResolveDataSourcesInput {
37
+ database?: false | IDatabaseConfig | string;
38
+ /** Whether the PROJECT configured `mongoose` — the framework's own fallback URI does not count */
39
+ explicitMongoose?: boolean;
40
+ /** The effective mongoose URI (project value or framework fallback) */
41
+ mongooseUri?: string;
42
+ }
43
+
44
+ /** A configuration this version cannot resolve or cannot wire. Thrown at boot, never at request time. */
45
+ export class DataSourceConfigError extends Error {
46
+ constructor(message: string) {
47
+ super(`[database] ${message}`);
48
+ this.name = 'DataSourceConfigError';
49
+ }
50
+ }
51
+
52
+ export const DEFAULT_SOURCE = 'default';
53
+ /** Source name an explicitly configured `mongoose` gets when `database` sets the default */
54
+ export const MONGOOSE_SOURCE = 'mongoose';
55
+ export const DEFAULT_SQL_ENGINE: DatabaseSqlEngine = 'typeorm';
56
+
57
+ const SQL_ENGINES: readonly DatabaseSqlEngine[] = ['drizzle', 'kysely', 'typeorm'];
58
+ const SOURCE_NAME = /^[A-Za-z][\w-]*$/;
59
+ const DRIVERS: Record<string, DatabaseDriver> = {
60
+ 'mariadb:': 'mariadb',
61
+ 'mongodb+srv:': 'mongodb',
62
+ 'mongodb:': 'mongodb',
63
+ 'mysql:': 'mysql',
64
+ 'postgres:': 'postgres',
65
+ 'postgresql:': 'postgres',
66
+ };
67
+
68
+ /**
69
+ * The database a URL points at, taken from its scheme.
70
+ */
71
+ export function driverFromUrl(url: string): DatabaseDriver {
72
+ const scheme = /^[a-z][a-z0-9+.-]*:/i.exec(url)?.[0]?.toLowerCase();
73
+ const driver = scheme ? DRIVERS[scheme] : undefined;
74
+ if (!driver) {
75
+ throw new DataSourceConfigError(
76
+ `Unsupported connection URL ${redactUrl(url)} — use mongodb://, mongodb+srv://, postgres://, postgresql://, mysql:// or mariadb://`,
77
+ );
78
+ }
79
+ return driver;
80
+ }
81
+
82
+ /**
83
+ * A connection URL reduced to scheme and host, so an error message or a log line never carries
84
+ * credentials, a path or query options (which may hold a password too).
85
+ */
86
+ export function redactUrl(url: unknown): string {
87
+ if (typeof url !== 'string') {
88
+ return `<${typeof url}>`;
89
+ }
90
+ const scheme = /^([a-z][a-z0-9+.-]*:)\/\//i.exec(url);
91
+ if (!scheme) {
92
+ return '<unparsable URL>';
93
+ }
94
+ // The authority ends at the first `/`, `?` or `#`, and the credentials at the LAST `@` inside it — the WHATWG
95
+ // rule node-postgres parses by, so a password with an unencoded `@` (which it accepts) never reaches the result
96
+ const authority = url.slice(scheme[0].length).split(/[/?#]/, 1)[0];
97
+ return `${scheme[1]}//${authority.slice(authority.lastIndexOf('@') + 1)}`;
98
+ }
99
+
100
+ /**
101
+ * Resolve the `database` configuration (plus the mongoose configuration it extends) into named sources.
102
+ */
103
+ export function resolveDataSources(input: ResolveDataSourcesInput): ResolvedDataSources {
104
+ const { database, explicitMongoose, mongooseUri } = input;
105
+
106
+ if (database === false) {
107
+ return { defaultSource: undefined, disabled: true, modelSources: {}, sources: {} };
108
+ }
109
+
110
+ const config: IDatabaseConfig = typeof database === 'string' ? { url: database } : (database ?? {});
111
+ if (typeof config !== 'object' || Array.isArray(config)) {
112
+ throw new DataSourceConfigError('`database` must be a URL, an object or false');
113
+ }
114
+ if (config.ownerUrl !== undefined && config.url === undefined) {
115
+ // The usual cause: `database` was a URL string and an NSC__DATABASE__* variable (e.g. NSC__DATABASE__OWNER_URL)
116
+ // was merged over it — the environment merge REPLACES a string with an object, so the URL is gone and every
117
+ // model would fall back to MongoDB without a word
118
+ throw new DataSourceConfigError(
119
+ 'database.ownerUrl is set but database.url is not. A NSC__DATABASE__* variable replaces a `database` given as a ' +
120
+ 'URL string; write `database: { url: … }` in the configuration (or set NSC__DATABASE__URL as well)',
121
+ );
122
+ }
123
+ const topEngine = config.sqlEngine === undefined ? undefined : checkEngine(config.sqlEngine, 'database.sqlEngine');
124
+
125
+ const sources: Record<string, ResolvedDataSource> = {};
126
+ if (config.url !== undefined) {
127
+ sources[DEFAULT_SOURCE] = buildSource(
128
+ DEFAULT_SOURCE,
129
+ { ownerUrl: config.ownerUrl, url: config.url },
130
+ topEngine,
131
+ 'database.url',
132
+ );
133
+ // A project that keeps its MongoDB next to a new default reaches it as a named source
134
+ if (explicitMongoose && mongooseUri) {
135
+ sources[MONGOOSE_SOURCE] = buildSource(MONGOOSE_SOURCE, { url: mongooseUri }, undefined, 'mongoose.uri');
136
+ }
137
+ } else if (mongooseUri) {
138
+ sources[DEFAULT_SOURCE] = buildSource(DEFAULT_SOURCE, { url: mongooseUri }, undefined, 'mongoose.uri');
139
+ }
140
+
141
+ for (const [name, value] of Object.entries(config.sources ?? {})) {
142
+ if (name === DEFAULT_SOURCE || name === MONGOOSE_SOURCE) {
143
+ throw new DataSourceConfigError(`database.sources: the source name "${name}" is reserved`);
144
+ }
145
+ if (!SOURCE_NAME.test(name)) {
146
+ throw new DataSourceConfigError(
147
+ `database.sources: invalid source name "${name}" — use letters, digits, "_" and "-", starting with a letter`,
148
+ );
149
+ }
150
+ const source: IDatabaseSourceConfig = typeof value === 'string' ? { url: value } : value;
151
+ sources[name] = buildSource(name, source, topEngine, `database.sources.${name}`);
152
+ }
153
+
154
+ const modelSources: Record<string, string> = {};
155
+ for (const [model, source] of Object.entries(config.models ?? {})) {
156
+ if (typeof source !== 'string' || !sources[source]) {
157
+ throw new DataSourceConfigError(
158
+ `database.models.${model} names the source "${String(source)}", which is not configured (known: ${knownSources(sources)})`,
159
+ );
160
+ }
161
+ modelSources[model] = source;
162
+ }
163
+
164
+ return {
165
+ defaultSource: sources[DEFAULT_SOURCE] ? DEFAULT_SOURCE : undefined,
166
+ disabled: false,
167
+ modelSources,
168
+ sources,
169
+ };
170
+ }
171
+
172
+ /**
173
+ * The source a model is stored in: the configuration first, then the class's `@PersistedModel`
174
+ * declaration, then the default source. `undefined` when the project runs without a database.
175
+ */
176
+ export function resolveModelSource(
177
+ resolved: ResolvedDataSources,
178
+ modelName: string,
179
+ declaredSource?: string,
180
+ ): string | undefined {
181
+ if (resolved.disabled) {
182
+ return undefined;
183
+ }
184
+ const configured = resolved.modelSources[modelName];
185
+ if (configured) {
186
+ return configured;
187
+ }
188
+ if (declaredSource !== undefined) {
189
+ if (!resolved.sources[declaredSource]) {
190
+ throw new DataSourceConfigError(
191
+ `@PersistedModel on ${modelName} names the source "${declaredSource}", which is not configured (known: ${knownSources(resolved.sources)})`,
192
+ );
193
+ }
194
+ return declaredSource;
195
+ }
196
+ return resolved.defaultSource;
197
+ }
198
+
199
+ /**
200
+ * Refuse what the running version cannot wire, with a message naming the setting.
201
+ *
202
+ * PostgreSQL, MySQL and MariaDB sources (default or additional) are wired next to the MongoDB connection, and since
203
+ * 12.1.0 a project runs without any database (`database: false`); a second MongoDB connection is refused. Refusing at
204
+ * boot is the point: a configuration that is accepted and then silently served by the wrong database is the outcome to
205
+ * avoid.
206
+ */
207
+ export function assertDataSourcesSupported(resolved: ResolvedDataSources): void {
208
+ for (const source of Object.values(resolved.sources)) {
209
+ if (source.driver === 'mongodb' && source.name !== DEFAULT_SOURCE && source.name !== MONGOOSE_SOURCE) {
210
+ throw new DataSourceConfigError(
211
+ `The additional MongoDB source "${source.name}" (${redactUrl(source.url)}) is not supported by this version yet — one MongoDB connection only`,
212
+ );
213
+ }
214
+ }
215
+ }
216
+
217
+ /** Whether any configured source is a MongoDB — the connection CoreModule opens, and the libraries it needs */
218
+ export function usesMongoDb(resolved: ResolvedDataSources): boolean {
219
+ return Object.values(resolved.sources).some((source) => source.driver === 'mongodb');
220
+ }
221
+
222
+ /** Whether any configured source is a SQL database */
223
+ export function hasSqlSource(resolved: ResolvedDataSources): boolean {
224
+ return Object.values(resolved.sources).some((source) => source.driver !== 'mongodb');
225
+ }
226
+
227
+ function buildSource(
228
+ name: string,
229
+ source: IDatabaseSourceConfig,
230
+ fallbackEngine: DatabaseSqlEngine | undefined,
231
+ path: string,
232
+ ): ResolvedDataSource {
233
+ if (!source || typeof source !== 'object' || typeof source.url !== 'string' || !source.url) {
234
+ throw new DataSourceConfigError(`${path}: the url must be a non-empty string`);
235
+ }
236
+ const driver = driverFromUrl(source.url);
237
+ if (driver === 'mongodb') {
238
+ if (source.ownerUrl !== undefined) {
239
+ throw new DataSourceConfigError(`${path}: ownerUrl applies to SQL sources only, not to ${redactUrl(source.url)}`);
240
+ }
241
+ if (source.sqlEngine !== undefined) {
242
+ throw new DataSourceConfigError(
243
+ `${path}: sqlEngine applies to SQL sources only, not to ${redactUrl(source.url)}`,
244
+ );
245
+ }
246
+ return { driver, name, url: source.url };
247
+ }
248
+ const engine =
249
+ source.sqlEngine === undefined
250
+ ? (fallbackEngine ?? DEFAULT_SQL_ENGINE)
251
+ : checkEngine(source.sqlEngine, `${path}.sqlEngine`);
252
+ if (source.ownerUrl !== undefined) {
253
+ if (typeof source.ownerUrl !== 'string' || !source.ownerUrl || driverFromUrl(source.ownerUrl) !== driver) {
254
+ throw new DataSourceConfigError(`${path}: ownerUrl must be a ${driver} URL of the same database`);
255
+ }
256
+ return { driver, name, ownerUrl: source.ownerUrl, sqlEngine: engine, url: source.url };
257
+ }
258
+ return { driver, name, sqlEngine: engine, url: source.url };
259
+ }
260
+
261
+ function checkEngine(value: unknown, path: string): DatabaseSqlEngine {
262
+ if (!SQL_ENGINES.includes(value as DatabaseSqlEngine)) {
263
+ throw new DataSourceConfigError(`${path}: "${String(value)}" is not a known sqlEngine (${SQL_ENGINES.join(', ')})`);
264
+ }
265
+ return value as DatabaseSqlEngine;
266
+ }
267
+
268
+ function knownSources(sources: Record<string, ResolvedDataSource>): string {
269
+ const names = Object.keys(sources);
270
+ return names.length ? names.join(', ') : 'none';
271
+ }