@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,66 @@
|
|
|
1
|
+
import type { Collection } from 'mongodb';
|
|
2
|
+
|
|
3
|
+
import type { LockStore } from './lock-store.interface.js';
|
|
4
|
+
import { MongoLockStore } from './mongo-lock-store.js';
|
|
5
|
+
import { getPersistenceRuntime } from './persistence-runtime.registry.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The framework's own locks — the system-setup claim, the cron lease and the migration lock — on a `LockStore`.
|
|
9
|
+
*
|
|
10
|
+
* On MongoDB each one keeps the document 12.0.0 wrote (same collection, same key, same timestamp field): during a
|
|
11
|
+
* rolling deploy an older replica still claims through its own code, and only one document per lock lets both
|
|
12
|
+
* versions see the same lease. The `MongoLockStore` options below encode each format. On a SQL default source the
|
|
13
|
+
* locks live in the lease table, namespaced per consumer.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Cron leases: `{ _id: <tick key>, expiresAt }` — already the lease format, so no legacy rule is needed */
|
|
17
|
+
export const CRON_LOCK_COLLECTION = 'cron-locks';
|
|
18
|
+
|
|
19
|
+
export const SYSTEM_SETUP_LOCK_COLLECTION = 'system-setup-locks';
|
|
20
|
+
export const SYSTEM_SETUP_LOCK_KEY = 'initial-admin';
|
|
21
|
+
/** The claim is taken over once it is this old: a replica killed between claiming and creating must not block setup */
|
|
22
|
+
export const SYSTEM_SETUP_CLAIM_STALE_AFTER_MS = 5 * 60_000;
|
|
23
|
+
|
|
24
|
+
export const MIGRATION_LOCK_KEY = 'lock';
|
|
25
|
+
/** A migration lock whose holder stopped heart-beating this long ago is broken */
|
|
26
|
+
export const MIGRATION_LOCK_STALE_AFTER_MS = 60_000;
|
|
27
|
+
|
|
28
|
+
export function cronMongoLocks(collection: Collection<any>): LockStore {
|
|
29
|
+
return new MongoLockStore(collection);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** `{ _id: 'initial-admin', claimedAt }` — expired once `claimedAt` is older than the stale period */
|
|
33
|
+
export function systemSetupMongoLocks(collection: Collection<any>): LockStore {
|
|
34
|
+
return new MongoLockStore(collection, {
|
|
35
|
+
legacyTimestamp: { field: 'claimedAt', staleAfterMs: SYSTEM_SETUP_CLAIM_STALE_AFTER_MS },
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* `{ lock: 'lock', owner, acquiredAt }` with a unique index on `lock` — `acquiredAt` is the holder's heartbeat, and
|
|
41
|
+
* a renewal refreshes it so an older waiter does not break a live lock
|
|
42
|
+
*/
|
|
43
|
+
export function migrationMongoLocks(collection: Collection<any>): LockStore {
|
|
44
|
+
return new MongoLockStore(collection, {
|
|
45
|
+
keyField: 'lock',
|
|
46
|
+
legacyTimestamp: { field: 'acquiredAt', staleAfterMs: MIGRATION_LOCK_STALE_AFTER_MS },
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The lease store of the default data source when it is a SQL database, its keys prefixed with `namespace` so the
|
|
52
|
+
* consumers sharing the one lease table cannot collide; `undefined` when the default source is MongoDB
|
|
53
|
+
*/
|
|
54
|
+
export async function defaultSqlLockStore(namespace: string): Promise<LockStore | undefined> {
|
|
55
|
+
const locks = await getPersistenceRuntime()?.defaultLockStore();
|
|
56
|
+
return locks ? namespacedLocks(locks, namespace) : undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function namespacedLocks(locks: LockStore, namespace: string): LockStore {
|
|
60
|
+
const key = (name: string) => `${namespace}:${name}`;
|
|
61
|
+
return {
|
|
62
|
+
release: (name, owner) => locks.release(key(name), owner),
|
|
63
|
+
renew: (name, owner, ttlSeconds) => locks.renew(key(name), owner, ttlSeconds),
|
|
64
|
+
tryAcquire: (name, owner, ttlSeconds) => locks.tryAcquire(key(name), owner, ttlSeconds),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Inject } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { getStoreToken } from './persistence.tokens.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Inject the data store of a model registered with `CorePersistenceModule.forFeature()` — the
|
|
7
|
+
* database-neutral counterpart of `@InjectModel()`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* constructor(@InjectStore(Project) private readonly projects: DataStore<Project>) {}
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function InjectStore(model: Function | string): ParameterDecorator & PropertyDecorator {
|
|
15
|
+
return Inject(getStoreToken(typeof model === 'string' ? model : model.name));
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Leases shared by every replica: "exactly one of N does this, and if it dies, somebody takes over".
|
|
3
|
+
*
|
|
4
|
+
* Expiry is part of the decision, never left to a background monitor: an expired lease is taken over by
|
|
5
|
+
* exactly one contender at the moment it is claimed. Import-free leaf (types only).
|
|
6
|
+
*/
|
|
7
|
+
export interface LockStore {
|
|
8
|
+
/** Release the lease — only by its owner. `true` when this owner held it. */
|
|
9
|
+
release(key: string, owner: string): Promise<boolean>;
|
|
10
|
+
/** Extend a lease this owner still holds. `false` when it expired or someone else took it. */
|
|
11
|
+
renew(key: string, owner: string, ttlSeconds: number): Promise<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* Take the lease when it is free or expired. Of N concurrent contenders exactly one gets `true`; a lease
|
|
14
|
+
* that is held and unexpired is never taken.
|
|
15
|
+
*/
|
|
16
|
+
tryAcquire(key: string, owner: string, ttlSeconds: number): Promise<boolean>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database-neutral description of a persisted model.
|
|
3
|
+
*
|
|
4
|
+
* The SQL side builds tables, columns, indexes and value mappings from these descriptors; the
|
|
5
|
+
* parity matrix and the Hub read them too. They describe what is STORED, not what the API exposes:
|
|
6
|
+
* a field without a persistence declaration is not part of a descriptor.
|
|
7
|
+
*
|
|
8
|
+
* Import-free on purpose (types only): every persistence file may depend on it without creating an
|
|
9
|
+
* import cycle — see `.claude/rules/architecture.md` → "DI Token Placement (SWC-Safe)".
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The storage kind of a field.
|
|
14
|
+
*
|
|
15
|
+
* - `enum`: a value from `enumValues`, stored as `enumBase`
|
|
16
|
+
* - `id`: an identifier of this or another record WITHOUT a declared target model
|
|
17
|
+
* - `ref`: an identifier of a record of the model named in `ref`
|
|
18
|
+
* - `object`: an embedded object whose shape is declared (`nested` holds its fields)
|
|
19
|
+
* - `json`: a value whose shape is NOT declared (Mixed, Map, a plain class without `@Schema`)
|
|
20
|
+
*/
|
|
21
|
+
export type FieldKind =
|
|
22
|
+
| 'bigint'
|
|
23
|
+
| 'boolean'
|
|
24
|
+
| 'buffer'
|
|
25
|
+
| 'date'
|
|
26
|
+
| 'decimal'
|
|
27
|
+
| 'enum'
|
|
28
|
+
| 'id'
|
|
29
|
+
| 'json'
|
|
30
|
+
| 'number'
|
|
31
|
+
| 'object'
|
|
32
|
+
| 'ref'
|
|
33
|
+
| 'string'
|
|
34
|
+
| 'uuid';
|
|
35
|
+
|
|
36
|
+
export interface FieldDescriptor {
|
|
37
|
+
/** Literal default value; absent when the default is computed (a function) */
|
|
38
|
+
default?: unknown;
|
|
39
|
+
/** Base type of an enum's values */
|
|
40
|
+
enumBase?: 'number' | 'string';
|
|
41
|
+
/** Allowed values of an enum */
|
|
42
|
+
enumValues?: readonly unknown[];
|
|
43
|
+
/** TTL: the record expires this many seconds after the field's date */
|
|
44
|
+
expiresAfterSeconds?: number;
|
|
45
|
+
/** Whether a default exists at all (literal or computed) */
|
|
46
|
+
hasDefault: boolean;
|
|
47
|
+
/** Whether a single-field index exists on this field (declared, unique or TTL) */
|
|
48
|
+
index: boolean;
|
|
49
|
+
/** Whether the field holds a list of `kind` values */
|
|
50
|
+
isArray: boolean;
|
|
51
|
+
kind: FieldKind;
|
|
52
|
+
/** Values are lowercased before they are stored */
|
|
53
|
+
lowercase: boolean;
|
|
54
|
+
name: string;
|
|
55
|
+
/** Fields of an embedded object (`kind: 'object'`) */
|
|
56
|
+
nested?: Record<string, FieldDescriptor>;
|
|
57
|
+
/** Target model of a reference (`kind: 'ref'`) */
|
|
58
|
+
ref?: string;
|
|
59
|
+
/**
|
|
60
|
+
* The field's previous name: a SQL store renames the column instead of adding a new, empty one. Declared, never
|
|
61
|
+
* guessed (plan §3.12) — MongoDB documents keep the old key until a migration moves it.
|
|
62
|
+
*/
|
|
63
|
+
renamedFrom?: string;
|
|
64
|
+
required: boolean;
|
|
65
|
+
/** `false` when the field is excluded from reads unless explicitly selected (`select: false`) */
|
|
66
|
+
select: boolean;
|
|
67
|
+
sparse: boolean;
|
|
68
|
+
/** Values are trimmed before they are stored */
|
|
69
|
+
trim: boolean;
|
|
70
|
+
unique: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface IndexDescriptor {
|
|
74
|
+
/** Field → direction or index type (`1`, `-1`, `'text'`, …), in declaration order */
|
|
75
|
+
fields: Record<string, number | string>;
|
|
76
|
+
/** Index options as declared (`unique`, `sparse`, `expireAfterSeconds`, `partialFilterExpression`, …) */
|
|
77
|
+
options: Record<string, unknown>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface ModelDescriptor {
|
|
81
|
+
/** Explicit collection / table name, when the model declares one */
|
|
82
|
+
collection?: string;
|
|
83
|
+
fields: Record<string, FieldDescriptor>;
|
|
84
|
+
indexes: IndexDescriptor[];
|
|
85
|
+
name: string;
|
|
86
|
+
/** Whether the model carries a `tenantId` — the same criterion the tenant plugin uses */
|
|
87
|
+
tenantScoped: boolean;
|
|
88
|
+
/** `createdAt` / `updatedAt` maintenance: `true`, `false`, or the configured field names */
|
|
89
|
+
timestamps: boolean | { createdAt: false | string; updatedAt: false | string };
|
|
90
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import type { FieldDescriptor, FieldKind, IndexDescriptor, ModelDescriptor } from './model-descriptor.interface.js';
|
|
2
|
+
import { declaredSchemaView } from './mongo/declared-schema.view.js';
|
|
3
|
+
import { type DeclaredSchema, isDeclaredSchema } from './mongo/model-declarations.js';
|
|
4
|
+
import { SchemaFactory } from './mongo/mongoose-compat.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Registry of database-neutral model descriptors.
|
|
8
|
+
*
|
|
9
|
+
* The descriptors are derived from the model's Mongoose schema where Mongoose is installed — what MongoDB stores,
|
|
10
|
+
* and therefore the most faithful source: it covers fields declared through `@UnifiedField({ mongoose })` and through
|
|
11
|
+
* a plain `@Prop()` alike, which consumer projects mix freely. `SchemaFactory.createForClass` works without a
|
|
12
|
+
* connection, so a descriptor exists before any database is reached. Where Mongoose is NOT installed (12.1.0+, a
|
|
13
|
+
* project on PostgreSQL alone), the schema is the recorded declaration (`DeclaredSchema`), read through a view that
|
|
14
|
+
* builds the paths and indexes exactly as Mongoose would (`mongo/declared-schema.view.ts`); the snapshot of every
|
|
15
|
+
* model the framework ships proves both sources agree.
|
|
16
|
+
*
|
|
17
|
+
* Only the schema's own declarations are read — never documents — so describing a model is free of
|
|
18
|
+
* side effects and safe at boot.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const descriptorsByName = new Map<string, ModelDescriptor>();
|
|
22
|
+
const descriptorsByClass = new WeakMap<object, ModelDescriptor>();
|
|
23
|
+
|
|
24
|
+
/** Mongoose's version key is bookkeeping of the Mongo driver, not model data. */
|
|
25
|
+
const IGNORED_PATHS = new Set(['__v']);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Minimal structural view of a Mongoose schema — `import type` would tie the descriptor to the
|
|
29
|
+
* installed mongoose version's generics, and only these members are read.
|
|
30
|
+
*/
|
|
31
|
+
interface SchemaLike {
|
|
32
|
+
eachPath(fn: (path: string, schemaType: any) => void): unknown;
|
|
33
|
+
get(key: string): unknown;
|
|
34
|
+
indexes(): Array<[Record<string, number | string>, Record<string, unknown>?]>;
|
|
35
|
+
path(path: string): unknown;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Describe a schema under the given model name.
|
|
40
|
+
*/
|
|
41
|
+
export function describeSchema(name: string, given: DeclaredSchema | SchemaLike): ModelDescriptor {
|
|
42
|
+
const schema: SchemaLike = isDeclaredSchema(given) ? declaredSchemaView(given) : given;
|
|
43
|
+
const indexes = describeIndexes(schema);
|
|
44
|
+
const descriptor: ModelDescriptor = {
|
|
45
|
+
fields: describeFields(schema, indexes),
|
|
46
|
+
indexes,
|
|
47
|
+
name,
|
|
48
|
+
tenantScoped: !!schema.path('tenantId'),
|
|
49
|
+
timestamps: describeTimestamps(schema.get('timestamps')),
|
|
50
|
+
};
|
|
51
|
+
const collection = schema.get('collection');
|
|
52
|
+
if (typeof collection === 'string' && collection) {
|
|
53
|
+
descriptor.collection = collection;
|
|
54
|
+
}
|
|
55
|
+
return descriptor;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Describe a model class (decorated with `@Schema()`), cached per class.
|
|
60
|
+
*
|
|
61
|
+
* The model name is the class name — the name `MongooseModule.forFeature([{ name: X.name, … }])` uses.
|
|
62
|
+
*/
|
|
63
|
+
export function describeModelClass(modelClass: abstract new (...args: any[]) => any): ModelDescriptor {
|
|
64
|
+
const cached = descriptorsByClass.get(modelClass);
|
|
65
|
+
if (cached) {
|
|
66
|
+
return cached;
|
|
67
|
+
}
|
|
68
|
+
const descriptor = describeSchema(modelClass.name, SchemaFactory.createForClass(modelClass as any));
|
|
69
|
+
descriptorsByClass.set(modelClass, descriptor);
|
|
70
|
+
return descriptor;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Register the schema a model is persisted with, under its model name. A later registration under
|
|
75
|
+
* the same name replaces the earlier one — the last `forFeature` wins, as it does in Mongoose.
|
|
76
|
+
*/
|
|
77
|
+
export function registerModelSchema(name: string, schema: DeclaredSchema | SchemaLike): ModelDescriptor {
|
|
78
|
+
const descriptor = describeSchema(name, schema);
|
|
79
|
+
descriptorsByName.set(name, descriptor);
|
|
80
|
+
return descriptor;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** The descriptor registered under a model name, if any. */
|
|
84
|
+
export function getModelDescriptor(name: string): ModelDescriptor | undefined {
|
|
85
|
+
return descriptorsByName.get(name);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Every registered descriptor, keyed by model name. */
|
|
89
|
+
export function getModelDescriptors(): ReadonlyMap<string, ModelDescriptor> {
|
|
90
|
+
return descriptorsByName;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ---------------------------------------------------------------------------------------------
|
|
94
|
+
// Internals
|
|
95
|
+
// ---------------------------------------------------------------------------------------------
|
|
96
|
+
|
|
97
|
+
function describeIndexes(schema: SchemaLike): IndexDescriptor[] {
|
|
98
|
+
return schema.indexes().map(([fields, options]) => ({ fields: { ...fields }, options: { ...options } }));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function describeTimestamps(value: unknown): ModelDescriptor['timestamps'] {
|
|
102
|
+
if (value && typeof value === 'object') {
|
|
103
|
+
const config = value as { createdAt?: boolean | string; updatedAt?: boolean | string };
|
|
104
|
+
const name = (option: boolean | string | undefined, fallback: string): false | string =>
|
|
105
|
+
option === false ? false : typeof option === 'string' ? option : fallback;
|
|
106
|
+
return { createdAt: name(config.createdAt, 'createdAt'), updatedAt: name(config.updatedAt, 'updatedAt') };
|
|
107
|
+
}
|
|
108
|
+
return value === true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Collect the schema's paths into fields. Dotted paths of a raw nested object (`{ meta: { score } }`
|
|
113
|
+
* becomes `meta.score`) are grouped back into one object field, because that is what is stored: one
|
|
114
|
+
* embedded object, not columns named with dots.
|
|
115
|
+
*/
|
|
116
|
+
function describeFields(schema: SchemaLike, indexes: IndexDescriptor[]): Record<string, FieldDescriptor> {
|
|
117
|
+
const entries: Array<[string, any]> = [];
|
|
118
|
+
schema.eachPath((path, schemaType) => {
|
|
119
|
+
// `labels.$*` is the value type of a Map, which the Map field itself already stands for
|
|
120
|
+
if (IGNORED_PATHS.has(path) || path.includes('$*')) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
entries.push([path, schemaType]);
|
|
124
|
+
});
|
|
125
|
+
return buildFields(entries, indexes, '');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function buildFields(
|
|
129
|
+
entries: Array<[string, any]>,
|
|
130
|
+
indexes: IndexDescriptor[],
|
|
131
|
+
prefix: string,
|
|
132
|
+
): Record<string, FieldDescriptor> {
|
|
133
|
+
const fields: Record<string, FieldDescriptor> = {};
|
|
134
|
+
const groups = new Map<string, Array<[string, any]>>();
|
|
135
|
+
for (const [path, schemaType] of entries) {
|
|
136
|
+
const dot = path.indexOf('.');
|
|
137
|
+
if (dot === -1) {
|
|
138
|
+
fields[path] = describeField(path, schemaType, indexes, `${prefix}${path}`);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const head = path.slice(0, dot);
|
|
142
|
+
const group = groups.get(head) ?? [];
|
|
143
|
+
group.push([path.slice(dot + 1), schemaType]);
|
|
144
|
+
groups.set(head, group);
|
|
145
|
+
}
|
|
146
|
+
for (const [head, group] of groups) {
|
|
147
|
+
fields[head] = clean({
|
|
148
|
+
...baseField(head),
|
|
149
|
+
kind: 'object',
|
|
150
|
+
nested: buildFields(group, indexes, `${prefix}${head}.`),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return fields;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function describeField(name: string, schemaType: any, indexes: IndexDescriptor[], fullPath: string): FieldDescriptor {
|
|
157
|
+
const options: Record<string, any> = schemaType?.options ?? {};
|
|
158
|
+
const field: FieldDescriptor = {
|
|
159
|
+
...baseField(name),
|
|
160
|
+
...describeKind(schemaType, options),
|
|
161
|
+
lowercase: options.lowercase === true,
|
|
162
|
+
renamedFrom: typeof options.renamedFrom === 'string' ? options.renamedFrom : undefined,
|
|
163
|
+
required: !!schemaType?.isRequired,
|
|
164
|
+
select: options.select !== false,
|
|
165
|
+
sparse: !!options.sparse,
|
|
166
|
+
trim: options.trim === true,
|
|
167
|
+
unique: options.unique === true || (Array.isArray(options.unique) && options.unique[0] === true),
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const defaultValue = schemaType?.defaultValue ?? options.default;
|
|
171
|
+
if (defaultValue !== undefined) {
|
|
172
|
+
field.hasDefault = true;
|
|
173
|
+
if (typeof defaultValue !== 'function') {
|
|
174
|
+
field.default = defaultValue;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Read the TTL from the schema's index list: Mongoose has already turned `expires: '1h'` into seconds there
|
|
179
|
+
const ttl = indexes.find(
|
|
180
|
+
(index) =>
|
|
181
|
+
Object.keys(index.fields).length === 1 && fullPath in index.fields && 'expireAfterSeconds' in index.options,
|
|
182
|
+
);
|
|
183
|
+
if (ttl) {
|
|
184
|
+
field.expiresAfterSeconds = Number(ttl.options.expireAfterSeconds);
|
|
185
|
+
}
|
|
186
|
+
field.index = !!options.index || field.unique || !!ttl;
|
|
187
|
+
|
|
188
|
+
return clean(field);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function baseField(name: string): FieldDescriptor {
|
|
192
|
+
return {
|
|
193
|
+
hasDefault: false,
|
|
194
|
+
index: false,
|
|
195
|
+
isArray: false,
|
|
196
|
+
kind: 'json',
|
|
197
|
+
lowercase: false,
|
|
198
|
+
name,
|
|
199
|
+
required: false,
|
|
200
|
+
select: true,
|
|
201
|
+
sparse: false,
|
|
202
|
+
trim: false,
|
|
203
|
+
unique: false,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
type KindPart = Pick<FieldDescriptor, 'enumBase' | 'enumValues' | 'isArray' | 'kind' | 'nested' | 'ref'>;
|
|
208
|
+
|
|
209
|
+
function describeKind(schemaType: any, options: Record<string, any>): KindPart {
|
|
210
|
+
// An array of sub-documents declared with @Schema
|
|
211
|
+
if (schemaType?.$isMongooseDocumentArray && schemaType.schema) {
|
|
212
|
+
return { isArray: true, kind: 'object', nested: nestedFields(schemaType.schema) };
|
|
213
|
+
}
|
|
214
|
+
// A single sub-document declared with @Schema
|
|
215
|
+
if (schemaType?.$isSingleNested && schemaType.schema) {
|
|
216
|
+
return { isArray: false, kind: 'object', nested: nestedFields(schemaType.schema) };
|
|
217
|
+
}
|
|
218
|
+
if (schemaType?.instance === 'Array') {
|
|
219
|
+
const element = schemaType.embeddedSchemaType ?? schemaType.caster;
|
|
220
|
+
// An array of arrays has no column shape; it is stored as JSON
|
|
221
|
+
if (!element || element.instance === 'Array') {
|
|
222
|
+
return { isArray: false, kind: 'json' };
|
|
223
|
+
}
|
|
224
|
+
return { ...scalarKind(element, element.options ?? {}), isArray: true };
|
|
225
|
+
}
|
|
226
|
+
return { ...scalarKind(schemaType, options), isArray: false };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function scalarKind(schemaType: any, options: Record<string, any>): Omit<KindPart, 'isArray'> {
|
|
230
|
+
// A reference is recognised by its declaration, not by its type: `type: Types.ObjectId` (the bson
|
|
231
|
+
// class rather than `Schema.Types.ObjectId`) makes Mongoose report the path as Mixed, yet it is a ref.
|
|
232
|
+
if (options.ref !== undefined || options.refPath !== undefined) {
|
|
233
|
+
const ref = typeof options.ref === 'string' ? options.ref : options.ref?.modelName;
|
|
234
|
+
return ref ? { kind: 'ref', ref } : { kind: 'ref' };
|
|
235
|
+
}
|
|
236
|
+
const instance: string | undefined = schemaType?.instance;
|
|
237
|
+
if (instance === 'String' || instance === 'Number') {
|
|
238
|
+
const base = instance === 'String' ? 'string' : 'number';
|
|
239
|
+
const values = enumValuesOf(schemaType, options, base);
|
|
240
|
+
return values ? { enumBase: base, enumValues: values, kind: 'enum' } : { kind: base };
|
|
241
|
+
}
|
|
242
|
+
const kinds: Record<string, FieldKind> = {
|
|
243
|
+
BigInt: 'bigint',
|
|
244
|
+
Boolean: 'boolean',
|
|
245
|
+
Buffer: 'buffer',
|
|
246
|
+
Date: 'date',
|
|
247
|
+
Decimal128: 'decimal',
|
|
248
|
+
Double: 'number',
|
|
249
|
+
Int32: 'number',
|
|
250
|
+
ObjectId: 'id',
|
|
251
|
+
UUID: 'uuid',
|
|
252
|
+
};
|
|
253
|
+
// Mixed, Map and anything unknown carry no declared shape
|
|
254
|
+
return { kind: (instance && kinds[instance]) || 'json' };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function enumValuesOf(schemaType: any, options: Record<string, any>, base: 'number' | 'string'): unknown[] | undefined {
|
|
258
|
+
if (Array.isArray(schemaType?.enumValues) && schemaType.enumValues.length) {
|
|
259
|
+
return [...schemaType.enumValues];
|
|
260
|
+
}
|
|
261
|
+
const declared = options.enum?.values ?? options.enum;
|
|
262
|
+
if (Array.isArray(declared)) {
|
|
263
|
+
return declared.length ? [...declared] : undefined;
|
|
264
|
+
}
|
|
265
|
+
if (declared && typeof declared === 'object') {
|
|
266
|
+
// A TypeScript numeric enum maps both ways (`{ A: 0, 0: 'A' }`): keep only the values of the base type
|
|
267
|
+
const values = Object.values(declared).filter((value) => typeof value === base);
|
|
268
|
+
return values.length ? values : undefined;
|
|
269
|
+
}
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function nestedFields(schema: SchemaLike): Record<string, FieldDescriptor> {
|
|
274
|
+
return describeFields(schema, describeIndexes(schema));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Drop optional keys that are `undefined`, so descriptors compare and print without noise. */
|
|
278
|
+
function clean(field: FieldDescriptor): FieldDescriptor {
|
|
279
|
+
for (const key of Object.keys(field) as Array<keyof FieldDescriptor>) {
|
|
280
|
+
if (field[key] === undefined) {
|
|
281
|
+
delete field[key];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return field;
|
|
285
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { optionalMongoPackages } from './mongo-packages.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The collection name MongoDB gives a model that declares none — and therefore the name of its SQL table
|
|
5
|
+
* (`postgres-schema.compiler.ts` → `tableName()`), so a model keeps one name on every database.
|
|
6
|
+
*
|
|
7
|
+
* Where Mongoose is installed its CURRENT pluralizer decides, a project's own `mongoose.pluralize(fn)` (or `null`,
|
|
8
|
+
* which keeps the name) included. Without Mongoose the legacy rules below decide — Mongoose's default
|
|
9
|
+
* (`lib/helpers/pluralize.js`, MIT, © LearnBoost and Automattic, extracted by TJ Holowaychuk from `_ext.js`), copied
|
|
10
|
+
* unchanged so a model is named alike whether or not the project installs Mongoose;
|
|
11
|
+
* `tests/unit/collection-name.spec.ts` compares the two.
|
|
12
|
+
*/
|
|
13
|
+
export function defaultCollectionName(modelName: string): string {
|
|
14
|
+
const packages = optionalMongoPackages();
|
|
15
|
+
if (packages) {
|
|
16
|
+
const pluralize = packages.mongoose.pluralize();
|
|
17
|
+
return pluralize ? pluralize(modelName) : modelName;
|
|
18
|
+
}
|
|
19
|
+
return legacyPluralize(modelName);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const RULES: Array<[RegExp, string]> = [
|
|
23
|
+
[/human$/gi, 'humans'],
|
|
24
|
+
[/(m|wom)an$/gi, '$1en'],
|
|
25
|
+
[/(pe)rson$/gi, '$1ople'],
|
|
26
|
+
[/(child)$/gi, '$1ren'],
|
|
27
|
+
[/^(ox)$/gi, '$1en'],
|
|
28
|
+
[/(ax|test)is$/gi, '$1es'],
|
|
29
|
+
[/(octop|cact|foc|fung|nucle)us$/gi, '$1i'],
|
|
30
|
+
[/(alias|status|virus)$/gi, '$1es'],
|
|
31
|
+
[/(bu)s$/gi, '$1ses'],
|
|
32
|
+
[/(buffal|tomat|potat)o$/gi, '$1oes'],
|
|
33
|
+
[/([ti])um$/gi, '$1a'],
|
|
34
|
+
[/sis$/gi, 'ses'],
|
|
35
|
+
[/(?:([^f])fe|([lr])f)$/gi, '$1$2ves'],
|
|
36
|
+
[/(hive)$/gi, '$1s'],
|
|
37
|
+
[/([^aeiouy]|qu)y$/gi, '$1ies'],
|
|
38
|
+
[/(x|ch|ss|sh)$/gi, '$1es'],
|
|
39
|
+
[/(matr|vert|ind)ix|ex$/gi, '$1ices'],
|
|
40
|
+
[/([m|l])ouse$/gi, '$1ice'],
|
|
41
|
+
[/(kn|w|l)ife$/gi, '$1ives'],
|
|
42
|
+
[/(quiz)$/gi, '$1zes'],
|
|
43
|
+
[/^goose$/i, 'geese'],
|
|
44
|
+
[/s$/gi, 's'],
|
|
45
|
+
[/([^a-z])$/, '$1'],
|
|
46
|
+
[/$/gi, 's'],
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
const UNCOUNTABLES = new Set([
|
|
50
|
+
'advice',
|
|
51
|
+
'energy',
|
|
52
|
+
'excretion',
|
|
53
|
+
'digestion',
|
|
54
|
+
'cooperation',
|
|
55
|
+
'health',
|
|
56
|
+
'justice',
|
|
57
|
+
'labour',
|
|
58
|
+
'machinery',
|
|
59
|
+
'equipment',
|
|
60
|
+
'information',
|
|
61
|
+
'pollution',
|
|
62
|
+
'sewage',
|
|
63
|
+
'paper',
|
|
64
|
+
'money',
|
|
65
|
+
'species',
|
|
66
|
+
'series',
|
|
67
|
+
'rain',
|
|
68
|
+
'rice',
|
|
69
|
+
'fish',
|
|
70
|
+
'sheep',
|
|
71
|
+
'moose',
|
|
72
|
+
'deer',
|
|
73
|
+
'news',
|
|
74
|
+
'expertise',
|
|
75
|
+
'status',
|
|
76
|
+
'media',
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
/** Mongoose's legacy pluralizer: lowercased, then the first matching rule */
|
|
80
|
+
export function legacyPluralize(name: string): string {
|
|
81
|
+
const lower = name.toLowerCase();
|
|
82
|
+
if (UNCOUNTABLES.has(lower)) {
|
|
83
|
+
return lower;
|
|
84
|
+
}
|
|
85
|
+
const rule = RULES.find(([pattern]) => lower.match(pattern));
|
|
86
|
+
return rule ? lower.replace(rule[0], rule[1]) : lower;
|
|
87
|
+
}
|