@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,85 @@
1
+ import type { LockStore } from '../lock-store.interface.js';
2
+ import type { ModelDescriptor } from '../model-descriptor.interface.js';
3
+ import { MysqlDataStore } from './mysql/mysql-data-store.js';
4
+ import type { MysqlExecutor } from './mysql/mysql-executor.js';
5
+ import { MysqlLockStore } from './mysql/mysql-lock-store.js';
6
+ import {
7
+ applyMysqlSchema,
8
+ assertSafeMysqlApplicationAccount,
9
+ type MysqlSchemaOptions,
10
+ mysqlAccount,
11
+ verifyMysqlSchema,
12
+ } from './mysql/mysql-schema.migrator.js';
13
+ import type { MysqlVariant } from './mysql/mysql-session.js';
14
+ import { PostgresLockStore } from './postgres/postgres-lock-store.js';
15
+ import type { PostgresSchemaOptions } from './postgres/postgres-schema.compiler.js';
16
+ import {
17
+ applyPostgresSchema,
18
+ assertSafeApplicationRole,
19
+ verifyPostgresSchema,
20
+ } from './postgres/postgres-schema.migrator.js';
21
+ import { SqlDataStore, type SqlDataStoreOptions } from './sql-data-store.js';
22
+ import type { SqlExecutor } from './sql-executor.interface.js';
23
+ import type { SchemaChange } from './sql-schema.shared.js';
24
+
25
+ /**
26
+ * What differs between the SQL databases at the level of a data source: how its schema is brought up to date, which
27
+ * application role it accepts, and which store and lease implementation serve it. The runtime asks the dialect and
28
+ * never the driver name.
29
+ */
30
+ export interface SqlDialect {
31
+ /** Shown in boot logs: `PostgreSQL`, `MySQL`, `MariaDB` */
32
+ readonly label: string;
33
+ /** Apply every automatic change as the OWNER (one locked run); refuses when a migration is needed */
34
+ applySchema(owner: SqlExecutor, app: SqlExecutor, models: ModelDescriptor[]): Promise<SchemaChange[]>;
35
+ /** Refuse an application role the database's protections cannot bind */
36
+ assertSafeApplication(app: SqlExecutor, tables: string[]): Promise<void>;
37
+ createLockStore(app: SqlExecutor): LockStore;
38
+ createStore(app: SqlExecutor, model: ModelDescriptor, options: SqlDataStoreOptions): SqlDataStore<any>;
39
+ /** How a tenant-isolated model's rows are protected, for the boot log */
40
+ isolation(isolated: boolean): string;
41
+ /** Without an owner connection: only check, and refuse to start on any pending change */
42
+ verifySchema(app: SqlExecutor, models: ModelDescriptor[]): Promise<SchemaChange[]>;
43
+ }
44
+
45
+ export interface SqlDialectContext {
46
+ /** The application role as the connection URL names it */
47
+ appRole: string;
48
+ driver: 'mariadb' | 'mysql' | 'postgres';
49
+ isTenantIsolated: (model: ModelDescriptor) => boolean;
50
+ }
51
+
52
+ export function sqlDialect(context: SqlDialectContext): SqlDialect {
53
+ return context.driver === 'postgres' ? postgresDialect(context) : mysqlDialect(context.driver);
54
+ }
55
+
56
+ function postgresDialect(context: SqlDialectContext): SqlDialect {
57
+ const options: PostgresSchemaOptions = { appRole: context.appRole, isTenantIsolated: context.isTenantIsolated };
58
+ return {
59
+ applySchema: (owner, _app, models) => applyPostgresSchema(owner, models, options),
60
+ assertSafeApplication: (app, tables) => assertSafeApplicationRole(app, tables),
61
+ createLockStore: (app) => new PostgresLockStore(app),
62
+ createStore: (app, model, storeOptions) => new SqlDataStore<any>(app, model, storeOptions),
63
+ isolation: (isolated) => (isolated ? ' (row-level security)' : ''),
64
+ label: 'PostgreSQL',
65
+ verifySchema: (app, models) => verifyPostgresSchema(app, models, options),
66
+ };
67
+ }
68
+
69
+ function mysqlDialect(variant: MysqlVariant): SqlDialect {
70
+ let account: Promise<string> | undefined;
71
+ // The account as the server matched it (`'user'@'host'`) — the name a grant needs, not the URL's user alone
72
+ const options = async (app: SqlExecutor): Promise<MysqlSchemaOptions> => {
73
+ account ??= mysqlAccount(app);
74
+ return { appAccount: await account, variant };
75
+ };
76
+ return {
77
+ applySchema: async (owner, app, models) => applyMysqlSchema(owner, models, await options(app)),
78
+ assertSafeApplication: (app) => assertSafeMysqlApplicationAccount(app, variant),
79
+ createLockStore: (app) => new MysqlLockStore(app),
80
+ createStore: (app, model, storeOptions) => new MysqlDataStore<any>(app as MysqlExecutor, model, storeOptions),
81
+ isolation: (isolated) => (isolated ? ' (tenant isolation in the application only)' : ''),
82
+ label: variant === 'mysql' ? 'MySQL' : 'MariaDB',
83
+ verifySchema: async (app, models) => verifyMysqlSchema(app, models, await options(app)),
84
+ };
85
+ }
@@ -0,0 +1,49 @@
1
+ import { BadRequestException } from '@nestjs/common';
2
+
3
+ /**
4
+ * Errors of the SQL persistence layer.
5
+ *
6
+ * Neither message carries the offending VALUE: a filter value can be anything a request sent, including a
7
+ * credential, and these messages travel into logs.
8
+ */
9
+
10
+ /**
11
+ * A filter, sort or update the SQL store cannot express. Thrown instead of dropping a condition (plan §3.2) —
12
+ * a condition that silently disappears widens a query, which on a tenant- or owner-scoped read is a data leak.
13
+ */
14
+ export class UnsupportedQueryError extends Error {
15
+ override readonly name = 'UnsupportedQueryError';
16
+ }
17
+
18
+ /**
19
+ * A filter value that cannot be cast to its field's type — the SQL counterpart of Mongoose's `CastError`, with the
20
+ * same casting rules, so a value MongoDB refuses is refused on SQL too.
21
+ */
22
+ export class QueryCastError extends Error {
23
+ override readonly name = 'QueryCastError';
24
+
25
+ /** The value that failed — not enumerable, so it never reaches a serialized error or a log line by accident */
26
+ declare readonly value: unknown;
27
+
28
+ constructor(
29
+ readonly path: string,
30
+ readonly kind: string,
31
+ value?: unknown,
32
+ ) {
33
+ super(`Cast to ${kind} failed at path "${path}"`);
34
+ Object.defineProperty(this, 'value', { enumerable: false, value });
35
+ }
36
+ }
37
+
38
+ /**
39
+ * A unique constraint refused a write — answered with 400. Carries MongoDB's duplicate-key code and message prefix,
40
+ * because callers in the framework and in projects recognise a duplicate by `error.code === 11000` or by `E11000`.
41
+ */
42
+ export class DuplicateKeyError extends BadRequestException {
43
+ override readonly name = 'DuplicateKeyError';
44
+ readonly code = 11000;
45
+
46
+ constructor(readonly model: string) {
47
+ super(`E11000 duplicate key error: a unique value of ${model} already exists`);
48
+ }
49
+ }
@@ -0,0 +1,282 @@
1
+ import type { DatabaseSqlEngine } from '../../interfaces/server-options.interface.js';
2
+ import type {
3
+ SqlExecutor,
4
+ SqlQueryResult,
5
+ SqlStatement,
6
+ SqlTenantScope,
7
+ SqlTransaction,
8
+ } from './sql-executor.interface.js';
9
+ import { createMysqlExecutor } from './mysql/mysql-executor.js';
10
+ import { APPLY_SCOPE_SQL, guardPool, runInOwnTransaction, scopeParams } from './sql-session.js';
11
+
12
+ /**
13
+ * The SQL engine adapters (plan §3.10). The per-operation path is identical for every engine — node-postgres,
14
+ * pipelined, on a guarded pool — so switching the engine cannot change what a store operation does. Engines
15
+ * differ only in how they run a multi-statement transaction and in the native API they hand to projects.
16
+ *
17
+ * Every engine is an OPTIONAL peer dependency and loaded on first use (`import()` with a literal specifier: these
18
+ * are dual packages, so they are loaded lazily everywhere — see `.claude/rules/architecture.md`).
19
+ */
20
+
21
+ export interface SqlExecutorOptions {
22
+ /** Shown as `application_name` in `pg_stat_activity`. */
23
+ applicationName?: string;
24
+ engine: DatabaseSqlEngine;
25
+ /** Pool size. @default 10 */
26
+ maxConnections?: number;
27
+ /** Client-side statement timeout in milliseconds (node-postgres `query_timeout`). @default none */
28
+ queryTimeoutMs?: number;
29
+ /** Connection URL of the APPLICATION role */
30
+ url: string;
31
+ }
32
+
33
+ export async function createSqlExecutor(options: SqlExecutorOptions): Promise<SqlExecutor> {
34
+ // The URL's scheme picks the dialect: MySQL and MariaDB have adapters of their own (phase 6)
35
+ const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(options.url)?.[1]?.toLowerCase();
36
+ if (scheme === 'mysql' || scheme === 'mariadb') {
37
+ return createMysqlExecutor({
38
+ engine: options.engine,
39
+ maxConnections: options.maxConnections,
40
+ url: options.url,
41
+ variant: scheme,
42
+ });
43
+ }
44
+ switch (options.engine) {
45
+ case 'drizzle':
46
+ return createDrizzleExecutor(options);
47
+ case 'kysely':
48
+ return createKyselyExecutor(options);
49
+ case 'typeorm':
50
+ return createTypeOrmExecutor(options);
51
+ default:
52
+ throw new Error(`Unknown SQL engine "${String(options.engine)}"`);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * The first SQL engine the project has installed, in the framework's order (`typeorm`, `kysely`, `drizzle`) — for a
58
+ * caller that runs outside the application and has no `database.sqlEngine` to read, such as the migrate CLI. A project
59
+ * installs only the engine it chose, so assuming the default there would fail every call of a project on another one.
60
+ */
61
+ export async function installedSqlEngine(): Promise<DatabaseSqlEngine> {
62
+ const candidates: [DatabaseSqlEngine, () => Promise<unknown>][] = [
63
+ ['typeorm', () => import('typeorm')],
64
+ ['kysely', () => import('kysely')],
65
+ ['drizzle', () => import('drizzle-orm')],
66
+ ];
67
+ for (const [engine, load] of candidates) {
68
+ try {
69
+ await load();
70
+ return engine;
71
+ } catch {
72
+ // Not installed — try the next one
73
+ }
74
+ }
75
+ throw new Error(
76
+ 'A SQL connection needs one of the optional SQL engines, none is installed. Run: pnpm add typeorm pg ' +
77
+ '(PostgreSQL) or pnpm add typeorm mysql2 (MySQL / MariaDB)',
78
+ );
79
+ }
80
+
81
+ function missingPeer(name: string): Error {
82
+ return new Error(
83
+ `A SQL data source is configured but the optional peer dependency "${name}" is not installed. Run: pnpm add ${name}`,
84
+ );
85
+ }
86
+
87
+ /** Pool options shared by every engine: pipelining for the per-operation path, the guard against poisoned clients. */
88
+ function poolOptions(options: SqlExecutorOptions): Record<string, unknown> {
89
+ return {
90
+ max: options.maxConnections ?? 10,
91
+ pipeline: true,
92
+ ...(options.applicationName ? { application_name: options.applicationName } : {}),
93
+ ...(options.queryTimeoutMs ? { query_timeout: options.queryTimeoutMs } : {}),
94
+ };
95
+ }
96
+
97
+ /**
98
+ * The node-postgres error behind an engine's wrapper (TypeORM `QueryFailedError.driverError`, Drizzle
99
+ * `DrizzleQueryError.cause`), so every engine fails with the same error and SQLSTATE as the per-operation path. It
100
+ * also keeps the statement's parameters out of the message: Drizzle's wrapper prints them.
101
+ */
102
+ function driverErrorOf(error: unknown): unknown {
103
+ const wrapped = (error as { cause?: unknown; driverError?: unknown } | undefined) ?? {};
104
+ for (const inner of [wrapped.driverError, wrapped.cause]) {
105
+ if (inner instanceof Error && typeof (inner as { code?: unknown }).code === 'string') {
106
+ return inner;
107
+ }
108
+ }
109
+ return error;
110
+ }
111
+
112
+ /** Run `step`, rethrowing an engine's wrapped error as the driver error underneath. */
113
+ async function unwrapped<T>(step: () => Promise<T>): Promise<T> {
114
+ try {
115
+ return await step();
116
+ } catch (error) {
117
+ throw driverErrorOf(error);
118
+ }
119
+ }
120
+
121
+ async function createPgPool(options: SqlExecutorOptions): Promise<any> {
122
+ let pg: any;
123
+ try {
124
+ pg = await import('pg');
125
+ } catch {
126
+ throw missingPeer('pg');
127
+ }
128
+ const Pool = pg.Pool ?? pg.default?.Pool;
129
+ return guardPool(new Pool({ connectionString: options.url, ...poolOptions(options) }));
130
+ }
131
+
132
+ function resultOf<R>(rows: R[] | undefined, rowCount: null | number | undefined): SqlQueryResult<R> {
133
+ const list = rows ?? [];
134
+ return { rowCount: typeof rowCount === 'number' ? rowCount : list.length, rows: list };
135
+ }
136
+
137
+ // ---------------------------------------------------------------------------------------------
138
+ // TypeORM (default)
139
+ // ---------------------------------------------------------------------------------------------
140
+
141
+ async function createTypeOrmExecutor(options: SqlExecutorOptions): Promise<SqlExecutor> {
142
+ let typeorm: any;
143
+ try {
144
+ typeorm = await import('typeorm');
145
+ } catch {
146
+ throw missingPeer('typeorm');
147
+ }
148
+ const DataSource = typeorm.DataSource ?? typeorm.default?.DataSource;
149
+ // The framework owns the schema (plan §3.12): TypeORM never synchronizes or runs migrations of its own.
150
+ const dataSource = new DataSource({
151
+ entities: [],
152
+ extra: poolOptions(options),
153
+ migrationsRun: false,
154
+ synchronize: false,
155
+ type: 'postgres',
156
+ url: options.url,
157
+ });
158
+ await dataSource.initialize();
159
+ const pool = guardPool(dataSource.driver.master);
160
+
161
+ return {
162
+ close: () => dataSource.destroy(),
163
+ driverPool: pool,
164
+ engine: 'typeorm',
165
+ native: <N>() => dataSource as N,
166
+ run: <R>(statement: SqlStatement, scope: SqlTenantScope) => runInOwnTransaction<R>(pool, statement, scope),
167
+ transaction: async <T>(fn: (tx: SqlTransaction) => Promise<T>): Promise<T> => {
168
+ const runner = dataSource.createQueryRunner();
169
+ await runner.connect();
170
+ await runner.startTransaction();
171
+ try {
172
+ const value = await fn({
173
+ native: <N>() => runner.manager as N,
174
+ run: <R>(statement: SqlStatement, scope: SqlTenantScope) =>
175
+ unwrapped(async () => {
176
+ await runner.query(APPLY_SCOPE_SQL, scopeParams(scope));
177
+ const result = await runner.query(statement.text, [...statement.params], true);
178
+ return resultOf<R>(result.records, result.affected);
179
+ }),
180
+ });
181
+ await unwrapped(() => runner.commitTransaction());
182
+ return value;
183
+ } catch (error) {
184
+ if (runner.isTransactionActive) {
185
+ await runner.rollbackTransaction().catch(() => undefined);
186
+ }
187
+ throw error;
188
+ } finally {
189
+ await runner.release();
190
+ }
191
+ },
192
+ };
193
+ }
194
+
195
+ // ---------------------------------------------------------------------------------------------
196
+ // Kysely
197
+ // ---------------------------------------------------------------------------------------------
198
+
199
+ async function createKyselyExecutor(options: SqlExecutorOptions): Promise<SqlExecutor> {
200
+ let kysely: any;
201
+ try {
202
+ kysely = await import('kysely');
203
+ } catch {
204
+ throw missingPeer('kysely');
205
+ }
206
+ const { CompiledQuery, Kysely, PostgresDialect } = kysely;
207
+ const pool = await createPgPool(options);
208
+ const db = new Kysely({ dialect: new PostgresDialect({ pool }) });
209
+
210
+ return {
211
+ close: () => db.destroy(),
212
+ driverPool: pool,
213
+ engine: 'kysely',
214
+ native: <N>() => db as N,
215
+ run: <R>(statement: SqlStatement, scope: SqlTenantScope) => runInOwnTransaction<R>(pool, statement, scope),
216
+ transaction: <T>(fn: (tx: SqlTransaction) => Promise<T>): Promise<T> =>
217
+ db.transaction().execute((trx: any) =>
218
+ fn({
219
+ native: <N>() => trx as N,
220
+ run: async <R>(statement: SqlStatement, scope: SqlTenantScope) => {
221
+ await trx.executeQuery(CompiledQuery.raw(APPLY_SCOPE_SQL, scopeParams(scope)));
222
+ const result = await trx.executeQuery(CompiledQuery.raw(statement.text, [...statement.params]));
223
+ const affected = result.numAffectedRows === undefined ? undefined : Number(result.numAffectedRows);
224
+ return resultOf<R>(result.rows, affected);
225
+ },
226
+ }),
227
+ ),
228
+ };
229
+ }
230
+
231
+ // ---------------------------------------------------------------------------------------------
232
+ // Drizzle
233
+ // ---------------------------------------------------------------------------------------------
234
+
235
+ async function createDrizzleExecutor(options: SqlExecutorOptions): Promise<SqlExecutor> {
236
+ let drizzleOrm: any;
237
+ let drizzlePg: any;
238
+ try {
239
+ drizzleOrm = await import('drizzle-orm');
240
+ drizzlePg = await import('drizzle-orm/node-postgres');
241
+ } catch {
242
+ throw missingPeer('drizzle-orm');
243
+ }
244
+ const { sql } = drizzleOrm;
245
+ const pool = await createPgPool(options);
246
+ const db = drizzlePg.drizzle({ client: pool });
247
+
248
+ // Positional statement → Drizzle SQL with the values bound as parameters again. Only `$<digits>` placeholders
249
+ // are split, and the framework's compilers never emit one inside a literal. `sql.param()`, not `sql\`${value}\``:
250
+ // the template expands an array into a list of parameters, which turns a `text[]` into a row.
251
+ const toSql = (text: string, params: readonly unknown[]) =>
252
+ sql.join(
253
+ text.split(/\$(\d+)/).map((part, index) => (index % 2 ? sql.param(params[Number(part) - 1]) : sql.raw(part))),
254
+ sql.raw(''),
255
+ );
256
+
257
+ return {
258
+ close: () => pool.end(),
259
+ driverPool: pool,
260
+ engine: 'drizzle',
261
+ native: <N>() => db as N,
262
+ run: <R>(statement: SqlStatement, scope: SqlTenantScope) => runInOwnTransaction<R>(pool, statement, scope),
263
+ // Drizzle runs the COMMIT inside `db.transaction()`; only that statement's wrapper is unwrapped here, an error
264
+ // `fn` raised through Drizzle's own API stays Drizzle's.
265
+ transaction: <T>(fn: (tx: SqlTransaction) => Promise<T>): Promise<T> =>
266
+ db
267
+ .transaction((tx: any) =>
268
+ fn({
269
+ native: <N>() => tx as N,
270
+ run: <R>(statement: SqlStatement, scope: SqlTenantScope) =>
271
+ unwrapped(async () => {
272
+ await tx.execute(toSql(APPLY_SCOPE_SQL, scopeParams(scope)));
273
+ const result = await tx.execute(toSql(statement.text, statement.params));
274
+ return resultOf<R>(result.rows, result.rowCount);
275
+ }),
276
+ }),
277
+ )
278
+ .catch((error: unknown) => {
279
+ throw (error as { query?: unknown })?.query === 'commit' ? driverErrorOf(error) : error;
280
+ }),
281
+ };
282
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The SQL executor port: what the framework needs from a SQL engine (plan §3.10).
3
+ *
4
+ * The framework compiles every statement, policy and schema change itself; an engine only executes and
5
+ * offers its own API for native access. Import-free on purpose (types only).
6
+ */
7
+ import type { DatabaseSqlEngine } from '../../interfaces/server-options.interface.js';
8
+
9
+ /**
10
+ * The tenant scope of ONE statement, written into the transaction with `set_config(…, true)` and read by the
11
+ * RLS guard function (plan §3.4, §3.8).
12
+ *
13
+ * - `system`: no tenant filter (system work, `runWithBypassTenantGuard()`, or a platform admin without tenant)
14
+ * - `tenant`: exactly `tenantId`
15
+ * - `tenants`: any of `tenantIds` (header-less read of a member)
16
+ * - `none`: no valid tenant context — the guard function refuses every tenant-scoped row (42501)
17
+ */
18
+ export type SqlTenantScope =
19
+ | { kind: 'none' }
20
+ | { kind: 'system' }
21
+ | { kind: 'tenant'; tenantId: string }
22
+ | { kind: 'tenants'; tenantIds: readonly string[] };
23
+
24
+ export interface SqlQueryResult<R = Record<string, any>> {
25
+ rowCount: number;
26
+ rows: R[];
27
+ }
28
+
29
+ /** A statement and its positional parameters (`$1`, `$2`, …). */
30
+ export interface SqlStatement {
31
+ params: readonly unknown[];
32
+ text: string;
33
+ }
34
+
35
+ /** Statements inside one transaction, on one connection. */
36
+ export interface SqlTransaction {
37
+ /** The engine's own API, bound to this transaction's connection. */
38
+ native<N = unknown>(): N;
39
+ /** Run a statement after applying `scope` to the transaction. */
40
+ run<R = Record<string, any>>(statement: SqlStatement, scope: SqlTenantScope): Promise<SqlQueryResult<R>>;
41
+ }
42
+
43
+ export interface SqlExecutor {
44
+ close(): Promise<void>;
45
+ /** The node-postgres pool the executor runs on — for Better-Auth's own adapter. */
46
+ readonly driverPool: unknown;
47
+ readonly engine: DatabaseSqlEngine;
48
+ /** The engine's own API, outside any framework transaction. */
49
+ native<N = unknown>(): N;
50
+ /**
51
+ * Run ONE statement in its own transaction with `scope` applied — `BEGIN`, `set_config`, statement, `COMMIT`
52
+ * pipelined into a single round trip (plan §3.8, A13).
53
+ */
54
+ run<R = Record<string, any>>(statement: SqlStatement, scope: SqlTenantScope): Promise<SqlQueryResult<R>>;
55
+ /** Several statements in one transaction, on one connection; rolled back when `fn` throws. */
56
+ transaction<T>(fn: (tx: SqlTransaction) => Promise<T>): Promise<T>;
57
+ }
@@ -0,0 +1,133 @@
1
+ import { UnsupportedQueryError } from './sql-errors.js';
2
+
3
+ /**
4
+ * Identifier rules shared by the query compiler and the schema compiler: one mapping from a model's field name to
5
+ * its column, and one place that decides what may become an identifier at all.
6
+ *
7
+ * Identifiers never come from a request: every name is looked up in the model descriptor first. This module is the
8
+ * second line — whatever reaches `quoteIdentifier()` must still look like an identifier, or it is refused.
9
+ */
10
+
11
+ const IDENTIFIER = /^[A-Za-z_]\w*$/;
12
+ /** Postgres truncates longer identifiers silently, which would let two names address one column */
13
+ const MAX_IDENTIFIER_LENGTH = 63;
14
+
15
+ /**
16
+ * Names that address JavaScript's object machinery rather than data. Mongoose ignores them in a path; a compiler that
17
+ * builds an object from path segments would otherwise reach `Object.prototype` through them
18
+ */
19
+ const RESERVED_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);
20
+
21
+ /** A field-name or path segment as the query language accepts it: no dots, no `$`, no leading digit, no prototype name. */
22
+ export function isPathSegment(segment: string): boolean {
23
+ return IDENTIFIER.test(segment) && !RESERVED_SEGMENTS.has(segment);
24
+ }
25
+
26
+ /** The column of a field: `_id` / `id` → `id`, camelCase → snake_case (`createdAt` → `created_at`, `userID` → `user_id`). */
27
+ export function columnName(field: string): string {
28
+ if (field === '_id' || field === 'id') {
29
+ return 'id';
30
+ }
31
+ if (!IDENTIFIER.test(field)) {
32
+ throw new UnsupportedQueryError(`"${field}" cannot be mapped to a column`);
33
+ }
34
+ return field
35
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2')
36
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
37
+ .toLowerCase();
38
+ }
39
+
40
+ /** Double-quote an identifier after checking it is one. */
41
+ export function quoteIdentifier(name: string): string {
42
+ if (!IDENTIFIER.test(name) || name.length > MAX_IDENTIFIER_LENGTH) {
43
+ throw new UnsupportedQueryError(`"${name}" is not a valid SQL identifier`);
44
+ }
45
+ return `"${name}"`;
46
+ }
47
+
48
+ /**
49
+ * Backtick-quote an identifier for MySQL / MariaDB after checking it is one — with the same limit as PostgreSQL's
50
+ * (MySQL allows 64), so a model's names are valid on every SQL database alike.
51
+ */
52
+ export function quoteMysqlIdentifier(name: string): string {
53
+ if (!IDENTIFIER.test(name) || name.length > MAX_IDENTIFIER_LENGTH) {
54
+ throw new UnsupportedQueryError(`"${name}" is not a valid SQL identifier`);
55
+ }
56
+ return `\`${name}\``;
57
+ }
58
+
59
+ /** Where a compiler puts a value: a bound parameter, or — for DDL, which has none — a literal. */
60
+ export interface SqlParamSink {
61
+ /** Returns the SQL that stands for `value` */
62
+ add(value: unknown): string;
63
+ }
64
+
65
+ /** Positional parameters of one statement (`$1`, `$2`, …), shared by every part that contributes to it. */
66
+ export class SqlParams implements SqlParamSink {
67
+ readonly values: unknown[] = [];
68
+
69
+ add(value: unknown): string {
70
+ this.values.push(value);
71
+ return `$${this.values.length}`;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Values as SQL literals, for the one place that cannot bind parameters: DDL (a partial index predicate, a column
77
+ * default). Only values the code declares reach it — schema options, never request data — and every literal is an
78
+ * escape-string (`E'…'`), so backslashes and quotes mean the same whatever `standard_conforming_strings` says.
79
+ */
80
+ export class SqlLiterals implements SqlParamSink {
81
+ add(value: unknown): string {
82
+ return sqlLiteral(value);
83
+ }
84
+ }
85
+
86
+ export function sqlLiteral(value: unknown): string {
87
+ if (value === null || value === undefined) {
88
+ return 'NULL';
89
+ }
90
+ if (typeof value === 'boolean') {
91
+ return value ? 'TRUE' : 'FALSE';
92
+ }
93
+ if (typeof value === 'number') {
94
+ if (!Number.isFinite(value)) {
95
+ throw new UnsupportedQueryError('A literal number must be finite');
96
+ }
97
+ return String(value);
98
+ }
99
+ if (typeof value === 'bigint') {
100
+ return value.toString();
101
+ }
102
+ if (value instanceof Date) {
103
+ return escapeString(value.toISOString());
104
+ }
105
+ if (Array.isArray(value)) {
106
+ return escapeString(`{${value.map(arrayElement).join(',')}}`);
107
+ }
108
+ if (typeof value === 'string') {
109
+ return escapeString(value);
110
+ }
111
+ throw new UnsupportedQueryError('A value of this type cannot be written as a SQL literal');
112
+ }
113
+
114
+ function arrayElement(value: unknown): string {
115
+ if (value === null || value === undefined) {
116
+ return 'NULL';
117
+ }
118
+ if (typeof value === 'number' || typeof value === 'bigint' || typeof value === 'boolean') {
119
+ return String(value);
120
+ }
121
+ const text = value instanceof Date ? value.toISOString() : value;
122
+ if (typeof text !== 'string') {
123
+ throw new UnsupportedQueryError('Only scalar arrays can be written as a SQL literal');
124
+ }
125
+ return `"${text.replace(/[\\"]/g, (char) => `\\${char}`)}"`;
126
+ }
127
+
128
+ function escapeString(text: string): string {
129
+ if (text.includes('\0')) {
130
+ throw new UnsupportedQueryError('A SQL literal cannot contain a NUL character');
131
+ }
132
+ return `E'${text.replace(/[\\']/g, (char) => `\\${char}`)}'`;
133
+ }