@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,453 @@
1
+ import type { ModelDescriptor } from '../../model-descriptor.interface.js';
2
+ import { isForeignColumn } from '../../persistence-runtime.registry.js';
3
+ import type { SqlExecutor, SqlQueryResult, SqlStatement, SqlTenantScope } from '../sql-executor.interface.js';
4
+ import { quoteMysqlIdentifier } from '../sql-naming.js';
5
+ import {
6
+ LOCK_MODEL,
7
+ type SchemaChange,
8
+ SchemaMigrationRequiredError,
9
+ SchemaOutOfDateError,
10
+ UnsafeDatabaseRoleError,
11
+ } from '../sql-schema.shared.js';
12
+ import type { MysqlVariant } from './mysql-session.js';
13
+ import {
14
+ addMysqlCheckStatement,
15
+ createMysqlTableStatement,
16
+ desiredMysqlTable,
17
+ type MysqlDesiredColumn,
18
+ type MysqlDesiredTable,
19
+ mysqlColumnDefinition,
20
+ NULL_SENTINEL_PREFIX,
21
+ variantLabel,
22
+ } from './mysql-schema.compiler.js';
23
+
24
+ /**
25
+ * Safe, framework-owned schema evolution on MySQL and MariaDB — the rules of `postgres-schema.migrator.ts`
26
+ * (`automatic` applied, `migration` refuses the boot, `notice` logged; nothing dropped or narrowed automatically).
27
+ *
28
+ * Two things differ. A DDL statement commits on its own in MySQL, so a run is not one transaction: it is serialized by
29
+ * a named lock (`GET_LOCK`, per database) instead, and a run that fails half-way leaves the statements it applied —
30
+ * each of them is one the next run would plan again, so the next boot completes it. And the application account gets
31
+ * its rights once for the database (`SELECT, INSERT, UPDATE, DELETE ON db.*`), which covers every table the framework
32
+ * creates later, instead of per table.
33
+ */
34
+
35
+ export interface MysqlSchemaOptions {
36
+ /** The application account as MySQL names it (`'user'@'host'`, `mysqlAccount()`) */
37
+ appAccount: string;
38
+ variant: MysqlVariant;
39
+ }
40
+
41
+ const SYSTEM: SqlTenantScope = { kind: 'system' };
42
+ /** One lock per database, shorter than GET_LOCK's 64 characters whatever the database is called */
43
+ const LOCK_NAME = "CONCAT('lenne.tech:schema:', SHA1(DATABASE()))";
44
+ /** How long a boot waits for another replica's schema run, in seconds */
45
+ const LOCK_TIMEOUT_SECONDS = 120;
46
+ /** The rights the application account needs, and the only ones it may hold on the framework's tables */
47
+ const DML = ['DELETE', 'INSERT', 'SELECT', 'UPDATE'];
48
+ /** Rights that let an account change or drop what the framework created, or hand rights on */
49
+ const FORBIDDEN = new Set([
50
+ 'ALTER',
51
+ 'ALTER ROUTINE',
52
+ 'CREATE',
53
+ 'CREATE ROUTINE',
54
+ 'CREATE USER',
55
+ 'CREATE VIEW',
56
+ 'DROP',
57
+ 'GRANT OPTION',
58
+ 'INDEX',
59
+ 'REFERENCES',
60
+ 'SUPER',
61
+ 'SYSTEM_USER',
62
+ 'TRIGGER',
63
+ ]);
64
+ /** Lowest supported servers — the versions the framework is tested against */
65
+ export const MIN_MYSQL_VERSION = [8, 4] as const;
66
+ export const MIN_MARIADB_VERSION = [11, 8] as const;
67
+
68
+ type Run = (statement: SqlStatement) => Promise<SqlQueryResult<any>>;
69
+
70
+ interface CatalogTable {
71
+ checks: Set<string>;
72
+ columns: Map<string, { collation: null | string; generated: boolean; type: string }>;
73
+ /** framework-named index → unique */
74
+ indexes: Map<string, boolean>;
75
+ }
76
+
77
+ interface Catalog {
78
+ database: string;
79
+ /** Whether the application account holds every DML right on the database */
80
+ granted: boolean;
81
+ tables: Map<string, CatalogTable>;
82
+ }
83
+
84
+ /** `'user'@'host'` of the account a connection runs as */
85
+ export async function mysqlAccount(executor: SqlExecutor): Promise<string> {
86
+ const { rows } = await executor.run<{ account: string }>(
87
+ { params: [], text: 'SELECT CURRENT_USER() AS account' },
88
+ SYSTEM,
89
+ );
90
+ const account = rows[0].account;
91
+ const at = account.lastIndexOf('@');
92
+ return `'${account.slice(0, at)}'@'${account.slice(at + 1)}'`;
93
+ }
94
+
95
+ /** `fn` on one owner connection holding the schema lock — the boot's evolution and `runSqlMigration()` alike */
96
+ export async function withMysqlSchemaLock<T>(owner: SqlExecutor, fn: (run: Run) => Promise<T>): Promise<T> {
97
+ return owner.transaction(async (tx) => {
98
+ const run: Run = (statement) => tx.run(statement, SYSTEM);
99
+ const { rows } = await run({ params: [LOCK_TIMEOUT_SECONDS], text: `SELECT GET_LOCK(${LOCK_NAME}, $1) AS locked` });
100
+ if (Number(rows[0]?.locked) !== 1) {
101
+ throw new Error(`Timed out after ${LOCK_TIMEOUT_SECONDS}s waiting for the schema lock of another process`);
102
+ }
103
+ try {
104
+ return await fn(run);
105
+ } finally {
106
+ // Session-scoped: never left to the pool, where it would block every later run
107
+ await run({ params: [], text: `SELECT RELEASE_LOCK(${LOCK_NAME})` }).catch(() => undefined);
108
+ }
109
+ });
110
+ }
111
+
112
+ /** Apply every automatic change as the OWNER, under the schema lock; refuse when a migration is needed. */
113
+ export async function applyMysqlSchema(
114
+ owner: SqlExecutor,
115
+ models: ModelDescriptor[],
116
+ options: MysqlSchemaOptions,
117
+ ): Promise<SchemaChange[]> {
118
+ return withMysqlSchemaLock(owner, async (run) => {
119
+ const changes = await planMysqlSchema(run, models, options);
120
+ const migrations = changes.filter((change) => change.kind === 'migration');
121
+ if (migrations.length) {
122
+ throw new SchemaMigrationRequiredError(migrations);
123
+ }
124
+ for (const change of changes) {
125
+ if (change.kind === 'automatic') {
126
+ for (const text of change.statements) {
127
+ try {
128
+ await run({ params: [], text });
129
+ } catch (error) {
130
+ // Without a transaction the statements before this one stay applied; say which change stopped the run
131
+ throw new Error(`Schema change "${change.description}" failed: ${(error as Error).message}`, {
132
+ cause: error,
133
+ });
134
+ }
135
+ }
136
+ }
137
+ }
138
+ return changes;
139
+ });
140
+ }
141
+
142
+ /** Without an owner connection: only check, as the APPLICATION account, and refuse to start on any pending change. */
143
+ export async function verifyMysqlSchema(
144
+ app: SqlExecutor,
145
+ models: ModelDescriptor[],
146
+ options: MysqlSchemaOptions,
147
+ ): Promise<SchemaChange[]> {
148
+ const changes = await planMysqlSchema((statement) => app.run(statement, SYSTEM), models, options);
149
+ const pending = changes.filter((change) => change.kind !== 'notice');
150
+ if (pending.length) {
151
+ throw new SchemaOutOfDateError(pending);
152
+ }
153
+ return changes;
154
+ }
155
+
156
+ export async function planMysqlSchema(
157
+ run: Run,
158
+ models: ModelDescriptor[],
159
+ options: MysqlSchemaOptions,
160
+ ): Promise<SchemaChange[]> {
161
+ const all = models.some((model) => model.name === LOCK_MODEL.name) ? models : [...models, LOCK_MODEL];
162
+ const tables = all.map((model) => desiredMysqlTable(model, options.variant));
163
+ const catalog = await readCatalog(
164
+ run,
165
+ tables.map((table) => table.name),
166
+ options.appAccount,
167
+ );
168
+ const changes: SchemaChange[] = [];
169
+ if (!catalog.granted) {
170
+ changes.push({
171
+ description: `grant ${options.appAccount} SELECT, INSERT, UPDATE, DELETE on database ${catalog.database}`,
172
+ kind: 'automatic',
173
+ statements: [
174
+ `GRANT SELECT, INSERT, UPDATE, DELETE ON ${quoteMysqlIdentifier(catalog.database)}.* TO ${options.appAccount}`,
175
+ ],
176
+ });
177
+ }
178
+ for (const table of tables) {
179
+ for (const notice of table.notices) {
180
+ changes.push({ description: notice, kind: 'notice', statements: [], table: table.name });
181
+ }
182
+ const existing = catalog.tables.get(table.name);
183
+ changes.push(...(existing ? planExistingTable(table, existing) : planNewTable(table)));
184
+ }
185
+ return changes;
186
+ }
187
+
188
+ function planNewTable(table: MysqlDesiredTable): SchemaChange[] {
189
+ return [
190
+ {
191
+ description: `create table ${table.name} (${table.model.name})`,
192
+ kind: 'automatic',
193
+ statements: [createMysqlTableStatement(table), ...table.indexes.map((index) => index.create)],
194
+ table: table.name,
195
+ },
196
+ ];
197
+ }
198
+
199
+ function planExistingTable(table: MysqlDesiredTable, existing: CatalogTable): SchemaChange[] {
200
+ const changes: SchemaChange[] = [];
201
+ const name = table.name;
202
+ const quoted = quoteMysqlIdentifier(name);
203
+ const declared = new Set<string>();
204
+ // The null sentinels of a NEW unique index belong to that index's migration: added on their own, the boot that
205
+ // refuses the index would never get to them, and the suggested CREATE INDEX would name a column that does not exist
206
+ const deferred = new Set(
207
+ table.indexes
208
+ .filter((index) => index.unique && !existing.indexes.has(index.name))
209
+ .flatMap((index) => index.sentinels ?? [])
210
+ .filter((sentinel) => !existing.columns.has(sentinel)),
211
+ );
212
+
213
+ for (const column of table.columns) {
214
+ declared.add(column.name);
215
+ const current = existing.columns.get(column.name);
216
+ if (!current && deferred.has(column.name)) {
217
+ continue;
218
+ }
219
+ if (!current) {
220
+ const previous = column.renamedFrom ? existing.columns.get(column.renamedFrom) : undefined;
221
+ if (previous) {
222
+ declared.add(column.renamedFrom);
223
+ changes.push({
224
+ description: `rename ${name}.${column.renamedFrom} to ${column.name} (declared renamedFrom)`,
225
+ kind: 'automatic',
226
+ statements: [
227
+ `ALTER TABLE ${quoted} RENAME COLUMN ${quoteMysqlIdentifier(column.renamedFrom)} TO ${quoteMysqlIdentifier(column.name)}`,
228
+ ],
229
+ table: name,
230
+ });
231
+ if (!sameType(column, previous)) {
232
+ changes.push(typeChange(name, column, previous));
233
+ }
234
+ continue;
235
+ }
236
+ changes.push({
237
+ description: `add ${column.generated ? 'virtual ' : ''}column ${name}.${column.name}`,
238
+ kind: 'automatic',
239
+ statements: [`ALTER TABLE ${quoted} ADD COLUMN ${mysqlColumnDefinition({ ...column, primaryKey: false })}`],
240
+ table: name,
241
+ });
242
+ continue;
243
+ }
244
+ if (column.renamedFrom && existing.columns.has(column.renamedFrom)) {
245
+ declared.add(column.renamedFrom);
246
+ changes.push({
247
+ description: `${name}.${column.name} is declared as renamed from ${column.renamedFrom}, but both columns exist — move the data and drop the old column in a migration`,
248
+ kind: 'migration',
249
+ statements: [],
250
+ table: name,
251
+ });
252
+ }
253
+ if (!column.generated && !sameType(column, current)) {
254
+ changes.push(typeChange(name, column, current));
255
+ }
256
+ }
257
+ for (const column of existing.columns.keys()) {
258
+ if (!declared.has(column) && !column.startsWith(NULL_SENTINEL_PREFIX) && !isForeignColumn(name, column)) {
259
+ changes.push({
260
+ description: `${name}.${column} is no longer declared; the column is kept until a migration drops it`,
261
+ kind: 'notice',
262
+ statements: [],
263
+ table: name,
264
+ });
265
+ }
266
+ }
267
+
268
+ for (const check of table.checks) {
269
+ if (!existing.checks.has(check.name)) {
270
+ changes.push({
271
+ description: `add check ${check.name} on ${name}`,
272
+ kind: 'automatic',
273
+ statements: [addMysqlCheckStatement(name, check)],
274
+ table: name,
275
+ });
276
+ }
277
+ }
278
+
279
+ const wanted = new Set(table.indexes.map((index) => index.name));
280
+ const added = new Set<string>();
281
+ for (const index of table.indexes) {
282
+ if (existing.indexes.has(index.name)) {
283
+ continue;
284
+ }
285
+ const sentinels = (index.sentinels ?? []).filter((sentinel) => deferred.has(sentinel) && !added.has(sentinel));
286
+ sentinels.forEach((sentinel) => added.add(sentinel));
287
+ changes.push({
288
+ description: `create ${index.unique ? 'unique ' : ''}index ${index.name} on ${name}`,
289
+ // A unique index can fail on the rows already stored, and it changes what may be written: a reviewed decision
290
+ kind: index.unique ? 'migration' : 'automatic',
291
+ statements: [
292
+ ...sentinels.map(
293
+ (sentinel) =>
294
+ `ALTER TABLE ${quoted} ADD COLUMN ${mysqlColumnDefinition(table.columns.find((column) => column.name === sentinel)!)}`,
295
+ ),
296
+ index.create,
297
+ ],
298
+ table: name,
299
+ });
300
+ }
301
+ for (const [index] of existing.indexes) {
302
+ if (!wanted.has(index)) {
303
+ changes.push({
304
+ description: `index ${index} on ${name} is no longer declared; it is kept until a migration drops it`,
305
+ kind: 'notice',
306
+ statements: [],
307
+ table: name,
308
+ });
309
+ }
310
+ }
311
+ return changes;
312
+ }
313
+
314
+ function sameType(column: MysqlDesiredColumn, current: { collation: null | string; type: string }): boolean {
315
+ if (column.type !== current.type) {
316
+ return false;
317
+ }
318
+ // Text compares byte-wise or not at all the way MongoDB does; JSON's collation is the server's business
319
+ const text = !column.json && ['char(36)', 'longtext', 'varchar(255)'].includes(column.type);
320
+ return !text || current.collation === 'utf8mb4_bin';
321
+ }
322
+
323
+ function typeChange(
324
+ table: string,
325
+ column: MysqlDesiredColumn,
326
+ current: { collation: null | string; type: string },
327
+ ): SchemaChange {
328
+ return {
329
+ description: `${table}.${column.name} is ${current.type}${current.collation ? ` COLLATE ${current.collation}` : ''}, the model asks for ${mysqlColumnDefinition({ ...column, default: undefined, primaryKey: false }).replace(/^`[^`]+` /, '')}`,
330
+ kind: 'migration',
331
+ statements: [
332
+ `ALTER TABLE ${quoteMysqlIdentifier(table)} MODIFY COLUMN ${mysqlColumnDefinition({ ...column, primaryKey: false })}`,
333
+ ],
334
+ table,
335
+ };
336
+ }
337
+
338
+ /** A catalog column type in the form the compiler writes: no display width (MariaDB prints `bigint(20)`) */
339
+ export function mysqlCatalogType(type: string): string {
340
+ const lower = type.toLowerCase().trim();
341
+ return lower === 'tinyint(1)' ? lower : lower.replace(/^(bigint|int|mediumint|smallint|tinyint)\(\d+\)/, '$1');
342
+ }
343
+
344
+ async function readCatalog(run: Run, tables: string[], appAccount: string): Promise<Catalog> {
345
+ const list = tables.map((_table, index) => `$${index + 1}`).join(', ');
346
+ const database = (await run({ params: [], text: 'SELECT DATABASE() AS name' })).rows[0]?.name;
347
+ if (!database) {
348
+ throw new Error('The MySQL / MariaDB connection URL names no database');
349
+ }
350
+ const columnResult = await run({
351
+ params: tables,
352
+ text: `SELECT TABLE_NAME AS t, COLUMN_NAME AS c, COLUMN_TYPE AS type, COLLATION_NAME AS collation, EXTRA AS extra
353
+ FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN (${list})`,
354
+ });
355
+ const indexResult = await run({
356
+ params: tables,
357
+ text: `SELECT DISTINCT TABLE_NAME AS t, INDEX_NAME AS name, NON_UNIQUE AS non_unique
358
+ FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN (${list})
359
+ AND (INDEX_NAME LIKE 'ix\\_%' OR INDEX_NAME LIKE 'ux\\_%')`,
360
+ });
361
+ const checkResult = await run({
362
+ params: tables,
363
+ text: `SELECT TABLE_NAME AS t, CONSTRAINT_NAME AS name FROM information_schema.TABLE_CONSTRAINTS
364
+ WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME IN (${list}) AND CONSTRAINT_TYPE = 'CHECK'`,
365
+ });
366
+ const grantResult = await run({
367
+ params: [appAccount],
368
+ text: `SELECT PRIVILEGE_TYPE AS privilege FROM information_schema.SCHEMA_PRIVILEGES
369
+ WHERE GRANTEE = $1 AND TABLE_SCHEMA = DATABASE()`,
370
+ });
371
+
372
+ const catalog: Catalog = {
373
+ database,
374
+ granted: DML.every((privilege) => grantResult.rows.some((row) => row.privilege === privilege)),
375
+ tables: new Map(),
376
+ };
377
+ const table = (name: string) => {
378
+ let entry = catalog.tables.get(name);
379
+ if (!entry) {
380
+ entry = { checks: new Set(), columns: new Map(), indexes: new Map() };
381
+ catalog.tables.set(name, entry);
382
+ }
383
+ return entry;
384
+ };
385
+ for (const row of columnResult.rows) {
386
+ table(row.t).columns.set(row.c, {
387
+ collation: row.collation ?? null,
388
+ generated: /GENERATED/i.test(row.extra ?? ''),
389
+ type: mysqlCatalogType(row.type),
390
+ });
391
+ }
392
+ for (const row of indexResult.rows) {
393
+ table(row.t).indexes.set(row.name, Number(row.non_unique) === 0);
394
+ }
395
+ for (const row of checkResult.rows) {
396
+ table(row.t).checks.add(row.name);
397
+ }
398
+ return catalog;
399
+ }
400
+
401
+ /**
402
+ * The boot check of the APPLICATION connection (plan §3.9, phase 6): with no row-level security, the framework's tables
403
+ * and their constraints (the roles CHECK, the unique indexes) are what the store's policies rely on, so the account the
404
+ * application runs as may read and write rows and nothing else — no right to change, drop or index a table, no trigger,
405
+ * no granting. Also refuses a server older than the tested versions.
406
+ */
407
+ export async function assertSafeMysqlApplicationAccount(app: SqlExecutor, variant: MysqlVariant): Promise<void> {
408
+ const { rows } = await app.run<{ version: string }>({ params: [], text: 'SELECT VERSION() AS version' }, SYSTEM);
409
+ const version = rows[0].version;
410
+ const isMariaDb = /mariadb/i.test(version);
411
+ if (isMariaDb !== (variant === 'mariadb')) {
412
+ throw new UnsafeDatabaseRoleError(
413
+ `The URL names ${variantLabel(variant)}, but the server is ${isMariaDb ? 'MariaDB' : 'MySQL'} ${version} — use the ${isMariaDb ? 'mariadb' : 'mysql'}:// scheme`,
414
+ );
415
+ }
416
+ const [major, minor] = version.split(/[.-]/).map(Number);
417
+ const [needMajor, needMinor] = isMariaDb ? MIN_MARIADB_VERSION : MIN_MYSQL_VERSION;
418
+ if (major < needMajor || (major === needMajor && minor < needMinor)) {
419
+ throw new UnsafeDatabaseRoleError(
420
+ `${variantLabel(variant)} ${version} is not supported; version ${needMajor}.${needMinor} or newer is required`,
421
+ );
422
+ }
423
+
424
+ const account = await mysqlAccount(app);
425
+ const privileges = await app.run<{ grantable: string; privilege: string; scope: string }>(
426
+ {
427
+ params: [account],
428
+ text: `SELECT PRIVILEGE_TYPE AS privilege, IS_GRANTABLE AS grantable, 'global' AS scope
429
+ FROM information_schema.USER_PRIVILEGES WHERE GRANTEE = $1
430
+ UNION ALL SELECT PRIVILEGE_TYPE, IS_GRANTABLE, 'database' FROM information_schema.SCHEMA_PRIVILEGES
431
+ WHERE GRANTEE = $1 AND TABLE_SCHEMA = DATABASE()
432
+ UNION ALL SELECT PRIVILEGE_TYPE, IS_GRANTABLE, CONCAT('table ', TABLE_NAME) FROM information_schema.TABLE_PRIVILEGES
433
+ WHERE GRANTEE = $1 AND TABLE_SCHEMA = DATABASE()`,
434
+ },
435
+ SYSTEM,
436
+ );
437
+ const problems = new Set<string>();
438
+ for (const row of privileges.rows) {
439
+ if (FORBIDDEN.has(row.privilege)) {
440
+ problems.add(`${row.privilege} (${row.scope})`);
441
+ }
442
+ if (row.grantable === 'YES') {
443
+ problems.add(`the right to grant ${row.privilege} (${row.scope})`);
444
+ }
445
+ }
446
+ if (problems.size) {
447
+ throw new UnsafeDatabaseRoleError(
448
+ `The application account ${account} holds ${[...problems].sort().join(', ')}. Without row-level security the ` +
449
+ 'framework relies on its tables and constraints staying as they are: connect `database.url` as an account ' +
450
+ 'that may only SELECT, INSERT, UPDATE and DELETE, and give the owner account to `database.ownerUrl`.',
451
+ );
452
+ }
453
+ }
@@ -0,0 +1,131 @@
1
+ import type { SqlQueryResult, SqlStatement } from '../sql-executor.interface.js';
2
+
3
+ /**
4
+ * Connection-level rules for MySQL 8.4 and MariaDB 11.8, shared by every SQL engine (plan phase 6).
5
+ *
6
+ * Neither database has row-level security, so no tenant scope travels with a statement: the store's before-layer and
7
+ * its row check after every read are the whole tenant isolation there (plan §3.4). What every connection needs instead
8
+ * is a fixed session, set once when the pool opens it and inherited by the engines' native APIs on the same pool.
9
+ */
10
+
11
+ /** Which of the two servers a source is — they share one dialect and differ in a few functions */
12
+ export type MysqlVariant = 'mariadb' | 'mysql';
13
+
14
+ /**
15
+ * The session every connection gets.
16
+ *
17
+ * - `sql_mode` is set in full, not amended: strict, so a value too long for a column is refused instead of cut, and
18
+ * WITHOUT `NO_BACKSLASH_ESCAPES` — the driver escapes parameters with backslashes on the client, and a server that
19
+ * reads a backslash literally would let a crafted value end its string (`ANSI_QUOTES` and `PIPES_AS_CONCAT` stay out
20
+ * for the same reason: the compilers rely on the default meaning of `"` and `||`)
21
+ * - `time_zone`: UTC, so the server's clock and the stored instants agree with the driver's (`timezone: 'Z'`)
22
+ * - `group_concat_max_len`: the store rebuilds JSON arrays with `GROUP_CONCAT`, which MySQL caps at 1024 bytes
23
+ */
24
+ export const MYSQL_SESSION_SQL =
25
+ "SET SESSION sql_mode = 'STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY', " +
26
+ "time_zone = '+00:00', group_concat_max_len = 4294967295";
27
+
28
+ /** Options the driver needs for the values the store reads back as the descriptor types them */
29
+ export function mysqlConnectionOptions(url: string, maxConnections: number): Record<string, unknown> {
30
+ return {
31
+ connectionLimit: maxConnections,
32
+ dateStrings: false,
33
+ // Instants are written and read as UTC; the session's time_zone agrees
34
+ timezone: 'Z',
35
+ uri: url,
36
+ // BIGINT and DECIMAL arrive as strings, never rounded to a double
37
+ bigNumberStrings: true,
38
+ decimalNumbers: false,
39
+ supportBigNumbers: true,
40
+ // One statement per call: a parameter can never smuggle a second one in
41
+ multipleStatements: false,
42
+ };
43
+ }
44
+
45
+ /**
46
+ * Turn the compilers' positional placeholders (`$1`, `$2`, …, shared with PostgreSQL) into the driver's `?`, with the
47
+ * values in the order the placeholders appear — a placeholder may repeat or appear out of order. Text inside quotes
48
+ * (`'…'`, `"…"`, `` `…` ``) is copied as it is: a JSON path literal such as `'$[*]'` is not a placeholder.
49
+ */
50
+ export function toMysqlStatement(statement: SqlStatement): { sql: string; values: unknown[] } {
51
+ const { parts, values } = mysqlStatementParts(statement);
52
+ return { sql: parts.join('?'), values };
53
+ }
54
+
55
+ /**
56
+ * The statement split at its placeholders: `parts` has one entry more than `values`, and `parts.join('?')` is the
57
+ * driver's text. For an engine that binds values itself between text fragments (Drizzle).
58
+ */
59
+ export function mysqlStatementParts(statement: SqlStatement): { parts: string[]; values: unknown[] } {
60
+ const { params, text } = statement;
61
+ const values: unknown[] = [];
62
+ const parts: string[] = [];
63
+ let sql = '';
64
+ let quote: null | string = null;
65
+ for (let i = 0; i < text.length; i++) {
66
+ const char = text[i];
67
+ if (quote) {
68
+ sql += char;
69
+ if (char === '\\' && quote !== '`' && i + 1 < text.length) {
70
+ sql += text[++i];
71
+ } else if (char === quote) {
72
+ if (text[i + 1] === quote) {
73
+ sql += text[++i];
74
+ } else {
75
+ quote = null;
76
+ }
77
+ }
78
+ continue;
79
+ }
80
+ if (char === "'" || char === '"' || char === '`') {
81
+ quote = char;
82
+ sql += char;
83
+ continue;
84
+ }
85
+ if (char === '$' && /\d/.test(text[i + 1] ?? '')) {
86
+ let digits = '';
87
+ while (/\d/.test(text[i + 1] ?? '')) {
88
+ digits += text[++i];
89
+ }
90
+ const index = Number(digits) - 1;
91
+ if (index < 0 || index >= params.length) {
92
+ throw new Error(`Statement references parameter $${digits}, but only ${params.length} were bound`);
93
+ }
94
+ values.push(driverValue(params[index]));
95
+ parts.push(sql);
96
+ sql = '';
97
+ continue;
98
+ }
99
+ sql += char;
100
+ }
101
+ parts.push(sql);
102
+ return { parts, values };
103
+ }
104
+
105
+ /**
106
+ * A value as the driver must receive it. The driver expands an array into a list and an object into `key = value`
107
+ * pairs — never wanted here: the compilers bind JSON as text. Refusing them keeps a compiler mistake from changing what a
108
+ * statement means.
109
+ */
110
+ function driverValue(value: unknown): unknown {
111
+ if (value === undefined) {
112
+ return null;
113
+ }
114
+ if (typeof value === 'bigint') {
115
+ return value.toString();
116
+ }
117
+ if (value === null || typeof value !== 'object' || value instanceof Date || Buffer.isBuffer(value)) {
118
+ return value;
119
+ }
120
+ throw new TypeError('A MySQL statement parameter must be a scalar, a Date or a Buffer — bind JSON as text');
121
+ }
122
+
123
+ /** A driver result as the executor port returns it: rows for a query, the matched-row count for a write */
124
+ export function mysqlResult<R>(result: unknown): SqlQueryResult<R> {
125
+ if (Array.isArray(result)) {
126
+ return { rowCount: result.length, rows: result as R[] };
127
+ }
128
+ // A write: `affectedRows` counts MATCHED rows (the driver sets CLIENT_FOUND_ROWS), as PostgreSQL's row count does
129
+ const affected = (result as { affectedRows?: unknown } | undefined)?.affectedRows;
130
+ return { rowCount: typeof affected === 'number' ? affected : 0, rows: [] };
131
+ }