@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.
- package/.claude/rules/architecture.md +6 -1
- package/.claude/rules/better-auth.md +46 -0
- package/.claude/rules/configurable-features.md +3 -2
- package/.claude/rules/package-management.md +24 -2
- package/.claude/rules/persistence.md +100 -0
- package/.claude/rules/role-system.md +9 -0
- package/.claude/rules/testing.md +116 -18
- package/CLAUDE.md +21 -2
- package/FRAMEWORK-API.md +6 -4
- package/README.md +106 -34
- package/dist/core/common/decorators/unified-field.decorator.d.ts +2 -1
- package/dist/core/common/decorators/unified-field.decorator.js +4 -1
- package/dist/core/common/decorators/unified-field.decorator.js.map +1 -1
- package/dist/core/common/filters/mongoose-cast-error.filter.d.ts +7 -5
- package/dist/core/common/filters/mongoose-cast-error.filter.js +3 -2
- package/dist/core/common/filters/mongoose-cast-error.filter.js.map +1 -1
- package/dist/core/common/helpers/db.helper.d.ts +2 -1
- package/dist/core/common/helpers/db.helper.js +32 -26
- package/dist/core/common/helpers/db.helper.js.map +1 -1
- package/dist/core/common/helpers/decorator.helper.d.ts +1 -1
- package/dist/core/common/helpers/filter.helper.d.ts +2 -1
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/helpers/gridfs.helper.d.ts +4 -4
- package/dist/core/common/helpers/gridfs.helper.js +14 -6
- package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
- package/dist/core/common/helpers/id.helper.d.ts +4 -1
- package/dist/core/common/helpers/id.helper.js +10 -4
- package/dist/core/common/helpers/id.helper.js.map +1 -1
- package/dist/core/common/helpers/model.helper.js +5 -5
- package/dist/core/common/helpers/model.helper.js.map +1 -1
- package/dist/core/common/helpers/service.helper.js +3 -3
- package/dist/core/common/helpers/service.helper.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +18 -2
- package/dist/core/common/interfaces/service-options.interface.d.ts +2 -2
- package/dist/core/common/models/core-persistence.model.d.ts +1 -2
- package/dist/core/common/models/core-persistence.model.js +3 -3
- package/dist/core/common/models/core-persistence.model.js.map +1 -1
- package/dist/core/common/persistence/core-persistence.lifecycle.d.ts +9 -0
- package/dist/core/common/persistence/core-persistence.lifecycle.js +38 -0
- package/dist/core/common/persistence/core-persistence.lifecycle.js.map +1 -0
- package/dist/core/common/persistence/core-persistence.module.d.ts +9 -0
- package/dist/core/common/persistence/core-persistence.module.js +76 -0
- package/dist/core/common/persistence/core-persistence.module.js.map +1 -0
- package/dist/core/common/persistence/data-source.config.d.ts +33 -0
- package/dist/core/common/persistence/data-source.config.js +151 -0
- package/dist/core/common/persistence/data-source.config.js.map +1 -0
- package/dist/core/common/persistence/data-source.runtime.d.ts +45 -0
- package/dist/core/common/persistence/data-source.runtime.js +278 -0
- package/dist/core/common/persistence/data-source.runtime.js.map +1 -0
- package/dist/core/common/persistence/data-store.interface.d.ts +73 -0
- package/dist/core/common/persistence/data-store.interface.js +2 -0
- package/dist/core/common/persistence/data-store.interface.js.map +1 -0
- package/dist/core/common/persistence/expiry-sweep.d.ts +12 -0
- package/dist/core/common/persistence/expiry-sweep.js +55 -0
- package/dist/core/common/persistence/expiry-sweep.js.map +1 -0
- package/dist/core/common/persistence/id-format.d.ts +3 -0
- package/dist/core/common/persistence/id-format.js +21 -0
- package/dist/core/common/persistence/id-format.js.map +1 -0
- package/dist/core/common/persistence/infrastructure-locks.d.ts +13 -0
- package/dist/core/common/persistence/infrastructure-locks.js +35 -0
- package/dist/core/common/persistence/infrastructure-locks.js.map +1 -0
- package/dist/core/common/persistence/inject-store.decorator.d.ts +1 -0
- package/dist/core/common/persistence/inject-store.decorator.js +6 -0
- package/dist/core/common/persistence/inject-store.decorator.js.map +1 -0
- package/dist/core/common/persistence/lock-store.interface.d.ts +5 -0
- package/dist/core/common/persistence/lock-store.interface.js +2 -0
- package/dist/core/common/persistence/lock-store.interface.js.map +1 -0
- package/dist/core/common/persistence/model-descriptor.interface.d.ts +36 -0
- package/dist/core/common/persistence/model-descriptor.interface.js +2 -0
- package/dist/core/common/persistence/model-descriptor.interface.js.map +1 -0
- package/dist/core/common/persistence/model-metadata.registry.d.ts +14 -0
- package/dist/core/common/persistence/model-metadata.registry.js +194 -0
- package/dist/core/common/persistence/model-metadata.registry.js.map +1 -0
- package/dist/core/common/persistence/mongo/collection-name.d.ts +2 -0
- package/dist/core/common/persistence/mongo/collection-name.js +73 -0
- package/dist/core/common/persistence/mongo/collection-name.js.map +1 -0
- package/dist/core/common/persistence/mongo/declared-schema.view.d.ts +11 -0
- package/dist/core/common/persistence/mongo/declared-schema.view.js +292 -0
- package/dist/core/common/persistence/mongo/declared-schema.view.js.map +1 -0
- package/dist/core/common/persistence/mongo/hex-object-id.d.ts +13 -0
- package/dist/core/common/persistence/mongo/hex-object-id.js +54 -0
- package/dist/core/common/persistence/mongo/hex-object-id.js.map +1 -0
- package/dist/core/common/persistence/mongo/model-declarations.d.ts +35 -0
- package/dist/core/common/persistence/mongo/model-declarations.js +80 -0
- package/dist/core/common/persistence/mongo/model-declarations.js.map +1 -0
- package/dist/core/common/persistence/mongo/mongo-packages.d.ts +15 -0
- package/dist/core/common/persistence/mongo/mongo-packages.js +66 -0
- package/dist/core/common/persistence/mongo/mongo-packages.js.map +1 -0
- package/dist/core/common/persistence/mongo/mongoose-compat.d.ts +22 -0
- package/dist/core/common/persistence/mongo/mongoose-compat.js +65 -0
- package/dist/core/common/persistence/mongo/mongoose-compat.js.map +1 -0
- package/dist/core/common/persistence/mongo/no-mongo-connection.module.d.ts +2 -0
- package/dist/core/common/persistence/mongo/no-mongo-connection.module.js +19 -0
- package/dist/core/common/persistence/mongo/no-mongo-connection.module.js.map +1 -0
- package/dist/core/common/persistence/mongo-lock-store.d.ts +21 -0
- package/dist/core/common/persistence/mongo-lock-store.js +72 -0
- package/dist/core/common/persistence/mongo-lock-store.js.map +1 -0
- package/dist/core/common/persistence/mongoose-data-store.d.ts +33 -0
- package/dist/core/common/persistence/mongoose-data-store.js +187 -0
- package/dist/core/common/persistence/mongoose-data-store.js.map +1 -0
- package/dist/core/common/persistence/neutral-populate.d.ts +6 -0
- package/dist/core/common/persistence/neutral-populate.js +72 -0
- package/dist/core/common/persistence/neutral-populate.js.map +1 -0
- package/dist/core/common/persistence/persisted-model.decorator.d.ts +6 -0
- package/dist/core/common/persistence/persisted-model.decorator.js +24 -0
- package/dist/core/common/persistence/persisted-model.decorator.js.map +1 -0
- package/dist/core/common/persistence/persistence-runtime.registry.d.ts +61 -0
- package/dist/core/common/persistence/persistence-runtime.registry.js +47 -0
- package/dist/core/common/persistence/persistence-runtime.registry.js.map +1 -0
- package/dist/core/common/persistence/persistence.tokens.d.ts +1 -0
- package/dist/core/common/persistence/persistence.tokens.js +4 -0
- package/dist/core/common/persistence/persistence.tokens.js.map +1 -0
- package/dist/core/common/persistence/policies/audit.policy.d.ts +8 -0
- package/dist/core/common/persistence/policies/audit.policy.js +37 -0
- package/dist/core/common/persistence/policies/audit.policy.js.map +1 -0
- package/dist/core/common/persistence/policies/password.policy.d.ts +3 -0
- package/dist/core/common/persistence/policies/password.policy.js +46 -0
- package/dist/core/common/persistence/policies/password.policy.js.map +1 -0
- package/dist/core/common/persistence/policies/role-guard.policy.d.ts +3 -0
- package/dist/core/common/persistence/policies/role-guard.policy.js +46 -0
- package/dist/core/common/persistence/policies/role-guard.policy.js.map +1 -0
- package/dist/core/common/persistence/policies/system-role.policy.d.ts +5 -0
- package/dist/core/common/persistence/policies/system-role.policy.js +46 -0
- package/dist/core/common/persistence/policies/system-role.policy.js.map +1 -0
- package/dist/core/common/persistence/policies/tenant.policy.d.ts +19 -0
- package/dist/core/common/persistence/policies/tenant.policy.js +120 -0
- package/dist/core/common/persistence/policies/tenant.policy.js.map +1 -0
- package/dist/core/common/persistence/routed-model.guard.d.ts +4 -0
- package/dist/core/common/persistence/routed-model.guard.js +73 -0
- package/dist/core/common/persistence/routed-model.guard.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.d.ts +46 -0
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.js +350 -0
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-executor.d.ts +13 -0
- package/dist/core/common/persistence/sql/mysql/mysql-executor.js +194 -0
- package/dist/core/common/persistence/sql/mysql/mysql-executor.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-lock-store.d.ts +11 -0
- package/dist/core/common/persistence/sql/mysql/mysql-lock-store.js +55 -0
- package/dist/core/common/persistence/sql/mysql/mysql-lock-store.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.d.ts +36 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js +288 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.d.ts +19 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js +328 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-session.d.ts +13 -0
- package/dist/core/common/persistence/sql/mysql/mysql-session.js +85 -0
- package/dist/core/common/persistence/sql/mysql/mysql-session.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.d.ts +9 -0
- package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.js +264 -0
- package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.d.ts +20 -0
- package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.js +519 -0
- package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-lock-store.d.ts +11 -0
- package/dist/core/common/persistence/sql/postgres/postgres-lock-store.js +44 -0
- package/dist/core/common/persistence/sql/postgres/postgres-lock-store.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.d.ts +42 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js +220 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.d.ts +12 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js +315 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.d.ts +5 -0
- package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.js +225 -0
- package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.d.ts +13 -0
- package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.js +484 -0
- package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-cast.d.ts +2 -0
- package/dist/core/common/persistence/sql/sql-cast.js +194 -0
- package/dist/core/common/persistence/sql/sql-cast.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-data-store.d.ts +79 -0
- package/dist/core/common/persistence/sql/sql-data-store.js +592 -0
- package/dist/core/common/persistence/sql/sql-data-store.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-dialect.d.ts +20 -0
- package/dist/core/common/persistence/sql/sql-dialect.js +38 -0
- package/dist/core/common/persistence/sql/sql-dialect.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-errors.d.ts +17 -0
- package/dist/core/common/persistence/sql/sql-errors.js +25 -0
- package/dist/core/common/persistence/sql/sql-errors.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-executor.factory.d.ts +11 -0
- package/dist/core/common/persistence/sql/sql-executor.factory.js +199 -0
- package/dist/core/common/persistence/sql/sql-executor.factory.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-executor.interface.d.ts +32 -0
- package/dist/core/common/persistence/sql/sql-executor.interface.js +2 -0
- package/dist/core/common/persistence/sql/sql-executor.interface.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-naming.d.ts +15 -0
- package/dist/core/common/persistence/sql/sql-naming.js +90 -0
- package/dist/core/common/persistence/sql/sql-naming.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-schema.shared.d.ts +25 -0
- package/dist/core/common/persistence/sql/sql-schema.shared.js +69 -0
- package/dist/core/common/persistence/sql/sql-schema.shared.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-session.d.ts +6 -0
- package/dist/core/common/persistence/sql/sql-session.js +78 -0
- package/dist/core/common/persistence/sql/sql-session.js.map +1 -0
- package/dist/core/common/persistence/sql/where-shared.d.ts +18 -0
- package/dist/core/common/persistence/sql/where-shared.js +93 -0
- package/dist/core/common/persistence/sql/where-shared.js.map +1 -0
- package/dist/core/common/persistence/store-guards.d.ts +10 -0
- package/dist/core/common/persistence/store-guards.js +49 -0
- package/dist/core/common/persistence/store-guards.js.map +1 -0
- package/dist/core/common/persistence/store-upsert.d.ts +2 -0
- package/dist/core/common/persistence/store-upsert.js +20 -0
- package/dist/core/common/persistence/store-upsert.js.map +1 -0
- package/dist/core/common/persistence/unavailable-store.d.ts +2 -0
- package/dist/core/common/persistence/unavailable-store.js +53 -0
- package/dist/core/common/persistence/unavailable-store.js.map +1 -0
- package/dist/core/common/persistence/unsupported-capability.error.d.ts +3 -0
- package/dist/core/common/persistence/unsupported-capability.error.js +4 -0
- package/dist/core/common/persistence/unsupported-capability.error.js.map +1 -0
- package/dist/core/common/plugins/mongoose-audit-fields.plugin.js +24 -68
- package/dist/core/common/plugins/mongoose-audit-fields.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-id.plugin.js +3 -0
- package/dist/core/common/plugins/mongoose-id.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-password.plugin.d.ts +1 -3
- package/dist/core/common/plugins/mongoose-password.plugin.js +2 -45
- package/dist/core/common/plugins/mongoose-password.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-role-guard.plugin.js +5 -46
- package/dist/core/common/plugins/mongoose-role-guard.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-system-role.plugin.js +2 -43
- package/dist/core/common/plugins/mongoose-system-role.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-tenant.plugin.js +10 -70
- package/dist/core/common/plugins/mongoose-tenant.plugin.js.map +1 -1
- package/dist/core/common/scalars/upload.scalar.js +1 -1
- package/dist/core/common/scalars/upload.scalar.js.map +1 -1
- package/dist/core/common/services/core-cron-jobs.initializer.js +1 -1
- package/dist/core/common/services/core-cron-jobs.initializer.js.map +1 -1
- package/dist/core/common/services/core-cron-jobs.service.d.ts +1 -0
- package/dist/core/common/services/core-cron-jobs.service.js +23 -14
- package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
- package/dist/core/common/services/crud.service.d.ts +4 -1
- package/dist/core/common/services/crud.service.js +132 -23
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/common/services/model-doc.service.js +1 -1
- package/dist/core/common/services/model-doc.service.js.map +1 -1
- package/dist/core/common/services/module.service.d.ts +9 -2
- package/dist/core/common/services/module.service.js +51 -6
- package/dist/core/common/services/module.service.js.map +1 -1
- package/dist/core/common/types/field-selection.type.d.ts +1 -1
- package/dist/core/common/types/id.type.d.ts +4 -4
- package/dist/core/common/types/object-id-like.type.d.ts +3 -0
- package/dist/core/common/types/object-id-like.type.js +2 -0
- package/dist/core/common/types/object-id-like.type.js.map +1 -0
- package/dist/core/common/types/populate-config.type.d.ts +1 -1
- package/dist/core/common/types/string-or-object-id.type.d.ts +2 -2
- package/dist/core/modules/ai/core-ai.constants.d.ts +4 -0
- package/dist/core/modules/ai/core-ai.constants.js +4 -0
- package/dist/core/modules/ai/core-ai.constants.js.map +1 -1
- package/dist/core/modules/ai/core-ai.module.js +21 -17
- package/dist/core/modules/ai/core-ai.module.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-budget-limit.model.d.ts +2 -92
- package/dist/core/modules/ai/models/core-ai-budget-limit.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-budget-limit.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-connection-preference.model.d.ts +2 -87
- package/dist/core/modules/ai/models/core-ai-connection-preference.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-connection-preference.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-connection.model.d.ts +2 -177
- package/dist/core/modules/ai/models/core-ai-connection.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-connection.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-conversation.model.d.ts +2 -92
- package/dist/core/modules/ai/models/core-ai-conversation.model.js +3 -4
- package/dist/core/modules/ai/models/core-ai-conversation.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-interaction.model.d.ts +2 -120
- package/dist/core/modules/ai/models/core-ai-interaction.model.js +2 -3
- package/dist/core/modules/ai/models/core-ai-interaction.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.d.ts +3 -0
- package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.js +21 -0
- package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.js.map +1 -0
- package/dist/core/modules/ai/models/core-ai-mode.model.d.ts +2 -102
- package/dist/core/modules/ai/models/core-ai-mode.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-mode.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-prompt-hint.model.d.ts +2 -97
- package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-prompt.model.d.ts +2 -112
- package/dist/core/modules/ai/models/core-ai-prompt.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-prompt.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-slot.model.d.ts +2 -112
- package/dist/core/modules/ai/models/core-ai-slot.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-slot.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-tool-grant.model.d.ts +2 -97
- package/dist/core/modules/ai/models/core-ai-tool-grant.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-tool-grant.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-tool-policy.model.d.ts +2 -103
- package/dist/core/modules/ai/models/core-ai-tool-policy.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-tool-policy.model.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-budget.service.d.ts +3 -1
- package/dist/core/modules/ai/services/core-ai-budget.service.js +15 -5
- package/dist/core/modules/ai/services/core-ai-budget.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-connection-preference.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-connection-preference.service.js +6 -10
- package/dist/core/modules/ai/services/core-ai-connection-preference.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-connection.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-connection.service.js +20 -42
- package/dist/core/modules/ai/services/core-ai-connection.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-conversation.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-conversation.service.js +28 -29
- package/dist/core/modules/ai/services/core-ai-conversation.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-interaction.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-interaction.service.js +3 -4
- package/dist/core/modules/ai/services/core-ai-interaction.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.d.ts +8 -0
- package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js +70 -18
- package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-mode.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-mode.service.js +3 -7
- package/dist/core/modules/ai/services/core-ai-mode.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-prompt-hint.service.d.ts +8 -1
- package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js +32 -26
- package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-prompt.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-prompt.service.js +10 -13
- package/dist/core/modules/ai/services/core-ai-prompt.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-slot.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-slot.service.js +14 -25
- package/dist/core/modules/ai/services/core-ai-slot.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-tool-grant.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-tool-grant.service.js +6 -18
- package/dist/core/modules/ai/services/core-ai-tool-grant.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-tool-policy.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-tool-policy.service.js +4 -8
- package/dist/core/modules/ai/services/core-ai-tool-policy.service.js.map +1 -1
- package/dist/core/modules/api-token/core-api-token.model.js +1 -1
- package/dist/core/modules/api-token/core-api-token.model.js.map +1 -1
- package/dist/core/modules/api-token/core-api-token.module.js +3 -2
- package/dist/core/modules/api-token/core-api-token.module.js.map +1 -1
- package/dist/core/modules/api-token/core-api-token.service.d.ts +8 -2
- package/dist/core/modules/api-token/core-api-token.service.js +106 -39
- package/dist/core/modules/api-token/core-api-token.service.js.map +1 -1
- package/dist/core/modules/auth/core-auth.module.js +2 -0
- package/dist/core/modules/auth/core-auth.module.js.map +1 -1
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js +1 -2
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js.map +1 -1
- package/dist/core/modules/auth/guards/role-guard.token.d.ts +1 -0
- package/dist/core/modules/auth/guards/role-guard.token.js +2 -0
- package/dist/core/modules/auth/guards/role-guard.token.js.map +1 -0
- package/dist/core/modules/auth/services/core-auth.service.js +4 -2
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-sql.helper.d.ts +6 -0
- package/dist/core/modules/better-auth/better-auth-sql.helper.js +113 -0
- package/dist/core/modules/better-auth/better-auth-sql.helper.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth-token.service.d.ts +3 -1
- package/dist/core/modules/better-auth/better-auth-token.service.js +15 -24
- package/dist/core/modules/better-auth/better-auth-token.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.config.d.ts +7 -0
- package/dist/core/modules/better-auth/better-auth.config.js +16 -5
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.d.ts +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +1 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +6 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.js +30 -15
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-mongo.users.d.ts +10 -0
- package/dist/core/modules/better-auth/core-better-auth-mongo.users.js +24 -0
- package/dist/core/modules/better-auth/core-better-auth-mongo.users.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.registry.d.ts +3 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.registry.js +8 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.registry.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.store.d.ts +71 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.store.js +190 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.store.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.d.ts +24 -1
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +308 -32
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.d.ts +2 -0
- package/dist/core/modules/better-auth/core-better-auth.module.js +54 -32
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.d.ts +7 -2
- package/dist/core/modules/better-auth/core-better-auth.service.js +61 -9
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- package/dist/core/modules/file/core-file-info.model.d.ts +1 -2
- package/dist/core/modules/file/core-file-info.model.js +2 -2
- package/dist/core/modules/file/core-file-info.model.js.map +1 -1
- package/dist/core/modules/file/core-file.service.d.ts +5 -3
- package/dist/core/modules/file/core-file.service.js +16 -9
- package/dist/core/modules/file/core-file.service.js.map +1 -1
- package/dist/core/modules/file/file-metadata.helper.d.ts +1 -1
- package/dist/core/modules/file/file-metadata.helper.js +2 -2
- package/dist/core/modules/file/file-metadata.helper.js.map +1 -1
- package/dist/core/modules/file/file-metadata.models.d.ts +35 -0
- package/dist/core/modules/file/file-metadata.models.js +20 -0
- package/dist/core/modules/file/file-metadata.models.js.map +1 -0
- package/dist/core/modules/file/file-metadata.store.d.ts +6 -0
- package/dist/core/modules/file/file-metadata.store.js +77 -0
- package/dist/core/modules/file/file-metadata.store.js.map +1 -0
- package/dist/core/modules/file/file-storage.helper.d.ts +1 -0
- package/dist/core/modules/file/file-storage.helper.js +34 -0
- package/dist/core/modules/file/file-storage.helper.js.map +1 -1
- package/dist/core/modules/file/filesystem-file.helper.d.ts +1 -1
- package/dist/core/modules/file/filesystem-file.helper.js +4 -4
- package/dist/core/modules/file/filesystem-file.helper.js.map +1 -1
- package/dist/core/modules/file/s3-file.helper.d.ts +1 -1
- package/dist/core/modules/file/s3-file.helper.js +5 -5
- package/dist/core/modules/file/s3-file.helper.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.module.js +12 -2
- package/dist/core/modules/health-check/core-health-check.module.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.service.d.ts +4 -3
- package/dist/core/modules/health-check/core-health-check.service.js +26 -5
- package/dist/core/modules/health-check/core-health-check.service.js.map +1 -1
- package/dist/core/modules/hub/core-hub.controller.d.ts +1 -0
- package/dist/core/modules/hub/core-hub.controller.js +10 -0
- package/dist/core/modules/hub/core-hub.controller.js.map +1 -1
- package/dist/core/modules/hub/core-hub.service.js +1 -1
- package/dist/core/modules/hub/core-hub.service.js.map +1 -1
- package/dist/core/modules/hub/helpers/hub-client-js.helper.js +23 -0
- package/dist/core/modules/hub/helpers/hub-client-js.helper.js.map +1 -1
- package/dist/core/modules/hub/hub-action-messages.d.ts +2 -0
- package/dist/core/modules/hub/hub-action-messages.js +2 -0
- package/dist/core/modules/hub/hub-action-messages.js.map +1 -1
- package/dist/core/modules/hub/hub-nav.js +1 -0
- package/dist/core/modules/hub/hub-nav.js.map +1 -1
- package/dist/core/modules/hub/interfaces/hub-panels.interface.d.ts +17 -1
- package/dist/core/modules/hub/services/core-hub-db.service.d.ts +6 -1
- package/dist/core/modules/hub/services/core-hub-db.service.js +16 -14
- package/dist/core/modules/hub/services/core-hub-db.service.js.map +1 -1
- package/dist/core/modules/hub/services/core-hub-migrations.service.d.ts +5 -0
- package/dist/core/modules/hub/services/core-hub-migrations.service.js +74 -1
- package/dist/core/modules/hub/services/core-hub-migrations.service.js.map +1 -1
- package/dist/core/modules/hub/services/core-hub-sources.service.d.ts +2 -1
- package/dist/core/modules/hub/services/core-hub-sources.service.js +32 -0
- package/dist/core/modules/hub/services/core-hub-sources.service.js.map +1 -1
- package/dist/core/modules/hub/services/hub-query-profiler.service.js +1 -1
- package/dist/core/modules/hub/services/hub-query-profiler.service.js.map +1 -1
- package/dist/core/modules/migrate/cli/migrate-cli.d.ts +2 -0
- package/dist/core/modules/migrate/cli/migrate-cli.js +35 -1
- package/dist/core/modules/migrate/cli/migrate-cli.js.map +1 -1
- package/dist/core/modules/migrate/index.d.ts +3 -0
- package/dist/core/modules/migrate/index.js +3 -0
- package/dist/core/modules/migrate/index.js.map +1 -1
- package/dist/core/modules/migrate/migration-runner.d.ts +2 -2
- package/dist/core/modules/migrate/migration-runner.js.map +1 -1
- package/dist/core/modules/migrate/migration-state-store.interface.d.ts +16 -0
- package/dist/core/modules/migrate/migration-state-store.interface.js +2 -0
- package/dist/core/modules/migrate/migration-state-store.interface.js.map +1 -0
- package/dist/core/modules/migrate/migration.helper.d.ts +3 -2
- package/dist/core/modules/migrate/migration.helper.js +21 -6
- package/dist/core/modules/migrate/migration.helper.js.map +1 -1
- package/dist/core/modules/migrate/mongo-state-store.d.ts +5 -12
- package/dist/core/modules/migrate/mongo-state-store.js +30 -24
- package/dist/core/modules/migrate/mongo-state-store.js.map +1 -1
- package/dist/core/modules/migrate/sql-migration.helper.d.ts +4 -0
- package/dist/core/modules/migrate/sql-migration.helper.js +34 -0
- package/dist/core/modules/migrate/sql-migration.helper.js.map +1 -0
- package/dist/core/modules/migrate/sql-state-store.d.ts +24 -0
- package/dist/core/modules/migrate/sql-state-store.js +129 -0
- package/dist/core/modules/migrate/sql-state-store.js.map +1 -0
- package/dist/core/modules/system-setup/core-system-setup.service.d.ts +8 -0
- package/dist/core/modules/system-setup/core-system-setup.service.js +41 -25
- package/dist/core/modules/system-setup/core-system-setup.service.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant-member.model.js +1 -1
- package/dist/core/modules/tenant/core-tenant-member.model.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant-member.store.d.ts +2 -0
- package/dist/core/modules/tenant/core-tenant-member.store.js +6 -0
- package/dist/core/modules/tenant/core-tenant-member.store.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.guard.d.ts +8 -3
- package/dist/core/modules/tenant/core-tenant.guard.js +57 -28
- package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.module.js +3 -2
- package/dist/core/modules/tenant/core-tenant.module.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.service.d.ts +3 -1
- package/dist/core/modules/tenant/core-tenant.service.js +48 -28
- package/dist/core/modules/tenant/core-tenant.service.js.map +1 -1
- package/dist/core/modules/tus/core-tus.service.d.ts +1 -1
- package/dist/core/modules/tus/core-tus.service.js +8 -7
- package/dist/core/modules/tus/core-tus.service.js.map +1 -1
- package/dist/core/modules/tus/tus.module.js +1 -1
- package/dist/core/modules/tus/tus.module.js.map +1 -1
- package/dist/core/modules/user/core-user.model.d.ts +1 -1
- package/dist/core/modules/user/core-user.model.js +1 -1
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/core/modules/user/core-user.service.d.ts +3 -1
- package/dist/core/modules/user/core-user.service.js +71 -16
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core.module.js +39 -5
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +26 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -1
- package/dist/server/common/models/persistence.model.d.ts +1 -1
- package/dist/server/common/models/persistence.model.js +3 -3
- package/dist/server/common/models/persistence.model.js.map +1 -1
- package/dist/server/modules/file/file-info.model.d.ts +1 -77
- package/dist/server/modules/file/file-info.model.js +1 -1
- package/dist/server/modules/file/file-info.model.js.map +1 -1
- package/dist/server/modules/file/file.service.js +1 -1
- package/dist/server/modules/file/file.service.js.map +1 -1
- package/dist/server/modules/user/user.model.d.ts +2 -186
- package/dist/server/modules/user/user.model.js +4 -5
- package/dist/server/modules/user/user.model.js.map +1 -1
- package/dist/server/modules/user/user.module.js +4 -3
- package/dist/server/modules/user/user.module.js.map +1 -1
- package/dist/server/modules/user/user.service.d.ts +1 -1
- package/dist/server/modules/user/user.service.js +5 -8
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/test/test.helper.js +2 -2
- package/dist/test/test.helper.js.map +1 -1
- package/dist/types/graphql-upload.d.ts +10 -7
- package/docs/REQUEST-LIFECYCLE.md +6 -3
- package/docs/choosing-a-database.md +107 -0
- package/docs/native-driver-security.md +29 -0
- package/docs/security-overrides.md +15 -6
- package/migration-guides/12.0.x-to-12.1.x.md +255 -0
- package/package.json +75 -29
- package/src/core/common/decorators/unified-field.decorator.ts +11 -1
- package/src/core/common/filters/mongoose-cast-error.filter.ts +12 -6
- package/src/core/common/helpers/db.helper.ts +40 -25
- package/src/core/common/helpers/decorator.helper.ts +1 -1
- package/src/core/common/helpers/filter.helper.ts +2 -1
- package/src/core/common/helpers/gridfs.helper.ts +28 -9
- package/src/core/common/helpers/id.helper.ts +21 -4
- package/src/core/common/helpers/model.helper.ts +5 -6
- package/src/core/common/helpers/service.helper.ts +3 -3
- package/src/core/common/interfaces/server-options.interface.ts +118 -10
- package/src/core/common/interfaces/service-options.interface.ts +2 -2
- package/src/core/common/models/core-persistence.model.ts +3 -3
- package/src/core/common/persistence/core-persistence.lifecycle.ts +47 -0
- package/src/core/common/persistence/core-persistence.module.ts +109 -0
- package/src/core/common/persistence/data-source.config.ts +271 -0
- package/src/core/common/persistence/data-source.runtime.ts +351 -0
- package/src/core/common/persistence/data-store.interface.ts +155 -0
- package/src/core/common/persistence/expiry-sweep.ts +105 -0
- package/src/core/common/persistence/id-format.ts +43 -0
- package/src/core/common/persistence/infrastructure-locks.ts +66 -0
- package/src/core/common/persistence/inject-store.decorator.ts +16 -0
- package/src/core/common/persistence/lock-store.interface.ts +17 -0
- package/src/core/common/persistence/model-descriptor.interface.ts +90 -0
- package/src/core/common/persistence/model-metadata.registry.ts +285 -0
- package/src/core/common/persistence/mongo/collection-name.ts +87 -0
- package/src/core/common/persistence/mongo/declared-schema.view.ts +378 -0
- package/src/core/common/persistence/mongo/hex-object-id.ts +75 -0
- package/src/core/common/persistence/mongo/model-declarations.ts +135 -0
- package/src/core/common/persistence/mongo/mongo-packages.ts +130 -0
- package/src/core/common/persistence/mongo/mongoose-compat.ts +129 -0
- package/src/core/common/persistence/mongo/no-mongo-connection.module.ts +18 -0
- package/src/core/common/persistence/mongo-lock-store.ts +121 -0
- package/src/core/common/persistence/mongoose-data-store.ts +232 -0
- package/src/core/common/persistence/neutral-populate.ts +98 -0
- package/src/core/common/persistence/persisted-model.decorator.ts +61 -0
- package/src/core/common/persistence/persistence-runtime.registry.ts +152 -0
- package/src/core/common/persistence/persistence.tokens.ts +9 -0
- package/src/core/common/persistence/policies/audit.policy.ts +80 -0
- package/src/core/common/persistence/policies/password.policy.ts +69 -0
- package/src/core/common/persistence/policies/role-guard.policy.ts +74 -0
- package/src/core/common/persistence/policies/system-role.policy.ts +90 -0
- package/src/core/common/persistence/policies/tenant.policy.ts +245 -0
- package/src/core/common/persistence/routed-model.guard.ts +107 -0
- package/src/core/common/persistence/sql/mysql/mysql-data-store.ts +503 -0
- package/src/core/common/persistence/sql/mysql/mysql-executor.ts +281 -0
- package/src/core/common/persistence/sql/mysql/mysql-lock-store.ts +87 -0
- package/src/core/common/persistence/sql/mysql/mysql-schema.compiler.ts +424 -0
- package/src/core/common/persistence/sql/mysql/mysql-schema.migrator.ts +453 -0
- package/src/core/common/persistence/sql/mysql/mysql-session.ts +131 -0
- package/src/core/common/persistence/sql/mysql/mysql-update.compiler.ts +379 -0
- package/src/core/common/persistence/sql/mysql/mysql-where.compiler.ts +686 -0
- package/src/core/common/persistence/sql/postgres/postgres-lock-store.ts +76 -0
- package/src/core/common/persistence/sql/postgres/postgres-schema.compiler.ts +328 -0
- package/src/core/common/persistence/sql/postgres/postgres-schema.migrator.ts +448 -0
- package/src/core/common/persistence/sql/postgres/postgres-update.compiler.ts +310 -0
- package/src/core/common/persistence/sql/postgres/postgres-where.compiler.ts +638 -0
- package/src/core/common/persistence/sql/sql-cast.ts +227 -0
- package/src/core/common/persistence/sql/sql-data-store.ts +762 -0
- package/src/core/common/persistence/sql/sql-dialect.ts +85 -0
- package/src/core/common/persistence/sql/sql-errors.ts +49 -0
- package/src/core/common/persistence/sql/sql-executor.factory.ts +282 -0
- package/src/core/common/persistence/sql/sql-executor.interface.ts +57 -0
- package/src/core/common/persistence/sql/sql-naming.ts +133 -0
- package/src/core/common/persistence/sql/sql-schema.shared.ts +105 -0
- package/src/core/common/persistence/sql/sql-session.ts +158 -0
- package/src/core/common/persistence/sql/where-shared.ts +118 -0
- package/src/core/common/persistence/store-guards.ts +73 -0
- package/src/core/common/persistence/store-upsert.ts +36 -0
- package/src/core/common/persistence/unavailable-store.ts +63 -0
- package/src/core/common/persistence/unsupported-capability.error.ts +7 -0
- package/src/core/common/plugins/mongoose-audit-fields.plugin.ts +33 -74
- package/src/core/common/plugins/mongoose-id.plugin.ts +9 -0
- package/src/core/common/plugins/mongoose-password.plugin.ts +6 -62
- package/src/core/common/plugins/mongoose-role-guard.plugin.ts +11 -63
- package/src/core/common/plugins/mongoose-system-role.plugin.ts +7 -78
- package/src/core/common/plugins/mongoose-tenant.plugin.ts +23 -144
- package/src/core/common/scalars/upload.scalar.ts +8 -3
- package/src/core/common/services/core-cron-jobs.initializer.ts +1 -1
- package/src/core/common/services/core-cron-jobs.service.ts +33 -22
- package/src/core/common/services/crud.service.ts +166 -35
- package/src/core/common/services/model-doc.service.ts +1 -1
- package/src/core/common/services/module.service.ts +78 -6
- package/src/core/common/types/field-selection.type.ts +1 -1
- package/src/core/common/types/id.type.ts +2 -2
- package/src/core/common/types/object-id-like.type.ts +11 -0
- package/src/core/common/types/populate-config.type.ts +1 -1
- package/src/core/common/types/string-or-object-id.type.ts +2 -2
- package/src/core/modules/ai/README.md +15 -2
- package/src/core/modules/ai/core-ai.constants.ts +10 -0
- package/src/core/modules/ai/core-ai.module.ts +32 -17
- package/src/core/modules/ai/models/core-ai-budget-limit.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-connection-preference.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-connection.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-conversation.model.ts +8 -4
- package/src/core/modules/ai/models/core-ai-interaction.model.ts +3 -3
- package/src/core/modules/ai/models/core-ai-mcp-oauth.models.ts +46 -0
- package/src/core/modules/ai/models/core-ai-mode.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-prompt-hint.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-prompt.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-slot.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-tool-grant.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-tool-policy.model.ts +2 -2
- package/src/core/modules/ai/services/core-ai-budget.service.ts +22 -4
- package/src/core/modules/ai/services/core-ai-connection-preference.service.ts +6 -13
- package/src/core/modules/ai/services/core-ai-connection.service.ts +34 -44
- package/src/core/modules/ai/services/core-ai-conversation.service.ts +31 -29
- package/src/core/modules/ai/services/core-ai-interaction.service.ts +3 -3
- package/src/core/modules/ai/services/core-ai-mcp-oauth.service.ts +93 -20
- package/src/core/modules/ai/services/core-ai-mode.service.ts +3 -6
- package/src/core/modules/ai/services/core-ai-prompt-hint.service.ts +43 -26
- package/src/core/modules/ai/services/core-ai-prompt.service.ts +15 -12
- package/src/core/modules/ai/services/core-ai-slot.service.ts +20 -24
- package/src/core/modules/ai/services/core-ai-tool-grant.service.ts +17 -27
- package/src/core/modules/ai/services/core-ai-tool-policy.service.ts +7 -10
- package/src/core/modules/api-token/core-api-token.model.ts +1 -1
- package/src/core/modules/api-token/core-api-token.module.ts +4 -2
- package/src/core/modules/api-token/core-api-token.service.ts +118 -43
- package/src/core/modules/auth/core-auth.module.ts +2 -0
- package/src/core/modules/auth/guards/legacy-auth-rate-limit.guard.ts +4 -3
- package/src/core/modules/auth/guards/role-guard.token.ts +7 -0
- package/src/core/modules/auth/services/core-auth.service.ts +16 -2
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +1 -1
- package/src/core/modules/better-auth/README.md +10 -1
- package/src/core/modules/better-auth/better-auth-sql.helper.ts +191 -0
- package/src/core/modules/better-auth/better-auth-token.service.ts +26 -35
- package/src/core/modules/better-auth/better-auth.config.ts +43 -7
- package/src/core/modules/better-auth/better-auth.types.ts +1 -1
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +13 -1
- package/src/core/modules/better-auth/core-better-auth-challenge.service.ts +36 -18
- package/src/core/modules/better-auth/core-better-auth-mongo.users.ts +35 -0
- package/src/core/modules/better-auth/core-better-auth-sql.registry.ts +20 -0
- package/src/core/modules/better-auth/core-better-auth-sql.store.ts +309 -0
- package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +418 -40
- package/src/core/modules/better-auth/core-better-auth.module.ts +71 -35
- package/src/core/modules/better-auth/core-better-auth.service.ts +81 -12
- package/src/core/modules/file/README.md +16 -3
- package/src/core/modules/file/core-file-info.model.ts +2 -2
- package/src/core/modules/file/core-file.service.ts +27 -18
- package/src/core/modules/file/file-metadata.helper.ts +7 -3
- package/src/core/modules/file/file-metadata.models.ts +44 -0
- package/src/core/modules/file/file-metadata.store.ts +109 -0
- package/src/core/modules/file/file-storage.helper.ts +47 -2
- package/src/core/modules/file/filesystem-file.helper.ts +11 -8
- package/src/core/modules/file/s3-file.helper.ts +11 -7
- package/src/core/modules/health-check/core-health-check.module.ts +16 -2
- package/src/core/modules/health-check/core-health-check.service.ts +25 -3
- package/src/core/modules/hub/README.md +20 -11
- package/src/core/modules/hub/core-hub.controller.ts +5 -0
- package/src/core/modules/hub/core-hub.service.ts +1 -1
- package/src/core/modules/hub/helpers/hub-client-js.helper.ts +23 -0
- package/src/core/modules/hub/hub-action-messages.ts +6 -0
- package/src/core/modules/hub/hub-nav.ts +1 -0
- package/src/core/modules/hub/interfaces/hub-panels.interface.ts +8 -1
- package/src/core/modules/hub/services/core-hub-db.service.ts +35 -17
- package/src/core/modules/hub/services/core-hub-migrations.service.ts +96 -2
- package/src/core/modules/hub/services/core-hub-sources.service.ts +47 -1
- package/src/core/modules/hub/services/hub-query-profiler.service.ts +1 -1
- package/src/core/modules/migrate/README.md +54 -0
- package/src/core/modules/migrate/cli/migrate-cli.ts +44 -3
- package/src/core/modules/migrate/index.ts +3 -0
- package/src/core/modules/migrate/migration-runner.ts +3 -2
- package/src/core/modules/migrate/migration-state-store.interface.ts +24 -0
- package/src/core/modules/migrate/migration.helper.ts +35 -10
- package/src/core/modules/migrate/mongo-state-store.ts +64 -65
- package/src/core/modules/migrate/sql-migration.helper.ts +48 -0
- package/src/core/modules/migrate/sql-state-store.ts +198 -0
- package/src/core/modules/system-setup/README.md +14 -2
- package/src/core/modules/system-setup/core-system-setup.service.ts +77 -45
- package/src/core/modules/tenant/README.md +9 -2
- package/src/core/modules/tenant/core-tenant-member.model.ts +1 -1
- package/src/core/modules/tenant/core-tenant-member.store.ts +13 -0
- package/src/core/modules/tenant/core-tenant.guard.ts +77 -24
- package/src/core/modules/tenant/core-tenant.module.ts +6 -3
- package/src/core/modules/tenant/core-tenant.service.ts +59 -42
- package/src/core/modules/tus/core-tus.service.ts +11 -12
- package/src/core/modules/tus/tus.module.ts +1 -1
- package/src/core/modules/user/core-user.model.ts +2 -2
- package/src/core/modules/user/core-user.service.ts +98 -20
- package/src/core.module.ts +60 -5
- package/src/index.ts +26 -0
- package/src/server/common/models/persistence.model.ts +4 -4
- package/src/server/modules/file/file-info.model.ts +1 -1
- package/src/server/modules/file/file.service.ts +1 -1
- package/src/server/modules/user/user.model.ts +10 -5
- package/src/server/modules/user/user.module.ts +9 -3
- package/src/server/modules/user/user.service.ts +9 -11
- package/src/test/test.helper.ts +2 -2
- package/src/types/graphql-upload.d.ts +10 -7
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Inject, Injectable, Logger, Optional } from '@nestjs/common';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { type Connection, Types } from 'mongoose';
|
|
2
|
+
import type * as mongo from 'mongodb';
|
|
3
|
+
import type { Connection } from 'mongoose';
|
|
5
4
|
|
|
6
5
|
import { ConfigService } from '../../../common/services/config.service.js';
|
|
7
6
|
import { CoreS3Service } from '../../../common/services/core-s3.service.js';
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
FILESYSTEM_FILES_COLLECTION,
|
|
12
11
|
FilesystemFileHelper,
|
|
13
12
|
} from '../../file/filesystem-file.helper.js';
|
|
13
|
+
import { fileMetadataCollection } from '../../file/file-metadata.store.js';
|
|
14
14
|
import { S3_FILES_COLLECTION, S3FileHelper } from '../../file/s3-file.helper.js';
|
|
15
15
|
import { HubActionMessage } from '../hub-action-messages.js';
|
|
16
16
|
import { HUB_CONFIG } from '../hub.constants.js';
|
|
@@ -24,6 +24,12 @@ import {
|
|
|
24
24
|
HubUnavailable,
|
|
25
25
|
} from '../interfaces/hub-panels.interface.js';
|
|
26
26
|
import type { ResolvedHubConfig } from '../interfaces/hub-config.interface.js';
|
|
27
|
+
import {
|
|
28
|
+
createGridFsBucket,
|
|
29
|
+
InjectConnection,
|
|
30
|
+
isValidObjectId,
|
|
31
|
+
newObjectId,
|
|
32
|
+
} from '../../../common/persistence/mongo/mongoose-compat.js';
|
|
27
33
|
|
|
28
34
|
/**
|
|
29
35
|
* Read-only MongoDB introspection for the DB, Models/ERD and Files panels.
|
|
@@ -123,10 +129,10 @@ export class CoreHubDbService {
|
|
|
123
129
|
if (!db) {
|
|
124
130
|
throw new Error(HubActionMessage.mongoUnavailable);
|
|
125
131
|
}
|
|
126
|
-
if (!
|
|
132
|
+
if (!isValidObjectId(id)) {
|
|
127
133
|
throw new Error(HubActionMessage.invalidFileId);
|
|
128
134
|
}
|
|
129
|
-
const objectId =
|
|
135
|
+
const objectId = newObjectId(id);
|
|
130
136
|
|
|
131
137
|
// Same probe order as `CoreFileService.deleteFile()`: S3, then filesystem, then GridFS as the
|
|
132
138
|
// fallthrough. Keeping the two in step matters — a Hub that resolved a file differently from the
|
|
@@ -134,7 +140,7 @@ export class CoreHubDbService {
|
|
|
134
140
|
let store: HubFileStore | undefined;
|
|
135
141
|
let doc: any;
|
|
136
142
|
for (const candidate of this.fileStores(bucket)) {
|
|
137
|
-
const [found] = await
|
|
143
|
+
const [found] = await this.fileCollection(candidate).find({ _id: objectId }, { limit: 1 }).toArray();
|
|
138
144
|
if (found) {
|
|
139
145
|
doc = found;
|
|
140
146
|
store = candidate.store;
|
|
@@ -150,7 +156,11 @@ export class CoreHubDbService {
|
|
|
150
156
|
|
|
151
157
|
switch (store) {
|
|
152
158
|
case 'filesystem': {
|
|
153
|
-
await FilesystemFileHelper.deleteFile(
|
|
159
|
+
await FilesystemFileHelper.deleteFile(
|
|
160
|
+
this.filesystemDir,
|
|
161
|
+
fileMetadataCollection(this.connection, 'filesystem'),
|
|
162
|
+
objectId,
|
|
163
|
+
);
|
|
154
164
|
break;
|
|
155
165
|
}
|
|
156
166
|
case 's3': {
|
|
@@ -158,11 +168,11 @@ export class CoreHubDbService {
|
|
|
158
168
|
if (!this.s3Service?.enabled) {
|
|
159
169
|
throw new Error(HubActionMessage.s3Unavailable);
|
|
160
170
|
}
|
|
161
|
-
await S3FileHelper.deleteFile(this.s3Service,
|
|
171
|
+
await S3FileHelper.deleteFile(this.s3Service, fileMetadataCollection(this.connection, 's3'), objectId);
|
|
162
172
|
break;
|
|
163
173
|
}
|
|
164
174
|
default: {
|
|
165
|
-
const gridFs =
|
|
175
|
+
const gridFs = createGridFsBucket(db as unknown as mongo.Db, { bucketName: bucket });
|
|
166
176
|
await gridFs.delete(objectId as unknown as mongo.ObjectId);
|
|
167
177
|
}
|
|
168
178
|
}
|
|
@@ -173,9 +183,9 @@ export class CoreHubDbService {
|
|
|
173
183
|
/**
|
|
174
184
|
* File inventory across ALL THREE metadata stores.
|
|
175
185
|
*
|
|
176
|
-
* Metadata
|
|
177
|
-
* `filesystem-files
|
|
178
|
-
* `CoreFileService.findFileInfo()` does
|
|
186
|
+
* Metadata is queryable whichever store holds the bytes (`fs.files` / `s3-files` /
|
|
187
|
+
* `filesystem-files`, the latter two as tables when `database` routes them to a SQL source), so the
|
|
188
|
+
* panel reads all three the way `CoreFileService.findFileInfo()` does (`fileCollection()`).
|
|
179
189
|
*
|
|
180
190
|
* It used to read `fs.files` alone. Under `file.storage: 's3'` or `'filesystem'` that made the
|
|
181
191
|
* panel report **0 files** — not "this panel does not cover your driver", but a confident wrong
|
|
@@ -209,11 +219,9 @@ export class CoreHubDbService {
|
|
|
209
219
|
|
|
210
220
|
for (const source of this.fileStores(bucket)) {
|
|
211
221
|
try {
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
.toArray();
|
|
216
|
-
const count = await db.collection(source.collection).countDocuments();
|
|
222
|
+
const collection = this.fileCollection(source);
|
|
223
|
+
const docs = await collection.find({}, { limit: window, sort: { uploadDate: -1 } }).toArray();
|
|
224
|
+
const count = await collection.countDocuments();
|
|
217
225
|
stores.push({ collection: source.collection, count, store: source.store });
|
|
218
226
|
for (const doc of docs) {
|
|
219
227
|
rows.push({
|
|
@@ -255,6 +263,16 @@ export class CoreHubDbService {
|
|
|
255
263
|
* GridFS is last because it is the fallthrough: its collection name depends on the bucket, and a
|
|
256
264
|
* document there carries no `storage` marker to identify it by.
|
|
257
265
|
*/
|
|
266
|
+
/**
|
|
267
|
+
* The metadata of one store as `CoreFileService` reads it: S3 and filesystem metadata follow `database` to a SQL
|
|
268
|
+
* table when their model is routed there; GridFS keeps `<bucket>.files` in MongoDB
|
|
269
|
+
*/
|
|
270
|
+
protected fileCollection(source: { collection: string; store: HubFileStore }): mongo.Collection<any> {
|
|
271
|
+
return source.store === 'gridfs'
|
|
272
|
+
? this.connection.db.collection(source.collection)
|
|
273
|
+
: fileMetadataCollection(this.connection, source.store);
|
|
274
|
+
}
|
|
275
|
+
|
|
258
276
|
protected fileStores(bucket: string): { collection: string; store: HubFileStore }[] {
|
|
259
277
|
return [
|
|
260
278
|
{ collection: S3_FILES_COLLECTION, store: 's3' },
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { Inject, Injectable, Logger, Optional } from '@nestjs/common';
|
|
2
|
-
import { InjectConnection } from '
|
|
2
|
+
import { InjectConnection } from '../../../common/persistence/mongo/mongoose-compat.js';
|
|
3
3
|
import { readdir } from 'fs/promises';
|
|
4
4
|
import type { Connection } from 'mongoose';
|
|
5
5
|
import { resolve } from 'path';
|
|
6
6
|
|
|
7
7
|
import { ConfigService } from '../../../common/services/config.service.js';
|
|
8
8
|
import { DEFAULT_MIGRATION_FILE_PATTERN, MigrationRunner } from '../../migrate/migration-runner.js';
|
|
9
|
+
import type { DatabaseSqlEngine } from '../../../common/interfaces/server-options.interface.js';
|
|
10
|
+
import { getPersistenceRuntime } from '../../../common/persistence/persistence-runtime.registry.js';
|
|
9
11
|
import { MongoStateStore } from '../../migrate/mongo-state-store.js';
|
|
12
|
+
import { SqlStateStore } from '../../migrate/sql-state-store.js';
|
|
10
13
|
import { HubActionMessage } from '../hub-action-messages.js';
|
|
11
14
|
import { HUB_CONFIG } from '../hub.constants.js';
|
|
12
15
|
import { HubMigrationsData, HubUnavailable } from '../interfaces/hub-panels.interface.js';
|
|
@@ -31,6 +34,7 @@ export class CoreHubMigrationsService {
|
|
|
31
34
|
|
|
32
35
|
/** Run all pending migrations. Returns the titles that were applied. */
|
|
33
36
|
async runPending(): Promise<{ ran: string[] }> {
|
|
37
|
+
await this.assertSingleMigrationState();
|
|
34
38
|
const runner = this.buildRunner();
|
|
35
39
|
const before = new Set(((await this.getStatus()) as HubMigrationsData).completed ?? []);
|
|
36
40
|
await runner.up();
|
|
@@ -40,6 +44,7 @@ export class CoreHubMigrationsService {
|
|
|
40
44
|
|
|
41
45
|
/** Roll back the most recently applied migration. Returns the title that was reverted. */
|
|
42
46
|
async rollbackLast(): Promise<{ rolledBack?: string }> {
|
|
47
|
+
await this.assertSingleMigrationState();
|
|
43
48
|
const before = ((await this.getStatus()) as HubMigrationsData).completed ?? [];
|
|
44
49
|
const runner = this.buildRunner();
|
|
45
50
|
await runner.down();
|
|
@@ -47,11 +52,18 @@ export class CoreHubMigrationsService {
|
|
|
47
52
|
return { rolledBack: before.find((title) => !after.has(title)) };
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
/** Build a MigrationRunner from the hub config + the configured Mongo URI. */
|
|
55
|
+
/** Build a MigrationRunner from the hub config + the configured Mongo URI (or the SQL default source's owner). */
|
|
51
56
|
protected buildRunner(): MigrationRunner {
|
|
52
57
|
if (this.config.migrations === false) {
|
|
53
58
|
throw new Error(HubActionMessage.migrationsDisabled);
|
|
54
59
|
}
|
|
60
|
+
const sqlStore = this.sqlStateStore();
|
|
61
|
+
if (sqlStore) {
|
|
62
|
+
return new MigrationRunner({
|
|
63
|
+
migrationsDirectory: resolve(process.cwd(), this.config.migrations.dir),
|
|
64
|
+
stateStore: sqlStore,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
55
67
|
const uri = this.configService.getFastButReadOnly<string>('mongoose.uri');
|
|
56
68
|
if (!uri) {
|
|
57
69
|
throw new Error(HubActionMessage.mongoUriMissing);
|
|
@@ -66,11 +78,93 @@ export class CoreHubMigrationsService {
|
|
|
66
78
|
});
|
|
67
79
|
}
|
|
68
80
|
|
|
81
|
+
/**
|
|
82
|
+
* The migration state store when the default source is a SQL database: the framework keeps the state there
|
|
83
|
+
* (`lt_migrations`), readable and writable by the table owner only. Throws without `database.ownerUrl`.
|
|
84
|
+
*/
|
|
85
|
+
protected sqlStateStore(): SqlStateStore | undefined {
|
|
86
|
+
const source = getPersistenceRuntime()?.defaultSqlSource();
|
|
87
|
+
if (!source) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
if (!source.ownerUrl) {
|
|
91
|
+
throw new Error(HubActionMessage.sqlOwnerMissing);
|
|
92
|
+
}
|
|
93
|
+
return new SqlStateStore({ engine: source.engine as DatabaseSqlEngine, url: source.ownerUrl });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Refuse to run or roll back while {@link migrationStateLeftInMongo} — the Hub would apply, against live data, every
|
|
98
|
+
* migration the project's own runs recorded in MongoDB.
|
|
99
|
+
*/
|
|
100
|
+
protected async assertSingleMigrationState(): Promise<void> {
|
|
101
|
+
const sqlStore = this.sqlStateStore();
|
|
102
|
+
if (!sqlStore) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const completed = ((await sqlStore.loadAsync()).migrations ?? []).map((migration) => migration.title);
|
|
106
|
+
if (await this.migrationStateLeftInMongo(completed)) {
|
|
107
|
+
throw new Error(this.migrationStateInMongoMessage());
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Whether the project still records its migrations in MongoDB although the default source is a SQL database.
|
|
113
|
+
*
|
|
114
|
+
* The state of a SQL default source belongs in `lt_migrations`, but only `migrations-utils/migrate.js` decides where
|
|
115
|
+
* it actually goes: one that still passes the MongoDB URI to `createMigrationStore()` writes the MongoDB collection,
|
|
116
|
+
* and the empty table would show every applied migration as pending. Answered from the data, never guessed: an empty
|
|
117
|
+
* table next to a MongoDB collection that lists applied migrations. A MongoDB read that fails throws, so the panel
|
|
118
|
+
* never offers a run it could not rule out.
|
|
119
|
+
*/
|
|
120
|
+
protected async migrationStateLeftInMongo(sqlCompleted: string[]): Promise<boolean> {
|
|
121
|
+
if (sqlCompleted.length || this.config.migrations === false) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const db = this.connection?.db;
|
|
125
|
+
if (!db) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
const [stateDoc] = await db.collection(this.config.migrations.collectionName).find({}).limit(1).toArray();
|
|
129
|
+
return (stateDoc?.migrations ?? []).length > 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
protected migrationStateInMongoMessage(): string {
|
|
133
|
+
return HubActionMessage.migrationStateInMongo(
|
|
134
|
+
this.config.migrations === false ? 'migrations' : this.config.migrations.collectionName,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
69
138
|
/** Completed + pending migrations. */
|
|
70
139
|
async getStatus(): Promise<HubMigrationsData | HubUnavailable> {
|
|
71
140
|
if (this.config.migrations === false) {
|
|
72
141
|
return { available: false, hint: 'The migrations panel is disabled.' };
|
|
73
142
|
}
|
|
143
|
+
let sqlStore: SqlStateStore | undefined;
|
|
144
|
+
try {
|
|
145
|
+
sqlStore = this.sqlStateStore();
|
|
146
|
+
} catch (error) {
|
|
147
|
+
return { available: false, hint: error instanceof Error ? error.message : String(error) };
|
|
148
|
+
}
|
|
149
|
+
if (sqlStore) {
|
|
150
|
+
let state: { lastRun?: string; migrations?: { title: string }[] } = {};
|
|
151
|
+
try {
|
|
152
|
+
state = await sqlStore.loadAsync();
|
|
153
|
+
} catch (error) {
|
|
154
|
+
this.logger.warn(`Failed to read migration state: ${error instanceof Error ? error.message : String(error)}`);
|
|
155
|
+
}
|
|
156
|
+
const completed = (state.migrations ?? []).map((migration) => migration.title);
|
|
157
|
+
try {
|
|
158
|
+
if (await this.migrationStateLeftInMongo(completed)) {
|
|
159
|
+
return { available: false, hint: this.migrationStateInMongoMessage() };
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return { available: false, hint: error instanceof Error ? error.message : String(error) };
|
|
163
|
+
}
|
|
164
|
+
const { dirAvailable, files } = await this.listMigrationFiles();
|
|
165
|
+
const pending = dirAvailable ? files.filter((file) => !completed.includes(file)) : [];
|
|
166
|
+
return { completed, dirAvailable, lastRun: state.lastRun, pending, source: 'table' };
|
|
167
|
+
}
|
|
74
168
|
const db = this.connection?.db;
|
|
75
169
|
if (!db) {
|
|
76
170
|
return { available: false, hint: 'No MongoDB connection is available.' };
|
|
@@ -6,7 +6,19 @@ import { CoreAiInteractionService } from '../../ai/services/core-ai-interaction.
|
|
|
6
6
|
import { CoreBetterAuthUserMapper } from '../../better-auth/core-better-auth-user.mapper.js';
|
|
7
7
|
import { CoreErrorCodeService } from '../../error-code/core-error-code.service.js';
|
|
8
8
|
import { CorePermissionsService } from '../../permissions/core-permissions.service.js';
|
|
9
|
-
import {
|
|
9
|
+
import { redactUrl } from '../../../common/persistence/data-source.config.js';
|
|
10
|
+
import {
|
|
11
|
+
getPersistedModels,
|
|
12
|
+
getPersistenceRuntime,
|
|
13
|
+
getRegisteredDataStore,
|
|
14
|
+
} from '../../../common/persistence/persistence-runtime.registry.js';
|
|
15
|
+
import { ConfigService } from '../../../common/services/config.service.js';
|
|
16
|
+
import {
|
|
17
|
+
HubCronData,
|
|
18
|
+
HubErrorCodesData,
|
|
19
|
+
HubPersistenceData,
|
|
20
|
+
HubUnavailable,
|
|
21
|
+
} from '../interfaces/hub-panels.interface.js';
|
|
10
22
|
|
|
11
23
|
/**
|
|
12
24
|
* Single choke point for the Hub's OPTIONAL data sources.
|
|
@@ -28,6 +40,40 @@ export class CoreHubSourcesService {
|
|
|
28
40
|
@Optional() protected readonly schedulerRegistry?: SchedulerRegistry,
|
|
29
41
|
) {}
|
|
30
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Where every model registered with `CorePersistenceModule.forFeature()` is stored: its source, the database and
|
|
45
|
+
* engine behind it, and what that store can do. Without a SQL source everything is on the MongoDB connection.
|
|
46
|
+
*/
|
|
47
|
+
getPersistence(): HubPersistenceData {
|
|
48
|
+
const overview = getPersistenceRuntime()?.describe() ?? {
|
|
49
|
+
defaultSource: 'default',
|
|
50
|
+
models: getPersistedModels().map((model) => ({ name: model.name, source: 'default' })),
|
|
51
|
+
sources: [
|
|
52
|
+
{
|
|
53
|
+
driver: 'mongodb',
|
|
54
|
+
host: redactUrl(ConfigService.configFastButReadOnly?.mongoose?.uri ?? ''),
|
|
55
|
+
name: 'default',
|
|
56
|
+
ownerConfigured: false,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
...overview,
|
|
62
|
+
models: overview.models
|
|
63
|
+
.map((model) => {
|
|
64
|
+
const store = getRegisteredDataStore(model.name);
|
|
65
|
+
const capabilities = store
|
|
66
|
+
? Object.entries(store.capabilities)
|
|
67
|
+
.filter(([, value]) => value === true)
|
|
68
|
+
.map(([key]) => key)
|
|
69
|
+
.sort()
|
|
70
|
+
: [];
|
|
71
|
+
return { ...model, capabilities, driver: store?.driver };
|
|
72
|
+
})
|
|
73
|
+
.sort((a, b) => a.name.localeCompare(b.name)),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
31
77
|
/** AI availability + a light interaction/usage summary. */
|
|
32
78
|
async getAi(): Promise<HubUnavailable | { available: true; totalInteractions: number }> {
|
|
33
79
|
const interactionService = this.resolve<CoreAiInteractionService>(CoreAiInteractionService);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Inject, Injectable, Logger, OnModuleDestroy, OnModuleInit, Optional } from '@nestjs/common';
|
|
2
|
-
import { InjectConnection } from '
|
|
2
|
+
import { InjectConnection } from '../../../common/persistence/mongo/mongoose-compat.js';
|
|
3
3
|
import type { Connection } from 'mongoose';
|
|
4
4
|
|
|
5
5
|
import { redactSensitiveText } from '../../../common/helpers/logging.helper.js';
|
|
@@ -137,6 +137,60 @@ await synchronizedMigration(migrationOptions, async (migrationSet) => {
|
|
|
137
137
|
await synchronizedUp(migrationOptions);
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
+
### SQL migrations (PostgreSQL data sources)
|
|
141
|
+
|
|
142
|
+
On a PostgreSQL source the framework migrates the schema itself at boot (new tables, columns, declared renames,
|
|
143
|
+
non-unique indexes, row-level security, grants). Changes that can reject or rewrite stored rows — a changed column
|
|
144
|
+
type, a new unique index, a rename whose old and new column both exist — are never applied automatically: the boot
|
|
145
|
+
stops with `SchemaMigrationRequiredError`, listing each change with a **suggested** statement.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
migrate create widen-budget --sql
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
writes a migration whose `up` / `down` call `runSqlMigration(ownerUrl, statements)`. Paste the suggested statements,
|
|
152
|
+
review them, add the reverse to `down`. They run as the table owner (`NSC__DATABASE__OWNER_URL`, i.e.
|
|
153
|
+
`database.ownerUrl`), in one transaction, under the advisory lock the boot's schema migration takes — so a replica
|
|
154
|
+
booting meanwhile waits and then finds nothing left to do. In a vendor-mode project the import points at the vendored
|
|
155
|
+
core automatically.
|
|
156
|
+
|
|
157
|
+
`NSC__DATABASE__OWNER_URL` in the server's environment needs the URL beside it: a `database` written as a URL string
|
|
158
|
+
is REPLACED by the variable (the environment merge turns it into `{ ownerUrl }`), so the boot refuses that
|
|
159
|
+
combination. Write `database: { url: … }` in the configuration, or set `NSC__DATABASE__URL` as well.
|
|
160
|
+
|
|
161
|
+
### Migration state on PostgreSQL (`SqlStateStore`)
|
|
162
|
+
|
|
163
|
+
A project whose default source is PostgreSQL keeps its migration state there instead of in MongoDB. Pass the OWNER's
|
|
164
|
+
URL to `createMigrationStore()` — it picks the store by the URL's scheme:
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
// migrations-utils/migrate.js
|
|
168
|
+
const { createMigrationStore } = require('@lenne.tech/nest-server');
|
|
169
|
+
|
|
170
|
+
module.exports = createMigrationStore(process.env.NSC__DATABASE__OWNER_URL);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
| | MongoDB (`MongoStateStore`) | PostgreSQL (`SqlStateStore`) |
|
|
174
|
+
| ------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
175
|
+
| State | one document in `migrations` | one row in `lt_migrations` (created on first use) |
|
|
176
|
+
| Run lock | a document in `migrations_lock`, renewed every 15 s, broken after 60 s without renewal | a transaction-scoped advisory lock held for the whole run — it ends with the connection, so a replica killed mid-run leaves nothing to break |
|
|
177
|
+
| Opt out of the lock | `lockCollectionName: ''` | `lockCollectionName: ''` (or `new SqlStateStore({ url, lock: false })`) |
|
|
178
|
+
| Connection | the MongoDB URI | the table owner (`database.ownerUrl`): migrations change the schema and every tenant's data |
|
|
179
|
+
|
|
180
|
+
The connection uses the first SQL engine the project has installed (`typeorm`, `kysely`, `drizzle`): the CLI runs
|
|
181
|
+
outside the application and cannot read `database.sqlEngine`. To pin one, export your own class:
|
|
182
|
+
`class Store extends SqlStateStore { constructor() { super({ engine: 'kysely', url: process.env.NSC__DATABASE__OWNER_URL }) } }`.
|
|
183
|
+
|
|
184
|
+
**Move the state when you switch.** A project that had MongoDB as its default source has its applied migrations in the
|
|
185
|
+
`migrations` collection. Pointed at the owner URL, `createMigrationStore()` starts from an empty `lt_migrations`, and the
|
|
186
|
+
next `migrate up` applies every migration again. Copy the state document's `lastRun` and `migrations` into the table
|
|
187
|
+
first (`await new SqlStateStore(ownerUrl).saveAsync(state)` with the document `MongoStateStore.loadAsync()` returns).
|
|
188
|
+
The Hub's Migrations panel refuses to run while the table is empty and the collection is not.
|
|
189
|
+
|
|
190
|
+
`MigrationRunner`, `synchronizedMigration()` and the `migrate` CLI accept either store. The advisory lock is held by an
|
|
191
|
+
open transaction for the length of the run: a server-side `idle_in_transaction_session_timeout` shorter than your
|
|
192
|
+
longest migration would end it early — leave that setting off (the default) for the owner role.
|
|
193
|
+
|
|
140
194
|
## API Reference
|
|
141
195
|
|
|
142
196
|
### MongoStateStore
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* --store, -s Path to state store module
|
|
18
18
|
* --compiler, -c Compiler to use (e.g., ts:./path/to/ts-compiler.js)
|
|
19
19
|
* --template-file, -t Template file for creating migrations
|
|
20
|
+
* --sql Create a SQL migration (statements run as the table owner, see runSqlMigration)
|
|
20
21
|
* --strict Fail if a recorded migration's file is missing (default: off / tolerate).
|
|
21
22
|
* Applies to up/list; down always fails hard on a missing rollback file.
|
|
22
23
|
*/
|
|
@@ -25,7 +26,7 @@ import * as fs from 'fs';
|
|
|
25
26
|
import * as path from 'path';
|
|
26
27
|
|
|
27
28
|
import { MigrationRunner, parseStrictEnv } from '../migration-runner.js';
|
|
28
|
-
import {
|
|
29
|
+
import type { MigrationStateStore } from '../migration-state-store.interface.js';
|
|
29
30
|
import { createRequire } from 'node:module';
|
|
30
31
|
import { callerDirectory } from '../../../common/helpers/module-location.helper.js';
|
|
31
32
|
|
|
@@ -42,6 +43,8 @@ interface CliOptions {
|
|
|
42
43
|
migrationsDir: string;
|
|
43
44
|
store?: string;
|
|
44
45
|
strict?: boolean;
|
|
46
|
+
/** `create`: a SQL migration instead of the default template */
|
|
47
|
+
sql?: boolean;
|
|
45
48
|
templateFile?: string;
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -97,6 +100,40 @@ export function rewriteFrameworkSpecifier(template: string, specifier: string):
|
|
|
97
100
|
*
|
|
98
101
|
* @param coreRoot - Root of the core this CLI belongs to; defaults to the one it runs from (tests only)
|
|
99
102
|
*/
|
|
103
|
+
/**
|
|
104
|
+
* The template of `migrate create <name> --sql`: the statements a refused boot suggested go into `up` after review,
|
|
105
|
+
* their reverse into `down`. They run as the table owner (`NSC__DATABASE__OWNER_URL`, i.e. `database.ownerUrl`).
|
|
106
|
+
* `specifier`: the import path a vendor-mode project uses instead of the package name.
|
|
107
|
+
*/
|
|
108
|
+
export function sqlMigrationTemplate(name: string, specifier?: string): string {
|
|
109
|
+
const template = `/**
|
|
110
|
+
* Migration: ${name} (SQL)
|
|
111
|
+
* Created: ${new Date().toISOString()}
|
|
112
|
+
*
|
|
113
|
+
* Paste the statements the boot suggested (SchemaMigrationRequiredError) and REVIEW them: a narrowed type, a new
|
|
114
|
+
* unique index or a rename collision can reject or rewrite stored rows. They run as the table owner, under the lock
|
|
115
|
+
* the boot's schema migration takes — on PostgreSQL in one transaction; on MySQL / MariaDB every DDL statement commits
|
|
116
|
+
* on its own, so write the migration so it can run again.
|
|
117
|
+
*/
|
|
118
|
+
import { runSqlMigration } from '@lenne.tech/nest-server';
|
|
119
|
+
|
|
120
|
+
const ownerUrl = process.env.NSC__DATABASE__OWNER_URL ?? '';
|
|
121
|
+
|
|
122
|
+
export const up = async () => {
|
|
123
|
+
await runSqlMigration(ownerUrl, [
|
|
124
|
+
// PostgreSQL: 'ALTER TABLE "projects" ALTER COLUMN "budget" TYPE text COLLATE "C" USING "budget"::text',
|
|
125
|
+
]);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const down = async () => {
|
|
129
|
+
await runSqlMigration(ownerUrl, [
|
|
130
|
+
// the reverse of every statement in up
|
|
131
|
+
]);
|
|
132
|
+
};
|
|
133
|
+
`;
|
|
134
|
+
return specifier ? rewriteFrameworkSpecifier(template, specifier) : template;
|
|
135
|
+
}
|
|
136
|
+
|
|
100
137
|
async function createMigration(name: string, options: CliOptions, coreRoot?: string) {
|
|
101
138
|
if (!name) {
|
|
102
139
|
console.error('Error: Migration name is required');
|
|
@@ -116,7 +153,9 @@ async function createMigration(name: string, options: CliOptions, coreRoot?: str
|
|
|
116
153
|
let template: string;
|
|
117
154
|
|
|
118
155
|
// Use custom template if provided
|
|
119
|
-
if (options.
|
|
156
|
+
if (options.sql) {
|
|
157
|
+
template = sqlMigrationTemplate(name, vendoredFrameworkSpecifier(options.migrationsDir, process.cwd(), coreRoot));
|
|
158
|
+
} else if (options.templateFile) {
|
|
120
159
|
const templatePath = path.resolve(process.cwd(), options.templateFile);
|
|
121
160
|
template = fs.readFileSync(templatePath, 'utf-8');
|
|
122
161
|
const specifier = vendoredFrameworkSpecifier(options.migrationsDir, process.cwd(), coreRoot);
|
|
@@ -197,7 +236,7 @@ async function listMigrations(options: CliOptions) {
|
|
|
197
236
|
/**
|
|
198
237
|
* Load state store from module
|
|
199
238
|
*/
|
|
200
|
-
function loadStateStore(storePath: string | undefined):
|
|
239
|
+
function loadStateStore(storePath: string | undefined): MigrationStateStore {
|
|
201
240
|
if (!storePath) {
|
|
202
241
|
throw new Error('--store option is required for up/down/list commands');
|
|
203
242
|
}
|
|
@@ -298,6 +337,8 @@ function parseArgs(): { command: string; name?: string; options: CliOptions } {
|
|
|
298
337
|
options.templateFile = args[++i];
|
|
299
338
|
} else if (arg === '--strict') {
|
|
300
339
|
options.strict = true;
|
|
340
|
+
} else if (arg === '--sql') {
|
|
341
|
+
options.sql = true;
|
|
301
342
|
}
|
|
302
343
|
}
|
|
303
344
|
|
|
@@ -38,4 +38,7 @@
|
|
|
38
38
|
export * from './cli/migrate-cli.js';
|
|
39
39
|
export * from './migration.helper.js';
|
|
40
40
|
export * from './migration-runner.js';
|
|
41
|
+
export * from './migration-state-store.interface.js';
|
|
41
42
|
export * from './mongo-state-store.js';
|
|
43
|
+
export * from './sql-migration.helper.js';
|
|
44
|
+
export * from './sql-state-store.js';
|
|
@@ -2,7 +2,8 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
|
|
4
4
|
import { _endMigration, _startMigration } from './migration.helper.js';
|
|
5
|
-
import {
|
|
5
|
+
import type { MigrationStateStore } from './migration-state-store.interface.js';
|
|
6
|
+
import { withMigrationLock } from './mongo-state-store.js';
|
|
6
7
|
import { createRequire } from 'node:module';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -98,7 +99,7 @@ export interface MigrationRunnerOptions {
|
|
|
98
99
|
/** Pattern to match migration files (default: {@link DEFAULT_MIGRATION_FILE_PATTERN}) */
|
|
99
100
|
pattern?: RegExp;
|
|
100
101
|
/** State store for tracking migrations */
|
|
101
|
-
stateStore:
|
|
102
|
+
stateStore: MigrationStateStore;
|
|
102
103
|
/**
|
|
103
104
|
* Fail hard when a migration recorded in the state has no file on disk.
|
|
104
105
|
*
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where `MigrationRunner` and the `migrate` CLI keep the applied migrations: `MongoStateStore` on MongoDB,
|
|
3
|
+
* `SqlStateStore` on PostgreSQL, MySQL and MariaDB. Types only.
|
|
4
|
+
*/
|
|
5
|
+
export interface MigrationSet {
|
|
6
|
+
down?: (done?: (err?: Error) => void) => void;
|
|
7
|
+
lastRun?: string;
|
|
8
|
+
migrations: Array<{ timestamp?: number; title: string }>;
|
|
9
|
+
up: (done?: (err?: Error) => void) => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface MigrationStateStore {
|
|
13
|
+
/** Callback API of the `migrate` package */
|
|
14
|
+
load(fn: (err?: Error, set?: MigrationSet) => void): void;
|
|
15
|
+
loadAsync(): Promise<MigrationSet>;
|
|
16
|
+
/** Callback API of the `migrate` package */
|
|
17
|
+
save(set: MigrationSet, fn: (err?: Error) => void): void;
|
|
18
|
+
saveAsync(set: MigrationSet): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Run `fn` while holding the store's migration lock, so concurrent runs of several replicas apply each migration
|
|
21
|
+
* once. A store without a lock runs `fn` unsynchronized.
|
|
22
|
+
*/
|
|
23
|
+
withLock?<T>(fn: () => Promise<T>): Promise<T>;
|
|
24
|
+
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
|
-
import { Db,
|
|
2
|
+
import type { Db, MongoClient, ObjectId } from 'mongodb';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
|
|
5
5
|
import { callerDirectory } from '../../common/helpers/module-location.helper.js';
|
|
6
|
+
import type { MigrationStateStore } from './migration-state-store.interface.js';
|
|
6
7
|
import { MongoStateStore } from './mongo-state-store.js';
|
|
8
|
+
import { SqlStateStore } from './sql-state-store.js';
|
|
9
|
+
import { requireMongoPackages } from '../../common/persistence/mongo/mongo-packages.js';
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* Migration helper functions for database operations
|
|
@@ -60,7 +63,7 @@ export const _endMigration = async () => {
|
|
|
60
63
|
* ```
|
|
61
64
|
*/
|
|
62
65
|
export const getDb = async (mongoUrl: string): Promise<Db> => {
|
|
63
|
-
const client: MongoClient = await MongoClient.connect(mongoUrl);
|
|
66
|
+
const client: MongoClient = await mongoDriver().MongoClient.connect(mongoUrl);
|
|
64
67
|
|
|
65
68
|
// Track connection for auto-cleanup in migrations
|
|
66
69
|
if (inMigrationContext) {
|
|
@@ -187,14 +190,14 @@ export const uploadFileToGridFS = async (
|
|
|
187
190
|
...options,
|
|
188
191
|
};
|
|
189
192
|
|
|
190
|
-
const client = await MongoClient.connect(mongoUrl);
|
|
193
|
+
const client = await mongoDriver().MongoClient.connect(mongoUrl);
|
|
191
194
|
// Registered unconditionally — unlike `getDb()`, which only registers inside a
|
|
192
195
|
// migration context. This client is always ours to close, so `_endMigration()`
|
|
193
196
|
// stays a backstop for the case where the upload throws before `settle()` runs.
|
|
194
197
|
activeConnections.add(client);
|
|
195
198
|
|
|
196
199
|
const db = client.db();
|
|
197
|
-
const bucket = new GridFSBucket(db, { bucketName });
|
|
200
|
+
const bucket = new (mongoDriver().GridFSBucket)(db, { bucketName });
|
|
198
201
|
const writeStream = bucket.openUploadStream(filename);
|
|
199
202
|
|
|
200
203
|
const readStream = fs.createReadStream(sourcePath);
|
|
@@ -276,10 +279,10 @@ export const uploadFileToGridFS = async (
|
|
|
276
279
|
* the same time serializes instead of applying the same migration twice (the container
|
|
277
280
|
* entrypoint runs migrations on every boot). Pass an empty string to opt out.
|
|
278
281
|
*
|
|
279
|
-
* @param
|
|
280
|
-
* @param collectionName - Optional collection name (default: 'migrations')
|
|
282
|
+
* @param databaseUrl - MongoDB connection URI, or the PostgreSQL / MySQL / MariaDB URL of the table owner (`database.ownerUrl`)
|
|
283
|
+
* @param collectionName - Optional collection name (default: 'migrations'; on SQL the table `lt_migrations`)
|
|
281
284
|
* @param lockCollectionName - Lock collection name (default: 'migrations_lock'); `''` disables locking
|
|
282
|
-
* @returns
|
|
285
|
+
* @returns A state store class (MongoStateStore or SqlStateStore) that can be used with the migrate CLI
|
|
283
286
|
*
|
|
284
287
|
* @example
|
|
285
288
|
* ```typescript
|
|
@@ -288,23 +291,45 @@ export const uploadFileToGridFS = async (
|
|
|
288
291
|
* const config = require('../src/config.env');
|
|
289
292
|
*
|
|
290
293
|
* module.exports = createMigrationStore(config.default.mongoose.uri);
|
|
294
|
+
* // A project whose default source is PostgreSQL:
|
|
295
|
+
* // module.exports = createMigrationStore(process.env.NSC__DATABASE__OWNER_URL);
|
|
291
296
|
* ```
|
|
292
297
|
*/
|
|
293
298
|
export const createMigrationStore = (
|
|
294
|
-
|
|
299
|
+
databaseUrl: string,
|
|
295
300
|
collectionName: string = 'migrations',
|
|
296
301
|
lockCollectionName: string = 'migrations_lock',
|
|
297
302
|
// Explicit return type: the returned class is anonymous to the declaration emitter, and
|
|
298
303
|
// MongoStateStore has private members, so an inferred type cannot be written to the .d.ts
|
|
299
304
|
// (TS4094).
|
|
300
|
-
|
|
305
|
+
// MongoStateStore's own fields stay in the type (optional: a SQL store has none), so code reading them keeps compiling
|
|
306
|
+
): new () => MigrationStateStore & Partial<Pick<MongoStateStore, 'lockCollectionName' | 'mongodbHost'>> => {
|
|
307
|
+
// A SQL URL (the OWNER's, `database.ownerUrl`) keeps the state in a table and serialises runs with a database lock;
|
|
308
|
+
// `lockCollectionName` set to '' disables that lock there too. The names default to the framework's own
|
|
309
|
+
// `lt_migrations` table, a custom `collectionName` is used as the table name
|
|
310
|
+
if (/^(postgres(ql)?|mysql|mariadb):/i.test(databaseUrl ?? '')) {
|
|
311
|
+
return class SqlMigrationStateStore extends SqlStateStore {
|
|
312
|
+
constructor() {
|
|
313
|
+
super({
|
|
314
|
+
lock: !!lockCollectionName,
|
|
315
|
+
tableName: collectionName === 'migrations' ? 'lt_migrations' : collectionName,
|
|
316
|
+
url: databaseUrl,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
}
|
|
301
321
|
return class MigrationStateStore extends MongoStateStore {
|
|
302
322
|
constructor() {
|
|
303
323
|
super({
|
|
304
324
|
collectionName,
|
|
305
325
|
lockCollectionName: lockCollectionName || undefined,
|
|
306
|
-
uri:
|
|
326
|
+
uri: databaseUrl,
|
|
307
327
|
});
|
|
308
328
|
}
|
|
309
329
|
};
|
|
310
330
|
};
|
|
331
|
+
|
|
332
|
+
/** The MongoDB driver — a MongoDB migration needs it, a project without MongoDB never reaches this */
|
|
333
|
+
function mongoDriver() {
|
|
334
|
+
return requireMongoPackages('A MongoDB migration (store or helper)').mongodb;
|
|
335
|
+
}
|