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