@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
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { Connection } from 'mongoose';
|
|
2
|
+
|
|
3
|
+
import { isObjectIdLike } from '../../common/helpers/id.helper.js';
|
|
4
|
+
import type { DataStore, FindOptions } from '../../common/persistence/data-store.interface.js';
|
|
5
|
+
import { getRegisteredDataStore, getStoreForModel } from '../../common/persistence/persistence-runtime.registry.js';
|
|
6
|
+
import { UnsupportedCapabilityError } from '../../common/persistence/unsupported-capability.error.js';
|
|
7
|
+
import type { FileCollection } from './file-metadata.helper.js';
|
|
8
|
+
import { FILESYSTEM_FILE_MODEL, S3_FILE_MODEL } from './file-metadata.models.js';
|
|
9
|
+
import { FILESYSTEM_FILES_COLLECTION } from './filesystem-file.helper.js';
|
|
10
|
+
import { S3_FILES_COLLECTION } from './s3-file.helper.js';
|
|
11
|
+
import { newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
12
|
+
|
|
13
|
+
/** The two stores that keep their metadata outside GridFS */
|
|
14
|
+
export type FileMetadataStore = 'filesystem' | 's3';
|
|
15
|
+
|
|
16
|
+
const STORES: Record<FileMetadataStore, { collection: string; model: string }> = {
|
|
17
|
+
filesystem: { collection: FILESYSTEM_FILES_COLLECTION, model: FILESYSTEM_FILE_MODEL },
|
|
18
|
+
s3: { collection: S3_FILES_COLLECTION, model: S3_FILE_MODEL },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Where the metadata of a store lives: its MongoDB collection, or — when `database` routes the model to a SQL source —
|
|
23
|
+
* that model's table, behind the same few collection operations the file helpers use. Resolved per call, so a
|
|
24
|
+
* service constructed before the stores exist still reaches the right one.
|
|
25
|
+
*
|
|
26
|
+
* Every reader and writer of `s3-files` / `filesystem-files` goes through here (`CoreFileService`, the TUS hand-off,
|
|
27
|
+
* the Hub): one of them reading the collection while the others write the table would lose files from view.
|
|
28
|
+
*/
|
|
29
|
+
export function fileMetadataCollection(connection: Connection | null, store: FileMetadataStore): FileCollection {
|
|
30
|
+
const { collection, model } = STORES[store];
|
|
31
|
+
const dataStore = connection
|
|
32
|
+
? connection.models?.[model]
|
|
33
|
+
? getStoreForModel(connection.models[model])
|
|
34
|
+
: undefined
|
|
35
|
+
: // No MongoDB connection (PostgreSQL alone, or `database: false`): the store registered for the model is the only
|
|
36
|
+
// one there is — this application's, since no other can have one without a connection either
|
|
37
|
+
getRegisteredDataStore(model);
|
|
38
|
+
if (dataStore && !dataStore.capabilities.mongoosePopulate) {
|
|
39
|
+
return sqlFileCollection(dataStore, collection);
|
|
40
|
+
}
|
|
41
|
+
if (!connection) {
|
|
42
|
+
throw new UnsupportedCapabilityError(
|
|
43
|
+
`The ${collection} file metadata has nowhere to go: no MongoDB is configured and no data source routes ${model}`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return connection.db.collection(collection);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A metadata table seen as the collection the helpers expect: `_id` (an ObjectId) is the record's `id`, MongoDB
|
|
51
|
+
* filters and sorts are passed to the store with `_id` renamed, and a record comes back with `_id` as an ObjectId and
|
|
52
|
+
* without the columns it has no value in — the shape a document of the collection has.
|
|
53
|
+
*/
|
|
54
|
+
export function sqlFileCollection(store: DataStore<any>, collectionName: string): FileCollection {
|
|
55
|
+
const find = async (filter: unknown, options: Record<string, any> = {}) =>
|
|
56
|
+
(await store.find(toWhere(filter ?? {}), toFindOptions(options))).map(toDocument);
|
|
57
|
+
const collection = {
|
|
58
|
+
collectionName,
|
|
59
|
+
countDocuments: async (filter: unknown = {}) => store.count(toWhere(filter)),
|
|
60
|
+
// The table carries the `filename` index the model declares
|
|
61
|
+
createIndex: async () => 'filename_1',
|
|
62
|
+
dbName: 'sql',
|
|
63
|
+
deleteOne: async (filter: unknown) => ({
|
|
64
|
+
acknowledged: true,
|
|
65
|
+
deletedCount: (await store.deleteOne(toWhere(filter))) ? 1 : 0,
|
|
66
|
+
}),
|
|
67
|
+
find: (filter?: unknown, options?: Record<string, any>) => ({ toArray: () => find(filter, options) }),
|
|
68
|
+
findOne: async (filter?: unknown, options?: Record<string, any>) =>
|
|
69
|
+
(await find(filter, { ...options, limit: 1 }))[0] ?? null,
|
|
70
|
+
insertOne: async (doc: Record<string, any>) => {
|
|
71
|
+
const { _id, ...fields } = doc;
|
|
72
|
+
await store.insert({ ...fields, id: String(_id) });
|
|
73
|
+
return { acknowledged: true, insertedId: _id };
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
return collection as unknown as FileCollection;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** A MongoDB filter for the store: `_id` becomes `id`, ObjectIds become their hex strings — at every depth */
|
|
80
|
+
function toWhere(value: unknown): any {
|
|
81
|
+
if (isObjectIdLike(value)) {
|
|
82
|
+
return value.toHexString();
|
|
83
|
+
}
|
|
84
|
+
if (Array.isArray(value)) {
|
|
85
|
+
return value.map(toWhere);
|
|
86
|
+
}
|
|
87
|
+
if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp) {
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key === '_id' ? 'id' : key, toWhere(entry)]));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function toFindOptions(options: Record<string, any>): FindOptions {
|
|
94
|
+
const { collation, limit, skip, sort } = options;
|
|
95
|
+
return {
|
|
96
|
+
...(collation ? { collation } : {}),
|
|
97
|
+
...(limit ? { limit } : {}),
|
|
98
|
+
...(skip ? { skip } : {}),
|
|
99
|
+
...(sort ? { sort: toWhere(sort) } : {}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function toDocument(record: Record<string, any>): Record<string, any> {
|
|
104
|
+
const { id, ...fields } = record;
|
|
105
|
+
return {
|
|
106
|
+
_id: newObjectId(id),
|
|
107
|
+
...Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== null && value !== undefined)),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Logger } from '@nestjs/common';
|
|
2
2
|
|
|
3
3
|
import { IServerOptions } from '../../common/interfaces/server-options.interface.js';
|
|
4
|
+
import { resolveDataSources, resolveModelSource } from '../../common/persistence/data-source.config.js';
|
|
5
|
+
import { FILESYSTEM_FILE_MODEL } from './file-metadata.models.js';
|
|
4
6
|
|
|
5
7
|
const logger = new Logger('CoreFileStorage');
|
|
6
8
|
|
|
@@ -58,6 +60,28 @@ export function hasDatabaseConfig(config?: Partial<IServerOptions>): boolean {
|
|
|
58
60
|
return !!config?.mongoose?.uri;
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
/**
|
|
64
|
+
* The SQL data source `database` routes the file metadata to, or `undefined` when it stays on MongoDB. Answers from the
|
|
65
|
+
* configuration alone, so the driver is known before any store exists; a configuration that cannot be resolved has
|
|
66
|
+
* already stopped the boot in `CoreModule.forRoot()`, so it reads as "MongoDB" here.
|
|
67
|
+
*/
|
|
68
|
+
export function fileMetadataSqlSource(config?: Partial<IServerOptions>): string | undefined {
|
|
69
|
+
if (!config?.database) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const resolved = resolveDataSources({
|
|
74
|
+
database: config.database,
|
|
75
|
+
explicitMongoose: !!config.mongoose,
|
|
76
|
+
mongooseUri: config.mongoose?.uri,
|
|
77
|
+
});
|
|
78
|
+
const source = resolveModelSource(resolved, FILESYSTEM_FILE_MODEL);
|
|
79
|
+
return source && resolved.sources[source]?.driver !== 'mongodb' ? source : undefined;
|
|
80
|
+
} catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
61
85
|
/**
|
|
62
86
|
* Decide which storage driver to use.
|
|
63
87
|
*
|
|
@@ -69,8 +93,10 @@ export function hasDatabaseConfig(config?: Partial<IServerOptions>): boolean {
|
|
|
69
93
|
* Without an explicit value the default is derived, most capable first:
|
|
70
94
|
*
|
|
71
95
|
* 1. `s3` — when the S3 config names a bucket
|
|
72
|
-
* 2. `
|
|
73
|
-
*
|
|
96
|
+
* 2. `filesystem` — when `database` routes the file metadata to a SQL source:
|
|
97
|
+
* GridFS would put bytes and metadata into MongoDB
|
|
98
|
+
* 3. `gridfs` — when a database is configured
|
|
99
|
+
* 4. `filesystem` — when none is (today a theoretical case: `CoreModule`
|
|
74
100
|
* always registers Mongoose, so a project without a database
|
|
75
101
|
* does not boot at all)
|
|
76
102
|
*
|
|
@@ -97,6 +123,25 @@ export function resolveFileStorage(config?: Partial<IServerOptions>): FileStorag
|
|
|
97
123
|
return { driver: 's3', explicit: false, reason: 's3.bucket is configured' };
|
|
98
124
|
}
|
|
99
125
|
|
|
126
|
+
if (config?.database === false) {
|
|
127
|
+
return {
|
|
128
|
+
driver: 'filesystem',
|
|
129
|
+
explicit: false,
|
|
130
|
+
reason: 'the project runs without a database (`database: false`) — file metadata has nowhere to go',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const sqlSource = fileMetadataSqlSource(config);
|
|
135
|
+
if (sqlSource) {
|
|
136
|
+
// GridFS keeps bytes AND metadata in MongoDB; a project that routes the file metadata to SQL does not get its
|
|
137
|
+
// files put into MongoDB without asking for it (`file.storage: 'gridfs'` still does)
|
|
138
|
+
return {
|
|
139
|
+
driver: 'filesystem',
|
|
140
|
+
explicit: false,
|
|
141
|
+
reason: `no S3 bucket is configured and the file metadata lives in the SQL source "${sqlSource}"`,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
100
145
|
if (hasDatabaseConfig(config)) {
|
|
101
146
|
return { driver: 'gridfs', explicit: false, reason: 'a database is configured and no S3 bucket is' };
|
|
102
147
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createReadStream, createWriteStream } from 'fs';
|
|
2
2
|
import { mkdir, rm, stat } from 'fs/promises';
|
|
3
|
-
import { Types } from 'mongoose';
|
|
3
|
+
import type { Types } from 'mongoose';
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { pipeline } from 'stream/promises';
|
|
6
6
|
import { Readable } from 'stream';
|
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
findMetadataByName,
|
|
15
15
|
} from './file-metadata.helper.js';
|
|
16
16
|
import { streamToBuffer } from './s3-file.helper.js';
|
|
17
|
+
import { newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
17
18
|
|
|
18
|
-
/** Metadata collection for files stored on the local filesystem */
|
|
19
|
+
/** Metadata collection for files stored on the local filesystem (on a SQL source: the table `filesystem_files`) */
|
|
19
20
|
export const FILESYSTEM_FILES_COLLECTION = 'filesystem-files';
|
|
20
21
|
|
|
21
22
|
/** Default directory for the filesystem storage driver */
|
|
@@ -31,12 +32,14 @@ export const DEFAULT_FILESYSTEM_DIR = 'uploads/files';
|
|
|
31
32
|
export type FilesystemFileInfo = FileMetadataInfo;
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
|
-
* Helper for files stored on the local filesystem with their metadata in
|
|
35
|
+
* Helper for files stored on the local filesystem with their metadata in the database.
|
|
35
36
|
*
|
|
36
37
|
* Counterpart of `GridFSHelper` and `S3FileHelper`: same operations, the local
|
|
37
|
-
* disk as the byte store and `filesystem-files` as the metadata store
|
|
38
|
+
* disk as the byte store and `filesystem-files` as the metadata store — pass
|
|
39
|
+
* `fileMetadataCollection(connection, 'filesystem')`, never the MongoDB collection
|
|
40
|
+
* directly: on a SQL source the metadata lives in the table `filesystem_files`.
|
|
38
41
|
*
|
|
39
|
-
* WHY THE METADATA STILL LIVES IN
|
|
42
|
+
* WHY THE METADATA STILL LIVES IN THE DATABASE: filename, content type, length and the
|
|
40
43
|
* custom `metadata` a per-file authorization rule reads have to be queryable —
|
|
41
44
|
* `findFileInfo()` filters and pages over them, and `checkRights()` reads them
|
|
42
45
|
* per request. A directory listing answers none of that, and sidecar files would
|
|
@@ -57,7 +60,7 @@ export class FilesystemFileHelper {
|
|
|
57
60
|
* a user-supplied filename here.
|
|
58
61
|
*/
|
|
59
62
|
static filePath(directory: string, id: string | Types.ObjectId): string {
|
|
60
|
-
const objectId = typeof id === 'string' ?
|
|
63
|
+
const objectId = typeof id === 'string' ? newObjectId(id) : id;
|
|
61
64
|
return path.join(path.resolve(directory), objectId.toHexString());
|
|
62
65
|
}
|
|
63
66
|
|
|
@@ -83,7 +86,7 @@ export class FilesystemFileHelper {
|
|
|
83
86
|
metadata?: Record<string, any>;
|
|
84
87
|
},
|
|
85
88
|
): Promise<FilesystemFileInfo> {
|
|
86
|
-
const _id =
|
|
89
|
+
const _id = newObjectId();
|
|
87
90
|
const target = FilesystemFileHelper.filePath(directory, _id);
|
|
88
91
|
|
|
89
92
|
await mkdir(path.dirname(target), { recursive: true });
|
|
@@ -163,7 +166,7 @@ export class FilesystemFileHelper {
|
|
|
163
166
|
* up through the API.
|
|
164
167
|
*/
|
|
165
168
|
static async deleteFile(directory: string, collection: FileCollection, id: string | Types.ObjectId): Promise<void> {
|
|
166
|
-
const objectId = typeof id === 'string' ?
|
|
169
|
+
const objectId = typeof id === 'string' ? newObjectId(id) : id;
|
|
167
170
|
await rm(FilesystemFileHelper.filePath(directory, objectId), { force: true });
|
|
168
171
|
await collection.deleteOne({ _id: objectId });
|
|
169
172
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Types } from 'mongoose';
|
|
1
|
+
import type { Types } from 'mongoose';
|
|
2
2
|
import { Readable } from 'stream';
|
|
3
3
|
|
|
4
4
|
import { CoreS3Service } from '../../common/services/core-s3.service.js';
|
|
@@ -10,13 +10,15 @@ import {
|
|
|
10
10
|
findMetadataById,
|
|
11
11
|
findMetadataByName,
|
|
12
12
|
} from './file-metadata.helper.js';
|
|
13
|
+
import { newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Name of the MongoDB collection holding the metadata of S3-stored files.
|
|
16
17
|
*
|
|
17
18
|
* S3 itself has no queryable metadata store, so file info (filename, contentType,
|
|
18
19
|
* length, uploadDate) is kept in this collection — the equivalent of GridFS's
|
|
19
|
-
* `fs.files`. The object key in the bucket is the string form of `_id`.
|
|
20
|
+
* `fs.files`. The object key in the bucket is the string form of `_id`. On a SQL
|
|
21
|
+
* source the same records live in the table `s3_files` (`fileMetadataCollection()`).
|
|
20
22
|
*/
|
|
21
23
|
export const S3_FILES_COLLECTION = 's3-files';
|
|
22
24
|
|
|
@@ -56,7 +58,9 @@ export async function streamToBuffer(stream: Readable): Promise<Buffer> {
|
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
|
-
* Helper for files stored in S3 with their metadata in
|
|
61
|
+
* Helper for files stored in S3 with their metadata in the database — pass
|
|
62
|
+
* `fileMetadataCollection(connection, 's3')` as the collection: on a SQL source the
|
|
63
|
+
* metadata lives in the table `s3_files`, not in MongoDB.
|
|
60
64
|
*
|
|
61
65
|
* Counterpart of GridFSHelper: same operations, S3 as the byte store and
|
|
62
66
|
* `s3-files` as the metadata store.
|
|
@@ -81,7 +85,7 @@ export class S3FileHelper {
|
|
|
81
85
|
metadata?: Record<string, any>;
|
|
82
86
|
},
|
|
83
87
|
): Promise<S3FileInfo> {
|
|
84
|
-
const _id =
|
|
88
|
+
const _id = newObjectId();
|
|
85
89
|
const key = _id.toHexString();
|
|
86
90
|
|
|
87
91
|
// A stream is never read into a Buffer here. Doing so — which every caller used to do —
|
|
@@ -126,7 +130,7 @@ export class S3FileHelper {
|
|
|
126
130
|
sourceKey: string;
|
|
127
131
|
},
|
|
128
132
|
): Promise<S3FileInfo> {
|
|
129
|
-
const _id =
|
|
133
|
+
const _id = newObjectId();
|
|
130
134
|
await s3Service.copyObject(options.sourceKey, _id.toHexString(), options.sourceBucket, options.contentType);
|
|
131
135
|
|
|
132
136
|
return S3FileHelper.recordFile(s3Service, collection, _id, {
|
|
@@ -206,7 +210,7 @@ export class S3FileHelper {
|
|
|
206
210
|
collection: FileCollection,
|
|
207
211
|
id: string | Types.ObjectId,
|
|
208
212
|
): Promise<void> {
|
|
209
|
-
const objectId = typeof id === 'string' ?
|
|
213
|
+
const objectId = typeof id === 'string' ? newObjectId(id) : id;
|
|
210
214
|
await s3Service.deleteObject(objectId.toHexString());
|
|
211
215
|
await collection.deleteOne({ _id: objectId });
|
|
212
216
|
}
|
|
@@ -215,7 +219,7 @@ export class S3FileHelper {
|
|
|
215
219
|
* Get the download stream of a file
|
|
216
220
|
*/
|
|
217
221
|
static async getStream(s3Service: CoreS3Service, id: string | Types.ObjectId): Promise<Readable> {
|
|
218
|
-
const objectId = typeof id === 'string' ?
|
|
222
|
+
const objectId = typeof id === 'string' ? newObjectId(id) : id;
|
|
219
223
|
return (await s3Service.getObject(objectId.toHexString())).body;
|
|
220
224
|
}
|
|
221
225
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Module } from '@nestjs/common';
|
|
2
|
-
import {
|
|
2
|
+
import { ModuleRef } from '@nestjs/core';
|
|
3
|
+
import { HealthIndicatorService, MongooseHealthIndicator, TerminusModule } from '@nestjs/terminus';
|
|
4
|
+
|
|
5
|
+
import { getConnectionToken } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
3
6
|
|
|
4
7
|
import { CoreHealthCheckController } from './core-health-check.controller.js';
|
|
5
8
|
import { CoreHealthCheckResolver } from './core-health-check.resolver.js';
|
|
@@ -12,6 +15,17 @@ import { CoreHealthCheckService } from './core-health-check.service.js';
|
|
|
12
15
|
@Module({
|
|
13
16
|
controllers: [CoreHealthCheckController],
|
|
14
17
|
imports: [TerminusModule],
|
|
15
|
-
providers: [
|
|
18
|
+
providers: [
|
|
19
|
+
CoreHealthCheckService,
|
|
20
|
+
CoreHealthCheckResolver,
|
|
21
|
+
{
|
|
22
|
+
inject: [ModuleRef, HealthIndicatorService, { optional: true, token: getConnectionToken() }],
|
|
23
|
+
provide: MongooseHealthIndicator,
|
|
24
|
+
// Terminus' indicator requires Mongoose as it is constructed. Without a MongoDB connection (a project on
|
|
25
|
+
// PostgreSQL alone) there is nothing for it to ping, and no Mongoose to require: the service skips the ping
|
|
26
|
+
useFactory: (moduleRef: ModuleRef, indicators: HealthIndicatorService, connection?: unknown) =>
|
|
27
|
+
connection ? new MongooseHealthIndicator(moduleRef, indicators) : null,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
16
30
|
})
|
|
17
31
|
export class CoreHealthCheckModule {}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
1
|
+
import { Inject, Injectable, Optional } from '@nestjs/common';
|
|
2
2
|
import {
|
|
3
3
|
DiskHealthIndicator,
|
|
4
4
|
type DiskHealthIndicatorOptions,
|
|
5
5
|
HealthCheckResult,
|
|
6
6
|
HealthCheckService,
|
|
7
|
+
HealthIndicatorService,
|
|
7
8
|
MemoryHealthIndicator,
|
|
8
9
|
MongooseHealthIndicator,
|
|
9
10
|
type MongoosePingCheckSettings,
|
|
10
11
|
} from '@nestjs/terminus';
|
|
11
12
|
|
|
12
13
|
import { getBuildInfo } from '../../common/helpers/meta.helper.js';
|
|
14
|
+
import { getPersistenceRuntime } from '../../common/persistence/persistence-runtime.registry.js';
|
|
13
15
|
import { ConfigService } from '../../common/services/config.service.js';
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -20,15 +22,18 @@ import { ConfigService } from '../../common/services/config.service.js';
|
|
|
20
22
|
export class CoreHealthCheckService {
|
|
21
23
|
constructor(
|
|
22
24
|
protected config: ConfigService,
|
|
23
|
-
|
|
25
|
+
// Explicit token: a union type gives Nest no class to inject; `null` where no MongoDB is configured (module factory)
|
|
26
|
+
@Inject(MongooseHealthIndicator) protected db: MongooseHealthIndicator | null,
|
|
24
27
|
protected disk: DiskHealthIndicator,
|
|
25
28
|
protected health: HealthCheckService,
|
|
26
29
|
protected memory: MemoryHealthIndicator,
|
|
30
|
+
@Optional() protected indicators?: HealthIndicatorService,
|
|
27
31
|
) {}
|
|
28
32
|
|
|
29
33
|
healthCheck(): Promise<HealthCheckResult> {
|
|
30
34
|
const healthIndicatorFunctions = [];
|
|
31
|
-
|
|
35
|
+
// The MongoDB ping where MongoDB is configured — a project on PostgreSQL alone has no MongoDB to ping
|
|
36
|
+
if (this.db && this.config.get<boolean>('healthCheck.configs.database.enabled')) {
|
|
32
37
|
healthIndicatorFunctions.push(() => {
|
|
33
38
|
// `timeout` stays part of the config contract, but @nestjs/terminus 12 deprecated it on the
|
|
34
39
|
// indicator in favour of `.withTimeout()` on the returned attempt — translate it here, so the
|
|
@@ -45,6 +50,23 @@ export class CoreHealthCheckService {
|
|
|
45
50
|
return timeout === undefined ? attempt : attempt.withTimeout(timeout);
|
|
46
51
|
});
|
|
47
52
|
}
|
|
53
|
+
if (this.config.get<boolean>('healthCheck.configs.database.enabled')) {
|
|
54
|
+
// Every SQL source answers on its own key, next to the MongoDB ping: `<key>:<source>` (`database:default`). A
|
|
55
|
+
// database the application cannot reach is down, whichever one it is
|
|
56
|
+
const key = this.config.get<string>('healthCheck.configs.database.key') ?? 'database';
|
|
57
|
+
const timeout =
|
|
58
|
+
this.config.get<MongoosePingCheckSettings>('healthCheck.configs.database.options')?.timeout ?? 1000;
|
|
59
|
+
for (const source of getPersistenceRuntime()?.sqlSources() ?? []) {
|
|
60
|
+
if (this.indicators) {
|
|
61
|
+
healthIndicatorFunctions.push(() =>
|
|
62
|
+
this.indicators
|
|
63
|
+
.check(`${key}:${source.name}`)
|
|
64
|
+
.attempt(() => source.ping())
|
|
65
|
+
.withTimeout(timeout),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
48
70
|
if (this.config.get<boolean>('healthCheck.configs.memoryHeap.enabled')) {
|
|
49
71
|
healthIndicatorFunctions.push(() =>
|
|
50
72
|
this.memory.checkHeap(
|
|
@@ -33,11 +33,12 @@ Do NOT set `hub` in the `production` block unless you intend the cockpit to be r
|
|
|
33
33
|
| Diagnostics | `/hub/diagnostics` | heap/rss, node/platform, collector buffer levels |
|
|
34
34
|
| Logs | `/hub/logs` | in-memory log ring buffer (redacted) |
|
|
35
35
|
| Request Traces | `/hub/traces` | HTTP timing middleware |
|
|
36
|
-
| Query Performance | `/hub/queries` | MongoDB driver command monitoring (opt-in)
|
|
36
|
+
| Query Performance | `/hub/queries` | MongoDB driver command monitoring (opt-in; MongoDB only) |
|
|
37
37
|
| Cron Jobs | `/hub/cron` | `@nestjs/schedule` `SchedulerRegistry` (optional) |
|
|
38
|
-
| Database | `/hub/db` | dbStats / per-collection collStats
|
|
38
|
+
| Database | `/hub/db` | dbStats / per-collection collStats (MongoDB only) |
|
|
39
39
|
| Models / ERD | `/hub/models` | Mongoose schemas → Mermaid ER diagram |
|
|
40
|
-
|
|
|
40
|
+
| Persistence | `/hub/persistence` | data sources, and per model: source, database, capabilities |
|
|
41
|
+
| Migrations | `/hub/migrations` | `MigrationRunner` status + run/rollback (MongoDB or SQL state) |
|
|
41
42
|
| Files | `/hub/files` | listing + delete across all three storage drivers |
|
|
42
43
|
| Config | `/hub/config` | full config, secrets masked |
|
|
43
44
|
| Auth Migration | `/hub/auth-migration` | Legacy → IAM progress (BetterAuth, optional) |
|
|
@@ -50,17 +51,25 @@ Do NOT set `hub` in the `production` block unless you intend the cockpit to be r
|
|
|
50
51
|
Each panel has a `*.json` sidecar (the stable data contract) that the client polls. Optional sources
|
|
51
52
|
degrade to an "unavailable" state instead of erroring.
|
|
52
53
|
|
|
54
|
+
With a SQL data source (`database`, see `.claude/rules/configurable-features.md` → Data Sources) the Database and
|
|
55
|
+
Query Performance panels cover the MongoDB connection only and report "unavailable" without one. The Migrations panel
|
|
56
|
+
reads the state from the store the framework keeps for the default source: on a SQL default source the
|
|
57
|
+
`lt_migrations` table, through the owner connection (`database.ownerUrl`, required there). That presumes
|
|
58
|
+
`migrations-utils/migrate.js` passes `database.ownerUrl` to `createMigrationStore()` (see the migrate README). While
|
|
59
|
+
it still passes the MongoDB URI, the table stays empty and the MongoDB collection lists the applied migrations; the
|
|
60
|
+
panel then reports that conflict and refuses Run and Rollback, which would apply the migrations a second time.
|
|
61
|
+
|
|
53
62
|
### Files panel
|
|
54
63
|
|
|
55
64
|
The panel reads all three file metadata stores, not just GridFS — the same three
|
|
56
|
-
`CoreFileService.findFileInfo()` consults,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
| Store |
|
|
60
|
-
| ------------ |
|
|
61
|
-
| `s3` | `s3-files`
|
|
62
|
-
| `filesystem` | `filesystem-files`
|
|
63
|
-
| `gridfs` | `<bucket>.files` (default `fs.files`) | MongoDB |
|
|
65
|
+
`CoreFileService.findFileInfo()` consults, wherever `database` routes their metadata
|
|
66
|
+
(`fileMetadataCollection()`):
|
|
67
|
+
|
|
68
|
+
| Store | Metadata | Bytes live in |
|
|
69
|
+
| ------------ | ------------------------------------------------------- | ------------------------------- |
|
|
70
|
+
| `s3` | collection `s3-files`, on a SQL source table `s3_files` | the S3 bucket |
|
|
71
|
+
| `filesystem` | `filesystem-files`, on a SQL source `filesystem_files` | `file.storageDir` on local disk |
|
|
72
|
+
| `gridfs` | `<bucket>.files` (default `fs.files`), always MongoDB | MongoDB |
|
|
64
73
|
|
|
65
74
|
Every row carries the `store` it was found in, and `files.json` reports a per-store `count` so an
|
|
66
75
|
empty store reads as **empty** rather than as _"this panel does not cover your driver"_. Until
|
|
@@ -156,6 +156,11 @@ export class CoreHubController {
|
|
|
156
156
|
this.sendJson(res, this.dbService.getModels());
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
@Get('persistence.json')
|
|
160
|
+
persistenceJson(@Res() res: Response): void {
|
|
161
|
+
this.sendJson(res, this.sourcesService.getPersistence());
|
|
162
|
+
}
|
|
163
|
+
|
|
159
164
|
/**
|
|
160
165
|
* ADMIN-gated auth probe AND cockpit-chrome payload: 200 returns the navigation, environment badge,
|
|
161
166
|
* version and external links the client uses to build the layout; 401/403 keeps the shell showing
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Inject, Injectable, 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 { getBuildInfo } from '../../common/helpers/meta.helper.js';
|
|
@@ -479,6 +479,29 @@ export function getHubClientJs(): string {
|
|
|
479
479
|
}, function (e) { clear(content); content.appendChild(unavailable('Failed to load: ' + e.message)); });
|
|
480
480
|
};
|
|
481
481
|
|
|
482
|
+
Hub.panels.persistence = function (content) {
|
|
483
|
+
// Routing is fixed at boot; load once instead of polling.
|
|
484
|
+
hubFetch('/persistence.json').then(function (d) {
|
|
485
|
+
clear(content);
|
|
486
|
+
if (d && d.available === false) { content.appendChild(unavailable(d.hint)); return; }
|
|
487
|
+
content.appendChild(el('h3', { text: 'Data sources' }));
|
|
488
|
+
content.appendChild(table([
|
|
489
|
+
{ key: 'name', label: 'Source', render: function (r) { return r.name + (r.name === d.defaultSource ? ' (default)' : ''); } },
|
|
490
|
+
{ key: 'driver', label: 'Database' },
|
|
491
|
+
{ key: 'engine', label: 'Engine', render: function (r) { return r.engine || '–'; } },
|
|
492
|
+
{ key: 'host', label: 'Host' },
|
|
493
|
+
{ key: 'ownerConfigured', label: 'Owner role', render: function (r) { return r.driver === 'mongodb' ? '–' : (r.ownerConfigured ? 'configured' : 'verify only'); } },
|
|
494
|
+
], d.sources || []));
|
|
495
|
+
content.appendChild(el('h3', { text: 'Models (' + (d.models || []).length + ')' }));
|
|
496
|
+
content.appendChild(table([
|
|
497
|
+
{ key: 'name', label: 'Model' },
|
|
498
|
+
{ key: 'source', label: 'Source', render: function (r) { return r.source || '–'; } },
|
|
499
|
+
{ key: 'driver', label: 'Store', render: function (r) { return r.driver || 'not created yet'; } },
|
|
500
|
+
{ key: 'capabilities', label: 'Capabilities', render: function (r) { return (r.capabilities || []).join(', ') || '–'; } },
|
|
501
|
+
], d.models || []));
|
|
502
|
+
}, function (e) { clear(content); content.appendChild(unavailable('Failed to load: ' + e.message)); });
|
|
503
|
+
};
|
|
504
|
+
|
|
482
505
|
Hub.panels.config = function (content) {
|
|
483
506
|
hubFetch('/config.json').then(function (d) { clear(content); content.appendChild(el('p', { class: 'hub-hint', text: 'Secrets are masked.' })); content.appendChild(jsonView(d)); },
|
|
484
507
|
function (e) { clear(content); content.appendChild(unavailable('Failed to load: ' + e.message)); });
|
|
@@ -39,6 +39,12 @@ export const HubActionMessage = {
|
|
|
39
39
|
missingHubRequestHeader: 'Missing X-Hub-Request header.',
|
|
40
40
|
/** Any action that needs the Mongo connection while it is unavailable. */
|
|
41
41
|
mongoUnavailable: 'No MongoDB connection is available.',
|
|
42
|
+
/** Migrations on a SQL default source run as the table owner. */
|
|
43
|
+
sqlOwnerMissing:
|
|
44
|
+
'The migration state of a SQL default source is read and written as the table owner — configure database.ownerUrl.',
|
|
45
|
+
/** SQL default source with an empty `lt_migrations` while the MongoDB collection lists applied migrations. */
|
|
46
|
+
migrationStateInMongo: (collection: string) =>
|
|
47
|
+
`The default source is a SQL database, but its lt_migrations table is empty while the MongoDB collection "${collection}" lists applied migrations — migrations-utils/migrate.js still keeps the state in MongoDB. Pass database.ownerUrl to createMigrationStore() and move the state to the table; until then the Hub neither shows nor runs migrations, which would apply them again.`,
|
|
42
48
|
/** Migrations action while no Mongo URI is configured. */
|
|
43
49
|
mongoUriMissing: 'No MongoDB URI is configured.',
|
|
44
50
|
/** Test mail: no recipient supplied. */
|
|
@@ -32,6 +32,7 @@ export const HUB_PANELS: readonly HubPanel[] = [
|
|
|
32
32
|
{ group: 'Runtime', id: 'cron', json: 'cron.json', optional: true, path: 'cron', title: 'Cron Jobs' },
|
|
33
33
|
{ group: 'Data', id: 'db', json: 'db.json', path: 'db', title: 'Database' },
|
|
34
34
|
{ group: 'Data', id: 'models', json: 'models.json', path: 'models', title: 'Models / ERD' },
|
|
35
|
+
{ group: 'Data', id: 'persistence', json: 'persistence.json', path: 'persistence', title: 'Persistence' },
|
|
35
36
|
{ group: 'Data', id: 'migrations', json: 'migrations.json', path: 'migrations', title: 'Migrations' },
|
|
36
37
|
{ group: 'Data', id: 'files', json: 'files.json', path: 'files', title: 'Files' },
|
|
37
38
|
{ group: 'Data', id: 'config', json: 'config.json', path: 'config', title: 'Config' },
|
|
@@ -71,12 +71,19 @@ export interface HubModelsData {
|
|
|
71
71
|
relationCount: number;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/** Persistence panel: where each model is stored, on which database and engine, with which capabilities */
|
|
75
|
+
export interface HubPersistenceData {
|
|
76
|
+
defaultSource?: string;
|
|
77
|
+
models: { capabilities: string[]; driver?: string; name: string; source?: string }[];
|
|
78
|
+
sources: { driver: string; engine?: string; host: string; name: string; ownerConfigured: boolean }[];
|
|
79
|
+
}
|
|
80
|
+
|
|
74
81
|
export interface HubMigrationsData {
|
|
75
82
|
completed: string[];
|
|
76
83
|
dirAvailable: boolean;
|
|
77
84
|
lastRun?: string;
|
|
78
85
|
pending: string[];
|
|
79
|
-
source: 'collection' | 'runner';
|
|
86
|
+
source: 'collection' | 'runner' | 'table';
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
/**
|