@ambiten/core 1.0.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/LICENSE +21 -0
- package/README.md +247 -0
- package/bin/bootstrap.js +26 -0
- package/dist/ambiten-cache/ambitenCache.d.ts +64 -0
- package/dist/ambiten-cache/ambitenCache.d.ts.map +1 -0
- package/dist/ambiten-cache/ambitenCache.js +127 -0
- package/dist/ambiten-cache/index.d.ts +2 -0
- package/dist/ambiten-cache/index.d.ts.map +1 -0
- package/dist/ambiten-cache/index.js +4 -0
- package/dist/browser.d.ts +32 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +37 -0
- package/dist/cli/ambiten-core-cli.d.ts +4 -0
- package/dist/cli/ambiten-core-cli.d.ts.map +1 -0
- package/dist/cli/ambiten-core-cli.js +41 -0
- package/dist/cli/buildInteractiveConfig.d.ts +4 -0
- package/dist/cli/buildInteractiveConfig.d.ts.map +1 -0
- package/dist/cli/buildInteractiveConfig.js +198 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/prompt.d.ts +10 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +48 -0
- package/dist/cli/types.d.ts +11 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/config/ambiten.config.schema.json +278 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/loadAmbitenConfig.d.ts +3 -0
- package/dist/config/loadAmbitenConfig.d.ts.map +1 -0
- package/dist/config/loadAmbitenConfig.js +131 -0
- package/dist/context/ambitenContext.d.ts +35 -0
- package/dist/context/ambitenContext.d.ts.map +1 -0
- package/dist/context/ambitenContext.js +147 -0
- package/dist/context/helpers/runManualTransaction.d.ts +3 -0
- package/dist/context/helpers/runManualTransaction.d.ts.map +1 -0
- package/dist/context/helpers/runManualTransaction.js +22 -0
- package/dist/context/helpers/transactionSession.d.ts +9 -0
- package/dist/context/helpers/transactionSession.d.ts.map +1 -0
- package/dist/context/helpers/transactionSession.js +8 -0
- package/dist/context/index.d.ts +4 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +6 -0
- package/dist/debug/debugLog.d.ts +2 -0
- package/dist/debug/debugLog.d.ts.map +1 -0
- package/dist/debug/debugLog.js +23 -0
- package/dist/debug/index.d.ts +2 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +4 -0
- package/dist/gc/ambitenGC.d.ts +49 -0
- package/dist/gc/ambitenGC.d.ts.map +1 -0
- package/dist/gc/ambitenGC.js +138 -0
- package/dist/gc/gcCron.browser.d.ts +2 -0
- package/dist/gc/gcCron.browser.d.ts.map +1 -0
- package/dist/gc/gcCron.browser.js +9 -0
- package/dist/gc/gcCron.node.d.ts +19 -0
- package/dist/gc/gcCron.node.d.ts.map +1 -0
- package/dist/gc/gcCron.node.js +47 -0
- package/dist/gc/gcManager.d.ts +37 -0
- package/dist/gc/gcManager.d.ts.map +1 -0
- package/dist/gc/gcManager.js +62 -0
- package/dist/gc/index.d.ts +5 -0
- package/dist/gc/index.d.ts.map +1 -0
- package/dist/gc/index.js +7 -0
- package/dist/graphql/ambitenGraphQL.d.ts +24 -0
- package/dist/graphql/ambitenGraphQL.d.ts.map +1 -0
- package/dist/graphql/ambitenGraphQL.js +215 -0
- package/dist/graphql/index.d.ts +2 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +4 -0
- package/dist/index-browser.js +25 -0
- package/dist/index-browser.js.map +1 -0
- package/dist/index-cli.js +26 -0
- package/dist/index-cli.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/init-cli/generate.project.d.ts +9 -0
- package/dist/init-cli/generate.project.d.ts.map +1 -0
- package/dist/init-cli/generate.project.js +38 -0
- package/dist/instrumentation/index.d.ts +3 -0
- package/dist/instrumentation/index.d.ts.map +1 -0
- package/dist/instrumentation/index.js +5 -0
- package/dist/instrumentation/measureQuery.browser.d.ts +3 -0
- package/dist/instrumentation/measureQuery.browser.d.ts.map +1 -0
- package/dist/instrumentation/measureQuery.browser.js +6 -0
- package/dist/instrumentation/measureQueryWithErrors.d.ts +11 -0
- package/dist/instrumentation/measureQueryWithErrors.d.ts.map +1 -0
- package/dist/instrumentation/measureQueryWithErrors.js +90 -0
- package/dist/lib-core/ambitenClient.d.ts +115 -0
- package/dist/lib-core/ambitenClient.d.ts.map +1 -0
- package/dist/lib-core/ambitenClient.js +537 -0
- package/dist/lib-core/ambitenModelFactory.d.ts +979 -0
- package/dist/lib-core/ambitenModelFactory.d.ts.map +1 -0
- package/dist/lib-core/ambitenModelFactory.js +3984 -0
- package/dist/lib-core/ambitenSchema.d.ts +126 -0
- package/dist/lib-core/ambitenSchema.d.ts.map +1 -0
- package/dist/lib-core/ambitenSchema.js +247 -0
- package/dist/lib-core/bootstrap/ambitenBootstrap.d.ts +38 -0
- package/dist/lib-core/bootstrap/ambitenBootstrap.d.ts.map +1 -0
- package/dist/lib-core/bootstrap/ambitenBootstrap.js +381 -0
- package/dist/lib-core/bootstrap/index.d.ts +2 -0
- package/dist/lib-core/bootstrap/index.d.ts.map +1 -0
- package/dist/lib-core/bootstrap/index.js +4 -0
- package/dist/lib-core/index.d.ts +5 -0
- package/dist/lib-core/index.d.ts.map +1 -0
- package/dist/lib-core/index.js +7 -0
- package/dist/middleware/authorization/auth.d.ts +22 -0
- package/dist/middleware/authorization/auth.d.ts.map +1 -0
- package/dist/middleware/authorization/auth.js +37 -0
- package/dist/middleware/index.d.ts +4 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +6 -0
- package/dist/middleware/rbac/rbacMiddleware.d.ts +103 -0
- package/dist/middleware/rbac/rbacMiddleware.d.ts.map +1 -0
- package/dist/middleware/rbac/rbacMiddleware.js +246 -0
- package/dist/middleware/rbac/rbacTypes.d.ts +4 -0
- package/dist/middleware/rbac/rbacTypes.d.ts.map +1 -0
- package/dist/middleware/rbac/rbacTypes.js +8 -0
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +5 -0
- package/dist/plugins/softDelete/applySoftDelete.d.ts +5 -0
- package/dist/plugins/softDelete/applySoftDelete.d.ts.map +1 -0
- package/dist/plugins/softDelete/applySoftDelete.js +139 -0
- package/dist/plugins/softDelete/types.d.ts +14 -0
- package/dist/plugins/softDelete/types.d.ts.map +1 -0
- package/dist/plugins/softDelete/types.js +2 -0
- package/dist/redis-manager/index.d.ts +2 -0
- package/dist/redis-manager/index.d.ts.map +1 -0
- package/dist/redis-manager/index.js +4 -0
- package/dist/redis-manager/redisClient.d.ts +32 -0
- package/dist/redis-manager/redisClient.d.ts.map +1 -0
- package/dist/redis-manager/redisClient.js +146 -0
- package/dist/tanancy/MultiTenantManager.d.ts +98 -0
- package/dist/tanancy/MultiTenantManager.d.ts.map +1 -0
- package/dist/tanancy/MultiTenantManager.js +190 -0
- package/dist/tanancy/TenantContext.d.ts +31 -0
- package/dist/tanancy/TenantContext.d.ts.map +1 -0
- package/dist/tanancy/TenantContext.js +59 -0
- package/dist/tanancy/TenantModelResolver.d.ts +10 -0
- package/dist/tanancy/TenantModelResolver.d.ts.map +1 -0
- package/dist/tanancy/TenantModelResolver.js +114 -0
- package/dist/tanancy/index.d.ts +5 -0
- package/dist/tanancy/index.d.ts.map +1 -0
- package/dist/tanancy/index.js +7 -0
- package/dist/tanancy/init/initMultiTenancy.d.ts +29 -0
- package/dist/tanancy/init/initMultiTenancy.d.ts.map +1 -0
- package/dist/tanancy/init/initMultiTenancy.js +62 -0
- package/dist/templates/generateDefaultConfigContent.d.ts +10 -0
- package/dist/templates/generateDefaultConfigContent.d.ts.map +1 -0
- package/dist/templates/generateDefaultConfigContent.js +108 -0
- package/dist/templates/generateGCManagerFile.d.ts +2 -0
- package/dist/templates/generateGCManagerFile.d.ts.map +1 -0
- package/dist/templates/generateGCManagerFile.js +39 -0
- package/dist/templates/generateGCRunnerFile.d.ts +2 -0
- package/dist/templates/generateGCRunnerFile.d.ts.map +1 -0
- package/dist/templates/generateGCRunnerFile.js +25 -0
- package/dist/templates/generateMainEntry.d.ts +3 -0
- package/dist/templates/generateMainEntry.d.ts.map +1 -0
- package/dist/templates/generateMainEntry.js +24 -0
- package/dist/templates/index.d.ts +6 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +8 -0
- package/dist/templates/scaffold/structureGenerator.d.ts +4 -0
- package/dist/templates/scaffold/structureGenerator.d.ts.map +1 -0
- package/dist/templates/scaffold/structureGenerator.js +193 -0
- package/dist/types/GCConfig.d.ts +7 -0
- package/dist/types/GCConfig.d.ts.map +1 -0
- package/dist/types/GCConfig.js +2 -0
- package/dist/types/ambiten-runtime-type.d.ts +24 -0
- package/dist/types/ambiten-runtime-type.d.ts.map +1 -0
- package/dist/types/ambiten-runtime-type.js +2 -0
- package/dist/types/ambiten.client.type.d.ts +136 -0
- package/dist/types/ambiten.client.type.d.ts.map +1 -0
- package/dist/types/ambiten.client.type.js +3 -0
- package/dist/types/ambiten.model.type.d.ts +135 -0
- package/dist/types/ambiten.model.type.d.ts.map +1 -0
- package/dist/types/ambiten.model.type.js +4 -0
- package/dist/types/ambitenConfig.d.ts +103 -0
- package/dist/types/ambitenConfig.d.ts.map +1 -0
- package/dist/types/ambitenConfig.js +3 -0
- package/dist/types/bootstrapClient.type.d.ts +11 -0
- package/dist/types/bootstrapClient.type.d.ts.map +1 -0
- package/dist/types/bootstrapClient.type.js +2 -0
- package/dist/types/db.provider.d.ts +66 -0
- package/dist/types/db.provider.d.ts.map +1 -0
- package/dist/types/db.provider.js +2 -0
- package/dist/types/document.d.ts +7 -0
- package/dist/types/document.d.ts.map +1 -0
- package/dist/types/document.js +2 -0
- package/dist/types/event.type.d.ts +6 -0
- package/dist/types/event.type.d.ts.map +1 -0
- package/dist/types/event.type.js +27 -0
- package/dist/types/graphql.type.d.ts +22 -0
- package/dist/types/graphql.type.d.ts.map +1 -0
- package/dist/types/graphql.type.js +2 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +17 -0
- package/dist/types/logger.types.d.ts +15 -0
- package/dist/types/logger.types.d.ts.map +1 -0
- package/dist/types/logger.types.js +3 -0
- package/dist/types/middleware/types.d.ts +28 -0
- package/dist/types/middleware/types.d.ts.map +1 -0
- package/dist/types/middleware/types.js +2 -0
- package/dist/types/result.utils.types.d.ts +7 -0
- package/dist/types/result.utils.types.d.ts.map +1 -0
- package/dist/types/result.utils.types.js +2 -0
- package/dist/types/schema.type.d.ts +23 -0
- package/dist/types/schema.type.d.ts.map +1 -0
- package/dist/types/schema.type.js +10 -0
- package/dist/types/user.type.d.ts +11 -0
- package/dist/types/user.type.d.ts.map +1 -0
- package/dist/types/user.type.js +2 -0
- package/dist/utils/AuthUtils.d.ts +15 -0
- package/dist/utils/AuthUtils.d.ts.map +1 -0
- package/dist/utils/AuthUtils.js +26 -0
- package/dist/utils/ModelRegistry.d.ts +15 -0
- package/dist/utils/ModelRegistry.d.ts.map +1 -0
- package/dist/utils/ModelRegistry.js +35 -0
- package/dist/utils/banner.d.ts +2 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +20 -0
- package/dist/utils/builders/createModel.d.ts +37 -0
- package/dist/utils/builders/createModel.d.ts.map +1 -0
- package/dist/utils/builders/createModel.js +38 -0
- package/dist/utils/builders/getTenantDb.d.ts +12 -0
- package/dist/utils/builders/getTenantDb.d.ts.map +1 -0
- package/dist/utils/builders/getTenantDb.js +25 -0
- package/dist/utils/builders/index.d.ts +4 -0
- package/dist/utils/builders/index.d.ts.map +1 -0
- package/dist/utils/builders/index.js +6 -0
- package/dist/utils/builders/schema.d.ts +22 -0
- package/dist/utils/builders/schema.d.ts.map +1 -0
- package/dist/utils/builders/schema.js +26 -0
- package/dist/utils/cacheWithRedis.d.ts +27 -0
- package/dist/utils/cacheWithRedis.d.ts.map +1 -0
- package/dist/utils/cacheWithRedis.js +22 -0
- package/dist/utils/castId.d.ts +5 -0
- package/dist/utils/castId.d.ts.map +1 -0
- package/dist/utils/castId.js +52 -0
- package/dist/utils/color-palatte.d.ts +4 -0
- package/dist/utils/color-palatte.d.ts.map +1 -0
- package/dist/utils/color-palatte.js +24 -0
- package/dist/utils/configureAmbitenContext.d.ts +13 -0
- package/dist/utils/configureAmbitenContext.d.ts.map +1 -0
- package/dist/utils/configureAmbitenContext.js +35 -0
- package/dist/utils/detect-package-manager.d.ts +5 -0
- package/dist/utils/detect-package-manager.d.ts.map +1 -0
- package/dist/utils/detect-package-manager.js +59 -0
- package/dist/utils/ensureModelNameSafe.d.ts +12 -0
- package/dist/utils/ensureModelNameSafe.d.ts.map +1 -0
- package/dist/utils/ensureModelNameSafe.js +28 -0
- package/dist/utils/ensureRedis.d.ts +7 -0
- package/dist/utils/ensureRedis.d.ts.map +1 -0
- package/dist/utils/ensureRedis.js +40 -0
- package/dist/utils/error/ambitenError-handler.d.ts +24 -0
- package/dist/utils/error/ambitenError-handler.d.ts.map +1 -0
- package/dist/utils/error/ambitenError-handler.js +39 -0
- package/dist/utils/error/errorTypes.d.ts +27 -0
- package/dist/utils/error/errorTypes.d.ts.map +1 -0
- package/dist/utils/error/errorTypes.js +30 -0
- package/dist/utils/error/index.d.ts +3 -0
- package/dist/utils/error/index.d.ts.map +1 -0
- package/dist/utils/error/index.js +5 -0
- package/dist/utils/eventOptions.d.ts +38 -0
- package/dist/utils/eventOptions.d.ts.map +1 -0
- package/dist/utils/eventOptions.js +130 -0
- package/dist/utils/events.d.ts +5 -0
- package/dist/utils/events.d.ts.map +1 -0
- package/dist/utils/events.js +7 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +25 -0
- package/dist/utils/invalidateTenantCache.d.ts +18 -0
- package/dist/utils/invalidateTenantCache.d.ts.map +1 -0
- package/dist/utils/invalidateTenantCache.js +27 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/modelLoader.d.ts +3 -0
- package/dist/utils/modelLoader.d.ts.map +1 -0
- package/dist/utils/modelLoader.js +41 -0
- package/dist/utils/resolveAmbitenOption.d.ts +2 -0
- package/dist/utils/resolveAmbitenOption.d.ts.map +1 -0
- package/dist/utils/resolveAmbitenOption.js +10 -0
- package/dist/utils/resolveRuntimeConfig.d.ts +22 -0
- package/dist/utils/resolveRuntimeConfig.d.ts.map +1 -0
- package/dist/utils/resolveRuntimeConfig.js +33 -0
- package/dist/utils/scaffoldLoger.d.ts +11 -0
- package/dist/utils/scaffoldLoger.d.ts.map +1 -0
- package/dist/utils/scaffoldLoger.js +68 -0
- package/dist/utils/symbols.d.ts +4 -0
- package/dist/utils/symbols.d.ts.map +1 -0
- package/dist/utils/symbols.js +6 -0
- package/dist/utils/time.d.ts +5 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +39 -0
- package/package.json +180 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
(()=>{var e={5(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.resolveAmbitenOption=function(e){for(const t of e)if(void 0!==t)return t}},221(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},490(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.detectPackageManager=s,t.getInstallCommand=function(e,t){switch(e){case"pnpm":return["pnpm",["add",...t].join(" ")];case"yarn":return["yarn",["add",...t].join(" ")];default:return["npm",["install",...t].join(" ")]}},t.installPackages=async function(e=[],t=process.cwd()){const n=s(t),i=0===e.length?["install"]:"npm"===n?["install",...e]:["add",...e];await new Promise((e,o)=>{const a=(0,r.spawn)(n,i,{cwd:t,stdio:"inherit",shell:"win32"===process.platform});a.on("error",o),a.on("close",t=>{0!==t?o(new Error(`${n} ${i.join(" ")} failed with exit code ${t}`)):e()})})};const i=n(5584),o=i.__importDefault(n(9896)),a=i.__importDefault(n(6928)),r=n(5317);function s(e=process.cwd()){if(o.default.existsSync(a.default.join(e,"pnpm-lock.yaml")))return"pnpm";if(o.default.existsSync(a.default.join(e,"yarn.lock")))return"yarn";if(o.default.existsSync(a.default.join(e,"package-lock.json")))return"npm";const t=process.env.npm_config_user_agent??"";return t.includes("pnpm")?"pnpm":t.includes("yarn")?"yarn":(t.includes("npm"),"npm")}},529(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.objectIdSymbol=t.schemaTypeSymbol=t.AmbitenSymbol=void 0,t.AmbitenSymbol=Symbol("Ambiten"),t.schemaTypeSymbol=Symbol("AmbitenSchemaType"),t.objectIdSymbol=Symbol.for("AmbitenObjectId")},618(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},829(e){"use strict";e.exports=require("jsonwebtoken")},901(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(5381),t),i.__exportStar(n(6570),t),i.__exportStar(n(2450),t),i.__exportStar(n(7219),t)},960(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(1332),t),i.__exportStar(n(6438),t),i.__exportStar(n(7825),t),i.__exportStar(n(8686),t),i.__exportStar(n(7624),t),i.__exportStar(n(529),t),i.__exportStar(n(2992),t),i.__exportStar(n(9881),t),i.__exportStar(n(7503),t),i.__exportStar(n(1791),t),i.__exportStar(n(4131),t),i.__exportStar(n(1186),t),i.__exportStar(n(6880),t),i.__exportStar(n(2883),t),i.__exportStar(n(7858),t),i.__exportStar(n(4239),t),i.__exportStar(n(1921),t),i.__exportStar(n(5),t),i.__exportStar(n(2536),t),i.__exportStar(n(5709),t),i.__exportStar(n(5341),t),i.__exportStar(n(490),t)},1051(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1077(e){function t(e){return Promise.resolve().then(()=>{var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t})}t.keys=()=>[],t.resolve=t,t.id=1077,e.exports=t},1095(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1186(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createBootstrapLogger=function(e={transportConfigs:[]}){if(!e?.enabled)return(0,i.setupLogger)({level:"warn",colorize:!1});const t={level:e.level??"info",colorize:e.colorize??!0,json:e.json??!1,transports:e.transports??[],formatOptions:e.formatOptions,hooks:e.hooks,contextProvider:e.contextProvider,enableMetrics:e.enableMetrics??{enabled:!1},circuitBreaker:e.circuitBreaker,compress:e.compress??{enabled:!1}};return(0,i.setupLogger)(t)};const i=n(9451)},1299(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DEFAULT_CONFIG_CONTENT=function(e){const t={configVersion:"1.0.0",projectName:e.projectName??"my-ambiten-app",connection:{uri:e.connection?.uri??"mongodb://localhost:27017/my-ambiten-app",options:{dbName:e.connection?.options?.dbName??e.projectName??"my-ambiten-app"}},...e.multiTenant?.enabled?{multiTenant:{enabled:!0,headerKey:e.multiTenant.headerKey??"x-tenant-id",tenants:e.multiTenant.tenants??{},initOptions:{lazy:e.multiTenant.initOptions?.lazy??!1,retryAttempts:e.multiTenant.initOptions?.retryAttempts??3}}}:{},...e.logger?.enabled?{logger:{enabled:!0,level:e.logger.level??"info",colorize:e.logger.colorize??!0,json:e.logger.json??!1,transportConfigs:[{type:"console",options:{}},{type:"rotating-file",options:{filename:"./logs/ambiten.log",frequency:"hourly",maxSize:200,compress:!1,flushInterval:1e3}}],enableMetrics:"boolean"==typeof e.logger.enableMetrics?{enabled:e.logger.enableMetrics,logInterval:6e4}:e.logger.enableMetrics??{enabled:!1,logInterval:6e4},compress:"boolean"==typeof e.logger.compress?{enabled:e.logger.compress}:e.logger.compress??{enabled:!1}}}:{},...e.graphql?.enabled?{graphql:{enabled:!0,subscriptions:e.graphql.subscriptions??!1,playground:e.graphql.playground??!0,schemaOutputPath:e.graphql.schemaOutputPath??"./src/graphql/schema.gql"}}:{},features:{models:e.features?.models??"./src/models",schemas:e.features?.schemas??"./src/schemas",...e.graphql?.enabled?{typeDefs:e.features?.typeDefs??"./src/graphql/typeDefs",resolvers:e.features?.resolvers??"./src/graphql/resolvers"}:{},useRedisCache:e.features?.useRedisCache??!1,redisUri:e.features?.redisUri??""},advanced:{autoInstall:e.advanced?.autoInstall??!1,circuitBreaker:{enabled:e.advanced?.circuitBreaker?.enabled??!0,retryAttempts:e.advanced?.circuitBreaker?.retryAttempts??5},garbageCollector:{enabled:e.advanced?.garbageCollector?.enabled??!1,retentionPeriod:e.advanced?.garbageCollector?.retentionPeriod??30,logResults:e.advanced?.garbageCollector?.logResults??!0},gcCron:e.advanced?.gcCron??"* * * * *"}};return JSON.stringify(t,null,2)}},1332(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Model=void 0;const i=n(6178);t.Model=e=>new i.AmbitenModel({...e,provider:e.provider??i.AmbitenClient.init()})},1349(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(5584).__exportStar(n(2625),t)},1538(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(1299),t),i.__exportStar(n(5596),t),i.__exportStar(n(6939),t),i.__exportStar(n(7004),t),i.__exportStar(n(6793),t)},1679(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenClient=void 0,t.createAmbitenClientModule=c;const i=n(2518);n(4469);const o=n(960),a=n(901),r=n(8742),s=Symbol.for("Ambiten:default");class l{_opts;_uri;_client;_db;collectionRef;_connected=!1;_defaultDbName;_overrideDbName;static instances=new Map;static defaultUri="mongodb://127.0.0.1:27017";constructor(e){this._opts=e,this._uri=e.uri||process.env.MONGO_URI||l.defaultUri,this._defaultDbName=e?.options?.dbName||process.env.DB_NAME||"Ambiten_default_db",this._client=new i.MongoClient(this._uri,{directConnection:!0,minPoolSize:5,maxPoolSize:50,serverSelectionTimeoutMS:5e3}),this._db=this._client.db(this._opts.options?.dbName),this.ensureMongoDependency()}static init(e){const t=String(s),n=this.instances.get(t);if(n)return n;const i=c({uri:e?.uri??this.defaultUri??process.env.MONGO_URI,options:{dbName:e?.options?.dbName},tenantResolver:e?.tenantResolver});return this.instances.set(t,i),i}ensureMongoDependency(){try{const{MongoClient:e}=n(2518)}catch{console.error('\n❌ Missing peer dependency: "mongodb".\nPlease install it in your project before continuing:\n\n npm i mongodb\n'),process.exit(1)}}async db(e){if(e?.db)return e.db;if(e?.tenantId){const t=this._opts.tenantResolver;if(!t)throw new Error("Multi-tenancy not enabled. Provide tenantResolver to AmbitenClient or avoid passing tenantId.");const n=await t.getClient(e.tenantId);if(!n)throw new Error(`Tenant "${e.tenantId}" is not registered.`);const i=e.dbName??a.MultiTenantManager.getTenantDbName(e.tenantId)??this._defaultDbName;return n.db(i)}if(!this._client||!this._connected){const e="AmbitenClient not connected. call connect() first.";throw(0,o.createAmbitenError)(o.ErrorType.CONNECTION_ERROR,e,{details:{operation:"db"}})}return e?.dbName?this._client.db(e.dbName):this._overrideDbName?this._client.db(this._overrideDbName):this._client.db(this._defaultDbName)}static async db(e){return this.init().db(e)}validateUri(e){if(!e||"string"!=typeof e){const t="Missing MongoDB URI. Set MONGODB_URI (or pass uri explicitly).";throw(0,o.createAmbitenError)(o.ErrorType.VALIDATION_ERROR,t,{details:{operation:"validateUri",providedUri:e}})}if(!/^mongodb(\+srv)?:\/\//.test(e)){const t=`Invalid MongoDB URI "${e}". It must start with "mongodb://" or "mongodb+srv://".`;throw(0,o.createAmbitenError)(o.ErrorType.VALIDATION_ERROR,t,{details:{operation:"validateUri",providedUri:e}})}}async connect(){return this.validateUri(this._opts.uri),this._client||(this._client=new i.MongoClient(this._opts.uri)),this._connected||(await this._client.connect(),this._connected=!0),this}async client(e){if(e?.tenantId){const t=this._opts.tenantResolver;if(!t)throw new Error("Multi-tenancy not enabled. Provide tenantResolver to AmbitenClient or avoid passing tenantId.");const n=await t.getClient(e.tenantId);if(!n)throw new Error(`Tenant "${e.tenantId}" is not registered.`);return n}if(!this._client)throw new Error("Client not initialized. Call `connect()` first.");return this._client}async useCollection(e){if(!e||"string"!=typeof e||!e.trim())throw new Error("Collection name is required.");if(!this._client)throw new Error("Client not initialized. Call `connect()` first.");const t=this.resolveClientScope({collectionName:e}),n=this._client.db(t.dbName);if(!n||"function"!=typeof n.collection)throw new Error("Database name is required in client options.");const i=n.collection(t.collectionName);return this.collectionRef=i,i}async collection(e,t){return(await this.db(t)).collection(e)}async getCollection(e,t){return this._client&&"function"==typeof this._client.db?this.collection(e,t):{toString:()=>e}}async getClusterInfo(){if(!this._client)throw new Error("Client not initialized. Call `connect()` first.");const e=this._opts?.options?.dbName;if(!e)throw new Error("Database name is required in client options.");const t=await this._client.db(e).admin().command({hello:1});return"isdbgrid"===t?.msg?(console.log("MongoDB is running in a sharded cluster."),{type:"sharded"}):t?.setName||t?.hosts?(console.log("MongoDB is running as a replica set."),{type:"replicaSet",setName:t.setName,hosts:t.hosts}):(console.log("MongoDB is running as a standalone instance."),{type:"standalone"})}static async resolveRuntime(){const e=r.AmbitenContext.get();if(!e?.tenantId)throw new Error("Tenant not resolved in context.");const t=a.MultiTenantManager.getTenant(e.tenantId);if(!t)throw new Error(`Tenant not found: ${e.tenantId}`);return{db:this.resolveDbFromTenant(t,e),session:e?.session}}async useDatabase(e){if(!e)throw new Error("Database name is required.");const t=await this.client();return this._overrideDbName=e,{db:t.db(e),client:t}}withDatabase(e){return{db:async t=>{const n={...t,dbName:t?.dbName??e};return this.db(n)},connect:async()=>(await this.connect(),this),client:async t=>{const n={...t,dbName:t?.dbName??e};return this.client(n)},collection:async(t,n)=>{const i={...n,dbName:n?.dbName??e};return this.collection(t,i)},startSession:async t=>{const n={...t,dbName:t?.dbName??e,session:t?.session};return this.startSession(n)},close:async()=>{await this.close()}}}resolveDbName(e){return this.resolveClientScope({dbName:e}).dbName}resolveClientScope(e={}){const t=r.AmbitenContext.get(),n=e.dbName??t.dbName??this._opts?.options?.dbName??this._defaultDbName;if(!n)throw new Error("Database name is required in client options.");const i=e.collectionName??t.collectionName;return{tenantId:t.tenantId,requestId:t.requestId,dbName:n,collectionName:i?.trim()||void 0,session:e.session??t.session}}static resolveDbFromTenant(e,t){if(!e?.client)throw new Error(`Tenant "${t?.tenantId}" has no MongoDB client.`);const n=t?.dbName??e.dbName;if(!n)throw new Error(`Database name not resolved for tenant "${t?.tenantId}".`);return e.client.db(n)}async withContext(e,t){return r.AmbitenContext.run({tenantId:e.tenantId,requestId:e.requestId,dbName:e.dbName,collectionName:e.collectionName,session:e.session},t)}logWithContext(e,t,n={}){const i=r.AmbitenContext.get(),o={requestId:i.requestId,tenantId:i.tenantId,...i.loggerMeta,...n};this._opts.options?.config?.logger?.[e]?.(t,o)}withTenant(e){return{db:async t=>{const n={...t,tenantId:t?.tenantId??e};return this.db(n)},connect:async()=>(await this.connect(),this),client:async t=>{const n={...t,tenantId:t?.tenantId??e};return this.client(n)},collection:async(t,n)=>{const i={...n,tenantId:n?.tenantId??e};return this.collection(t,i)},startSession:async t=>{const n={...t,tenantId:t.tenantId??e};return this.startSession(n)},close:async()=>{await this.close()}}}withScope(e){return{db:async t=>{const n={...t,tenantId:t?.tenantId??e.tenantId,dbName:t?.dbName??e.dbName};return this.db(n)},connect:async()=>(await this.connect(),this),client:async t=>{const n={...t,tenantId:t?.tenantId??e.tenantId,dbName:t?.dbName??e.dbName};return this.client(n)},collection:async(t,n)=>{const i={...n,tenantId:n?.tenantId??e.tenantId,dbName:n?.dbName??e.dbName};return this.collection(t,i)},startSession:async t=>{const n={...t,tenantId:t?.tenantId??e.tenantId,dbName:t?.dbName??e.dbName};return this.startSession(n)},close:async()=>{await this.close()}}}resetDatabase(){this._overrideDbName=void 0}async startSession(e){return(await this.client(e)).startSession()}async dropCollection(e,t){if(!this._client&&!t?.db)throw(0,o.createAmbitenError)(o.ErrorType.CONNECTION_ERROR,"Client not initialized. Call `connect()` first.",{details:{operation:"dropCollection",providedCollectionName:e}});const n=e?.trim()||this.collectionRef?.collectionName;if(!n)throw(0,o.createAmbitenError)(o.ErrorType.VALIDATION_ERROR,"Collection name is required.",{details:{operation:"dropCollection",providedCollectionName:e}});const i=t?.db??this._client.db(this.resolveDbName(t?.dbName));await i.collection(n).drop()}async dropDatabase(e){if(!this._client&&!e?.db)throw(0,o.createAmbitenError)(o.ErrorType.CONNECTION_ERROR,"Client not initialized. Call `connect()` first.",{details:{operation:"dropDatabase"}});const t=e?.db??this._client.db(this.resolveDbName(e?.dbName)),n=await t.dropDatabase();return void 0===n||n}async close(){this._client&&await(this._client.close?.()),this._client=null,this._db=null,this._connected=!1,console.log("[info]: Disconnected from MongoDB")}async disconnect(){await this.close()}isConnected(){return this._connected}static handleTopologyEvent(e){e instanceof i.TopologyOpeningEvent?console.log(`Topology opened: ${e.topologyId}`):e instanceof i.TopologyClosedEvent?console.log(`Topology closed: ${e.topologyId}`):console.warn(`[warning]: Unknown topology event: ${e}`)}static async handleLogBatch(e,t){if(!Array.isArray(e)||0===e.length)return void console.warn("[warning]: Received an empty log batch or invalid format.");const n=r.AmbitenContext.get();this.handleTopologyEvent(e[0]);const i=e.slice(1);if(0===i.length)return;if(!t)return void console.warn(`[warning]: No transporter provided; ${i.length} topology event(s) will not be processed.`);const o=i.map(e=>{const i=e.constructor?.name??"TopologyEvent",o=i.toLowerCase().includes("opening")?"opening":i.toLowerCase().includes("closed")?"closed":"unknown",a=`Topology event: ${i}`;return t.write({level:"info",timestamp:(new Date).toISOString(),message:a,source:"AmbitenTopology",context:{requestId:n?.requestId,tenantId:n?.tenantId,collectionName:n?.collectionName,dbName:n?.dbName},meta:{eventType:o,topologyId:e.topologyId}},a)});await Promise.all(o)}}function c(e){return new l(e)}t.AmbitenClient=l},1684(e){"use strict";e.exports=require("graphql-tag")},1737(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(4878),t),i.__exportStar(n(7584),t)},1791(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DB_CHANGE_EVENT=t.DOCUMENT_DELETED_EVENT=t.DOCUMENT_UPDATED_EVENT=t.DOCUMENT_INSERTED_EVENT=void 0,t.DOCUMENT_INSERTED_EVENT="DOCUMENT_INSERTED",t.DOCUMENT_UPDATED_EVENT="DOCUMENT_UPDATED",t.DOCUMENT_DELETED_EVENT="DOCUMENT_DELETED",t.DB_CHANGE_EVENT="DB_CHANGE_EVENT"},1891(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.debugLog=function(e,t={}){if(!i.AmbitenContext.isDebug())return;const n=i.AmbitenContext.getLogger(),o=i.AmbitenContext.getLoggerMeta()??{},a={tenantId:i.AmbitenContext.getTenantId(),requestId:i.AmbitenContext.getRequestId(),dbName:i.AmbitenContext.getDbName(),collectionName:i.AmbitenContext.getCollectionName(),...o,...t};n?.debug?n.debug(e,a):console.debug(`[AMBITEN_DEBUG] ${e}`,a)};const i=n(8742)},1921(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ensureRedis=async function(){let e=this.publisher,t=this.subscriber;try{const n=await i.redis.get();return n?(n.isOpen||"function"!=typeof n.connect||await n.connect(),e||(e="function"==typeof n.duplicate?n.duplicate():n,e&&"function"==typeof e.connect&&await e.connect(),this.publisher=e),t||(t="function"==typeof n.duplicate?n.duplicate():n,t&&"function"==typeof t.connect&&await t.connect(),this.subscriber=t),console.log("[info] Ensuring Redis connection..."),console.log("[info] Redis connection established"),this):(console.log("⚠️ Redis client not available from redis manager; skipping Redis initialization"),this)}catch(e){const t=e instanceof Error?e.message:String(e);return console.log("[info] ⚠️ Redis connection skipped or failed:",t),this}};const i=n(3868)},1955(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2450(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getTenantModel=void 0;const i=n(9729),o=n(5381),a=n(8742),r=new Map;t.getTenantModel=async e=>{const t=e?.collectionName?.trim(),n=e?.tenantId??a.AmbitenContext.getTenantId();if(!t)throw new Error("collectionName is required.");if(!n)throw new Error("tenantId is required to run tenant context");r.has(n)||r.set(n,new Map);const s=r.get(n),l=e.dbName?`${t}::${e.dbName}`:t;if(s.has(l))return s.get(l);const c=function(e,t){return{async db(n){const i=await o.MultiTenantManager.getClient(e);if(!i)throw new Error(`Tenant "${e}" not registered.`);const a=n?.dbName??t;return a?i.db(a):i.db()}}}(n,e.dbName),d=(0,i.Model)({collectionName:t,schema:e.schema,provider:c});return s.set(l,d),d}},2518(e){"use strict";e.exports=require("mongodb")},2536(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.resolveRuntimeConfig=function(e){const t=i.AmbitenContext.get();return{tenantId:(0,o.resolveAmbitenOption)([e.methodTenantId,t?.tenantId,e.modelTenantId]),dbName:(0,o.resolveAmbitenOption)([e.methodDbName,t?.dbName,e.modelDbName,e.clientDbName]),collectionName:(0,o.resolveAmbitenOption)([e.methodCollectionName,t?.collectionName,e.modelCollectionName]),session:(0,o.resolveAmbitenOption)([e.methodSession,t?.session,e.modelSession]),requestId:t?.requestId,loggerMeta:t?.loggerMeta}};const i=n(8742),o=n(5)},2590(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.checkPermission=r,t.getCachedData=s,t.setCachedData=l,t.invalidateTenantCache=async function(e,t){try{const n=`${e}:permissions:${t}`;await i.redis.exists(n)?(await i.redis.del(n),console.info(`Cache invalidated for tenant ${e} and role ${t}`)):console.warn(`No cache found for tenant ${e} and role ${t}`)}catch(n){throw console.error(`Error invalidating cache for tenant ${e} and role ${t}:`,n),new Error(`Failed to invalidate cache for tenant ${e} and role ${t}`)}},t.enforceRBAC=function(e,t){const n=async(n,i,o,a)=>{const{user:s}=o;if(!s||!await r(s.role,t))throw new Error("Unauthorized: You do not have permission to perform this action.");return await e(n,i,o,a)};return Object.defineProperty(n,"name",{value:e.name||"anonymous",writable:!1,configurable:!0}),n.__originalResolver=e,n.__rbacAction=t,n},t.getRBACAction=function(e){return e.__rbacAction||null},t.getOriginalResolver=function(e){return e.__originalResolver||e};const i=n(3868),o=n(6941);function a(e,t){if(Array.isArray(e))return`${e.join(",")}:${t}`;if(e&&"object"==typeof e){if("tenantId"in e)return`${e.tenantId}:${t}`;try{return`${JSON.parse(JSON.stringify(e))}:${t}`}catch(n){return`${String(e)}:${t}`}}return`${e}:${t}`}async function r(e,t){const n=a(e,"permissions");let r=await s(e,"permissions");return r||(console.info(`Cache miss for role "${e}". Fetching permissions...`),r=o.rolePermissions[e]||[],r.length>0?console.info(`Permissions found for role "${e}": ${r.join(", ")}`):console.warn(`No permissions found for role "${e}"`)),await i.redis.exists(n)&&console.info(`Cache hit for role "${e}"`),r&&(r=Promise.resolve(o.rolePermissions[e]||[]),await l(e,"permissions",await r,500)),Promise.resolve(o.rolePermissions[e]||[]).then(n=>n.includes(t)?(console.info(`Permission granted for role "${e}" to perform action "${t}"`),!0):(console.warn(`Permission denied for role "${e}" to perform action "${t}"`),!1))}async function s(e,t){const n=a(e,t),o=await i.redis.get(n);o?console.info(`Cache hit for key "${n}"`):console.warn(`Cache miss for key "${n}"`);try{return o?JSON.parse(JSON.stringify(o)):null}catch(e){return console.warn(`Failed to parse cached data for key ${n}:`,e),o}}async function l(e,t,n,r){const s=a(e,t);try{await(i.redis?.set(s,JSON.stringify(n),{EX:r})),console.info(`Cache set for ${s}:`,n)}catch(e){console.error(`Failed to set cache for ${s}:`,e)}let l;if("string"==typeof e?l=e:Array.isArray(e)&&e.length>0?l=e[0]:e&&"object"==typeof e&&"tenantId"in e&&(l=e.tenantId),l){const e=o.rolePermissions[l]||[];e.length>0?console.info(`Permissions cached for role "${l}": ${e.join(", ")}`):console.warn(`No permissions found for role "${l}" to cache`)}else console.warn("Role key is not a string, cannot cache permissions")}},2625(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.loadAmbitenConfig=async function(e){const t=e?[a.default.resolve(e)]:[a.default.resolve(process.cwd(),d),a.default.resolve(process.cwd(),"config",d),a.default.resolve(process.cwd(),"src","config",d),a.default.resolve(__dirname,d),a.default.resolve(__dirname,"..",d)];let n,i;for(const e of t)if(await o.default.pathExists(e)){n=e;break}if(!n)throw new Error(`Config file not found at any of: ${t.join(", ")}`);try{const e=await o.default.readFile(n,"utf-8");i=function(e){const t={...e};return"boolean"==typeof t.logger&&(t.logger={enabled:t.logger}),t.logger&&"object"==typeof t.logger&&("boolean"==typeof t.logger.enableMetrics&&(t.logger.enableMetrics={enabled:t.logger.enableMetrics,logInterval:6e4}),t.logger.enableMetrics||(t.logger.enableMetrics={enabled:!1,logInterval:6e4}),"boolean"==typeof t.logger.compressLogFiles&&(t.logger.compressLogFiles={enabled:t.logger.compressLogFiles}),t.logger.compressLogFiles||(t.logger.compressLogFiles={enabled:!1})),"boolean"==typeof t.graphql&&(t.graphql={enabled:t.graphql}),"boolean"==typeof t.advanced&&(t.advanced={garbageCollector:{enabled:t.advanced}}),t.advanced&&"boolean"==typeof t.advanced.garbageCollector&&(t.advanced.garbageCollector={enabled:t.advanced.garbageCollector}),t.features||(t.features={}),void 0===t.features.useRedisCache&&(t.features.useRedisCache=!1),t}(JSON.parse(e))}catch(e){throw new Error(`[Ambiten] Failed to parse config file: ${e}`)}if(c||(c=l.compile(s.default)),!c(i)){console.error(JSON.stringify(c.errors,null,2));const e=c.errors?.map(e=>{const t=e.instancePath||"(root)",n="additionalProperties"===e.keyword?`: ${e.params.additionalProperty}`:"";return`${t} ${e.message}${n}`}).join("; ");throw new Error(`[Ambiten] Invalid configuration: ${e}`)}return function(e){if(!e.connection?.uri)throw new Error('Invalid config: "connection.uri" is required.');if(e.multiTenant?.enabled&&e.multiTenant.tenants&&"object"!=typeof e.multiTenant.tenants)throw new Error('Invalid config: "multiTenant.tenants" must be a tenant-to-URI map.')}(i),i.graphql??={enabled:!1},i.features??={useRedisCache:!1},i.advanced??={circuitBreaker:{enabled:!1},garbageCollector:{enabled:!1}},i};const i=n(5584),o=i.__importDefault(n(4652)),a=i.__importDefault(n(6928)),r=i.__importDefault(n(5711)),s=i.__importDefault(n(7499)),l=new r.default({allErrors:!0,useDefaults:!0,strict:!1,coerceTypes:!0});let c=null;const d="ambiten.config.json"},2703(e){"use strict";e.exports=require("node-cron")},2883(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.now=t.isValidDuration=t.formatDuration=t.parseDuration=void 0,t.parseDuration=e=>{const n=e.match(/^(\d+)([smhd])$/),i=(0,t.isValidDuration)(e);if(!n||!i)throw new Error(`Invalid duration format: ${e}. Expected format is <number><unit> where unit is one of 's', 'm', 'h', or 'd'.`);const o=parseInt(n[1],10),a=n[2];switch(a){case"s":return 1e3*o;case"m":return 60*o*1e3;case"h":return 60*o*60*1e3;case"d":return 24*o*60*60*1e3;default:throw new Error(`Unknown time unit: ${a}`)}},t.formatDuration=e=>{const t=Math.floor(e/1e3),n=Math.floor(t/60),i=Math.floor(n/60),o=Math.floor(i/24);return o>0?`${o}d`:i>0?`${i}h`:n>0?`${n}m`:`${t}s`},t.isValidDuration=e=>/^(\d+)([smhd])$/.test(e),t.now=new Date},2987(e){"use strict";e.exports=require("perf_hooks")},2992(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenError=void 0,t.createAmbitenError=function(e,t,i={}){return new n({type:e,message:t,cause:i.cause,details:i.details})};class n extends Error{type;details;constructor(e){super(e.message,{cause:e.cause}),this.name=e.type,this.type=e.type,this.details=e.details,Error.captureStackTrace?.(this,n)}toJSON(){return{name:this.name,type:this.type,message:this.message,details:this.details,cause:this.cause instanceof Error?{name:this.cause.name,message:this.cause.message}:this.cause}}}t.AmbitenError=n},2999(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenBootstrapFactory=void 0;const i=n(1349),o=n(9451),a=n(6178),r=n(6562),s=n(3868),l=n(960),c=n(901),d=n(8093),u=n(8917);class m{config;provider;model;schema;graphql;gc;logger;adapter;onConnectHooks=[];connectCallbacks=[];isConnected;constructor(e){this.adapter=e}onConnect(e){this.isConnected?this.connectCallbacks.push(e):e()}async initialize(e){this.config=e&&"object"==typeof e?e:await(0,i.loadAmbitenConfig)(e),this.initializeLogger(),await this.initializeRedis(),await this.initializeMongoProvider(),this.initializeSchema(),await this.initializeModel(),await this.initializeMultiTenancy(),await this.initializeGraphQL(),await this.runOnConnectHooks(),await this.initializeGarbageCollector()}initializeLogger(){const e=this.config.logger;this.logger=(0,o.setupLogger)({...e,transports:void 0,transportConfigs:e?.transportConfigs?.length?e.transportConfigs:[{type:"console",options:{}},{type:"rotating-file",options:{filename:"./logs/ambiten.log",frequency:"daily",compress:!1,flushInterval:1e3}}]}),this.logger.info("Logger initialized",{source:"AmbitenBootstrap"})}async initializeRedis(){this.config.features?.useRedisCache&&this.config.features.redisUri&&(await s.redis.get(this.config.features.redisUri),this.getLogger().info("Redis connected",{source:"AmbitenBootstrap"}))}async initializeMongoProvider(){const e=this.config.connection?.options?.dbName||this.config.projectName||void 0;this.provider=this.config.mongoClient??this.config.provider??(0,a.createAmbitenClientModule)({uri:this.config.connection?.uri||"mongodb://localhost:27017",options:{dbName:e,...this.config.connection?.options}}),await this.provider.connect(),(0,l.configureAmbitenContext)(this.provider),this.logger?this.getLogger().info("MongoDB connected via AmbitenClientModule",{source:"AmbitenBootstrap"}):console.log((0,l.colorize)("MongoDB connected via AmbitenClientModule","blue"))}initializeSchema(){this.schema=new a.Schema("object"==typeof this.config.schema?this.config.schema:{}),this.config.schema?(this.schema.registerSchema(this.config.schema),this.getLogger().info("Schema registered",{source:"AmbitenBootstrap"})):this.getLogger().warn("No schema provided, using default schema",{source:"AmbitenBootstrap"})}async initializeModel(){const e=this.config.model?.collectionName||"default";this.model=(0,l.Model)({collectionName:e,schema:this.schema,provider:this.provider,ctx:this.config.model?.ctx,collection:this.config.model?.collection,gcConfig:this.config.model?.gcConfig}),this.config.model&&(await this.model.registerModel({...this.config.model,collectionName:e,schema:this.schema,provider:this.provider}),this.logger?this.getLogger().info(`Model registered: ${e}`,{source:"AmbitenBootstrap"}):console.log((0,l.colorize)(`Model registered: ${e}`,"blue")))}async initializeMultiTenancy(){if(!this.config.multiTenant?.enabled)return;const e=this.config.multiTenant.tenants||{},t=this.config.multiTenant.initOptions||{};await(0,c.initMultiTenancy)(e,t),this.getLogger().info("Multi-tenancy initialized",{source:"AmbitenBootstrap",tenantCount:Object.keys(e).length,lazy:t.lazy??!1})}async initializeGraphQL(){this.config.graphql?.enabled&&(this.graphql=new r.AmbitenGraphQL({useRedis:this.config.features?.useRedisCache??!1,customTypeDefs:this.config.features?.typeDefs?Array.isArray(this.config.features.typeDefs)?this.config.features.typeDefs:[this.config.features.typeDefs]:[],customResolvers:this.config.features?.resolvers?Array.isArray(this.config.features.resolvers)?this.config.features.resolvers:[this.config.features.resolvers]:[],provider:this.provider}),await this.graphql.generateSchema(),this.logger?(this.getLogger().info("GraphQL schema generated"),this.getLogger().info("GraphQL initialized")):(console.log((0,l.colorize)("GraphQL schema generated","blue")),console.log((0,l.colorize)("GraphQL initialized","blue"))))}async runOnConnectHooks(){for(const e of this.onConnectHooks)await e()}async initializeGarbageCollector(){this.config.advanced?.garbageCollector?.enabled&&(this.gc=new d.AmbitenGC({enabled:this.config.advanced.garbageCollector.enabled??!0,cron:this.config.advanced.gcCron||"0 0 * * *",logResults:this.config.advanced.garbageCollector.logResults??!0,continueOnError:!0}),console.log("✅ Garbage Collector initialized"))}async registerMultiTenancy(e){const t=this.config.multiTenant,n=this.config.logger?.logger;if(!t?.enabled)return void n?.warn("Multi-tenancy is not enabled.",{source:"AmbitenBootstrap"});const i=e?.tenants??t.tenants;i&&0!==Object.keys(i).length?(await(0,c.initMultiTenancy)(i,{lazy:e?.lazy??t.initOptions?.lazy??!0,config:this.config.logger}),n?.info("Multi-tenancy registered successfully.",{source:"AmbitenBootstrap",tenantCount:Object.keys(i).length})):n?.warn("Multi-tenancy is enabled but no tenants were provided.",{source:"AmbitenBootstrap"})}async cache(e,t,n={}){if(!s.redis)throw new Error("Redis is not initialized");return(0,l.cacheWithRedis)(s.redis,e,t,n)}async invalidateCache(e,t){if(!s.redis)throw new Error("No Redis client available");const n=this.config.logger?.logger;if(!e)throw new Error("Tenant ID is required to invalidate cache");n?.info("Invalidating cache for tenant:",{source:"AmbitenBootstrap",tenantId:e,namespace:t}),await(0,u.invalidateTenantCache)(s.redis,e,t)}async getRedisClient(){return this.config.features?.useRedisCache&&this.config.features.redisUri&&await s.redis.get(this.config.features.redisUri),s.redis}getMongoClient(){return this.provider}getModel(){return this.model}getSchema(){return this.schema}getGraphQL(){if(!this.graphql)throw new Error("GraphQL is not initialized.");return this.graphql}getGCRunner(){if(!this.gc)throw new Error("Garbage Collector is not initialized.");return this.gc}getLogger(){return this.logger}async shutdown(){const e=this.config.logger?.logger;s.redis.isOpen&&(await s.redis.disconnect(),e?.info("🧹 Redis connection closed",{source:"AmbitenBootstrap"})),this.provider&&(await this.provider.close(),e?.log?.("info","MongoDB connection closed")),e?.log?.("info","Shutdown complete")}}t.AmbitenBootstrapFactory=class{static async create(e={}){const t=new m(e.adapter);return await t.initialize(e.config),t}}},3057(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenContext=void 0;const i=n(6698),o=n(5303),a={maxQueries:1/0,queriesExecuted:0,totalTimeMs:0};t.AmbitenContext=new class{storage=new i.AsyncLocalStorage;transactionResolver;run(e,t){const n=this.storage.getStore()??{},i={...n,...e,budget:e.budget?this.normalizeBudget(e.budget):n.budget?this.normalizeBudget(n.budget):void 0};return this.storage.run(i,t)}get(){return this.storage.getStore()??{}}hasActiveContext(){return void 0!==this.storage.getStore()}set(e){const t=this.storage.getStore();t&&Object.assign(t,e)}clear(){const e=this.storage.getStore();if(e)for(const t of Object.keys(e))delete e[t]}configureTransactionResolver(e){this.transactionResolver=e}getTenantId(){return this.get().tenantId}getRequestId(){return this.get().requestId}getDbName(){return this.get().dbName}getCollectionName(){return this.get().collectionName}getSession(){return this.get().session}getLogger(){return this.get().logger}getLoggerMeta(){return this.get().loggerMeta}getObserver(){return this.get().observer}normalizeBudget(e){return{maxQueries:e?.maxQueries??a.maxQueries,queriesExecuted:e?.queriesExecuted??a.queriesExecuted,totalTimeMs:e?.totalTimeMs??a.totalTimeMs}}getBudget(){const e=this.get(),t=this.normalizeBudget(e.budget);return e.budget=t,t}setBudget(e){this.get().budget=this.normalizeBudget(e)}assertQueryBudget(){const e=this.get(),t=this.getBudget();if(t.queriesExecuted>=t.maxQueries)throw new Error(`[Ambiten] Tenant ${e.tenantId??"unknown"} exceeded query budget for this request.`)}incrementQueries(){this.assertQueryBudget();const e=this.getBudget();return e.queriesExecuted+=1,e}addQueryTime(e){const t=this.getBudget();return t.totalTimeMs+=e,t}isDebug(){const e=this.get();return Boolean(e.debug||"true"===process.env.AMBITEN_DEBUG||"1"===process.env.AMBITEN_DEBUG)}async withTransaction(e){const t=this.get();if(t.session)return e(t.session);if(!this.transactionResolver)throw new Error("AmbitenContext transaction resolver is not configured.");const n=await this.transactionResolver.resolveClient(t.tenantId,t.dbName);if(!n)throw new Error(`No MongoClient available for${t.tenantId?` tenant "${t.tenantId}"`:" current context"}.`);const i=n.startSession();if("function"==typeof i.withTransaction)try{let t;return await i.withTransaction(async()=>(t=await this.run({session:i},()=>e(i)),t)),t}finally{await i.endSession()}return this.run({session:i},()=>(0,o.runManualTransaction)(i,e))}hasTransactionResolver(){return Boolean(this.transactionResolver)}}},3100(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(5584).__exportStar(n(5710),t)},3206(e,t,n){"use strict";e=n.nmd(e),Object.defineProperty(t,"__esModule",{value:!0}),t.runBootstrapCLI=r;const i=n(6858),o=n(4172),a=n(4629);async function r(e=process.argv){const t=new i.Command;t.name("Ambiten").description("Ambiten CLI").version("1.0.0","-v, --version","Output the current CLI version"),t.command("init").description("Initialize an Ambiten-powered project").argument("[projectName]","Name of the project").option("--with-graphql","Include GraphQL starter support").option("--with-redis","Enable Redis cache defaults").option("--logger","Enable logger configuration").option("--multi-tenant","Enable multi-tenant mode").option("--uri <mongodbUri>","MongoDB connection URI").option("--rbac","Reserve RBAC feature scaffolding").option("--with-garbage-collector","Enable garbage collector starter files").option("--install","Auto-install dependencies after scaffolding").action(async(e,t)=>{try{const n=await(0,a.buildInteractiveConfig)(e,t);await(0,o.generateProject)(n)}catch(e){console.error("[Ambiten CLI] Failed to initialize project:",e),process.exit(1)}}),await t.parseAsync(e)}t.default=r,n.c[n.s]===e&&r(process.argv)},3292(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(9528),t),i.__exportStar(n(4291),t),i.__exportStar(n(9831),t),i.__exportStar(n(9647),t),i.__exportStar(n(5451),t),i.__exportStar(n(1955),t),i.__exportStar(n(8952),t),i.__exportStar(n(1051),t),i.__exportStar(n(618),t),i.__exportStar(n(7129),t),i.__exportStar(n(221),t),i.__exportStar(n(1095),t),i.__exportStar(n(3735),t),i.__exportStar(n(3536),t)},3536(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},3681(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.measureQueryForBrowser=async function(e,t){return t()}},3735(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},3803(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getTenantDB=void 0;const i=n(6178),o=new Map;t.getTenantDB=async e=>{if(o.has(e))return o.get(e);const t=i.AmbitenClient.init().withDatabase(e);if(!t)throw new Error(`Database not found for tenant: ${e}`);return o.set(e,await t.db()),await t.db()}},3868(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(5584).__exportStar(n(6720),t)},3904(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.runGarbageCollectorOnAllModels=async function(e={}){const t=i.AmbitenModelRegistry.getAllModels(),n={scanned:t.length,succeeded:0,failed:0,models:[]};for(const i of t){const t=i.getContext?.(),a=t?.ctx?.collectionName;try{if("function"!=typeof i.runGC)throw new Error("Registered model does not implement runGC().");await i.runGC(e.ctx),n.succeeded+=1,n.models.push({collectionName:a,success:!0})}catch(t){if(n.failed+=1,n.models.push({collectionName:a,success:!1,error:t}),console.error((0,o.colorize)(`[GC] Failed on collection "${a??"unknown"}"`,"red"),t),!e.continueOnError)throw t}}return n},t.runGarbageCollector=async function(e,t){await e.runGC(t)};const i=n(8686),o=n(960)},3907(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(9228),t),i.__exportStar(n(3681),t)},3946(e){"use strict";e.exports=require("graphql-subscriptions")},4131(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.cacheWithRedis=async function(e,t,n,o={}){const a=new i.AmbitenCache(e);return await a.wrap(t,n,o)};const i=n(3100)},4172(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.generateProject=l,t.generateProjectWithConfig=async function(e){return l({...e,projectName:e.projectName||"Ambiten-app"})};const i=n(5584),o=i.__importDefault(n(4652)),a=i.__importDefault(n(6928)),r=n(1538),s=n(960);async function l(e){const t=Date.now(),n=e.projectName?.trim()||"Ambiten-app",i=a.default.resolve(process.cwd(),n),l=a.default.join(i,"Ambiten.config.json"),c=a.default.join(i,"src","main.ts");console.log((0,s.colorize)(`\n🚀 Creating project "${n}"`,"green")),console.log((0,s.colorize)(`📁 Location: ${i}\n`,"blue")),await o.default.ensureDir(i);const d=(0,s.createScaffoldLogger)(i),u={...e,projectName:n};await(0,r.generateAppStructure)(i,u,d);const m=Date.now()-t;return d.printSummary(n,u,m),{projectRoot:i,configPath:l,entryFilePath:c}}},4239(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createScaffoldLogger=function(e){const t={files:[],dirs:[]},n=t=>i.default.relative(e,t).replace(/\\/g,"/");return{addFile(e){t.files.push(n(e))},addDir(e){t.dirs.push(n(e)+"/")},printSummary(e,n,i){const a=[n.multiTenant?.enabled?"Multi-tenancy":null,n.graphql?.enabled?"GraphQL":null,n.logger?.enabled?"Logger":null,n.features?.useRedisCache?"Redis Cache":null,n.advanced?.garbageCollector?.enabled?"Garbage Collector":null].filter(Boolean),r=[n.multiTenant?.enabled?null:"Multi-tenancy",n.graphql?.enabled?null:"GraphQL",n.logger?.enabled?null:"Logger",n.features?.useRedisCache?null:"Redis Cache",n.advanced?.garbageCollector?.enabled?null:"Garbage Collector"].filter(Boolean),s=(i/1e3).toFixed(2);console.log(""),console.log((0,o.colorize)(`✔ Project scaffold completed in ${s}s`,"green")),console.log(""),t.dirs.length&&(console.log((0,o.colorize)("Directories:","blue")),t.dirs.forEach(e=>{console.log((0,o.colorize)(` + ${e}`,"green"))}),console.log("")),t.files.length&&(console.log((0,o.colorize)("Files:","blue")),t.files.forEach(e=>{console.log((0,o.colorize)(` + ${e}`,"green"))}),console.log("")),console.log((0,o.colorize)("Feature summary:","blue")),a.forEach(e=>{console.log((0,o.colorize)(` ✓ ${e}`,"green"))}),r.forEach(e=>{console.log((0,o.colorize)(` ✗ ${e}`,"yellow"))}),console.log(""),console.log((0,o.colorize)("Next steps:","blue")),console.log((0,o.colorize)(` cd ${e}`,"green")),console.log((0,o.colorize)(" pnpm install","green")),console.log((0,o.colorize)(" pnpm dev","green")),console.log("")}}};const i=n(5584).__importDefault(n(6928)),o=n(5341)},4291(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SchemaType=void 0;const i=n(2518);t.SchemaType={Types:{ObjectId:i.ObjectId}}},4434(e){"use strict";e.exports=require("events")},4443(e){"use strict";e.exports=require("prompts")},4469(e){"use strict";e.exports=require("dotenv/config")},4629(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.buildInteractiveConfig=async function(e,t){const n=await(0,i.default)([{type:e?null:"text",name:"projectName",message:"Project name",initial:"Ambiten-app",validate:e=>e.trim().length>0||"Project name is required"},{type:a(t.uri)?null:"text",name:"uri",message:"MongoDB URI",initial:(t,n)=>`mongodb://localhost:27017/${o(e||n.projectName||"Ambiten-app")}`,validate:e=>e.trim().length>0||"MongoDB URI is required"},{type:a(t.withGraphql)?null:"toggle",name:"withGraphql",message:"Include GraphQL starter support?",initial:!1,active:"yes",inactive:"no"},{type:a(t.multiTenant)?null:"toggle",name:"multiTenant",message:"Enable multi-tenancy?",initial:!1,active:"yes",inactive:"no"},{type:a(t.logger)?null:"toggle",name:"logger",message:"Enable logger configuration?",initial:!0,active:"yes",inactive:"no"},{type:a(t.withRedis)?null:"toggle",name:"withRedis",message:"Enable Redis cache defaults?",initial:!1,active:"yes",inactive:"no"},{type:a(t.withGarbageCollector)?null:"toggle",name:"withGarbageCollector",message:"Enable garbage collector starter files?",initial:!1,active:"yes",inactive:"no"},{type:a(t.install)?null:"toggle",name:"install",message:"Install dependencies after scaffold?",initial:!1,active:"yes",inactive:"no"}],{onCancel:()=>{throw new Error("CLI initialization cancelled by user.")}}),r=o(e||n.projectName||"Ambiten-app"),s=t.uri||n.uri||`mongodb://localhost:27017/${r}`,l=a(t.withGraphql)?Boolean(t.withGraphql):Boolean(n.withGraphql),c=a(t.multiTenant)?Boolean(t.multiTenant):Boolean(n.multiTenant),d=a(t.logger)?Boolean(t.logger):Boolean(n.logger),u=a(t.withRedis)?Boolean(t.withRedis):Boolean(n.withRedis),m=a(t.withGarbageCollector)?Boolean(t.withGarbageCollector):Boolean(n.withGarbageCollector),h={projectName:r,connection:{uri:s,options:{dbName:r}},features:{useRedisCache:u,redisUri:u?"redis://localhost:6379":""},advanced:{autoInstall:a(t.install)?Boolean(t.install):Boolean(n.install),garbageCollector:{enabled:m}}};if(l&&(h.graphql={enabled:!0,subscriptions:!1,playground:!0,schemaOutputPath:"./src/graphql/schema.gql"}),d&&(h.logger={enabled:!0,level:"info",colorize:!0,json:!1,transports:[{type:"console",options:{}}]}),c&&(h.multiTenant={enabled:!0,headerKey:"x-tenant-id",tenants:{tenant1:`mongodb://localhost:27017/${r}_tenant1`},initOptions:{lazy:!0}}),t.rbac&&(h.features={...h.features}),function(e){const t=["","Scaffold summary:",` Project: ${e.projectName}`,` MongoDB URI: ${e.connection?.uri??"(none)"}`," GraphQL: "+(e.graphql?.enabled?"enabled":"disabled")," Multi-tenancy: "+(e.multiTenant?.enabled?"enabled":"disabled")," Logger: "+(e.logger?.enabled?"enabled":"disabled")," Redis Cache: "+(e.features?.useRedisCache?"enabled":"disabled")," Garbage Collector: "+(e.advanced?.garbageCollector?.enabled?"enabled":"disabled")," Auto-install: "+(e.advanced?.autoInstall?"enabled":"disabled"),""];console.log(t.join("\n"))}(h),!(await(0,i.default)({type:"toggle",name:"proceed",message:"Proceed with project generation?",initial:!0,active:"yes",inactive:"no"},{onCancel:()=>{throw new Error("Project generation cancelled by user.")}})).proceed)throw new Error("Project generation cancelled by user.");return h};const i=n(5584).__importDefault(n(4443));function o(e){return e.trim().replace(/\s+/g,"-").toLowerCase()}function a(e){return void 0!==e}},4652(e){"use strict";e.exports=require("fs-extra")},4835(e){"use strict";e.exports=require("redis")},4878(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.applySoftDelete=function(e,t={}){const s={...n,...t};if(!s.enabled)return e;const l=e=>{!0!==e.withDeleted&&(!0!==e.onlyDeleted?s.excludeDeletedByDefault&&(e.filter=a(e.filter,i(s))):e.filter=a(e.filter,o(s)))};return e.beforeFind(e=>{l(e)}),e.beforeFindOne(e=>{l(e)}),e.beforeFindOneAndUpdate(e=>{l(e)}),e.beforeFindOneAndReplace(e=>{l(e)}),e.beforeFindOneAndUpsert(e=>{l(e)}),e.beforeAggregate(e=>{if(!0===e.withDeleted)return;const t=!0===e.onlyDeleted?{$match:o(s)}:s.excludeDeletedByDefault?{$match:i(s)}:null;t&&(e.pipeline=[t,...e.pipeline??[]])}),e.beforeDeleteOne(e=>{!0!==e.hardDelete&&(e.filter=a(e.filter,i(s)),e.update=r(s),e.meta={...e.meta??{},softDelete:!0})}),e.beforeDeleteMany(e=>{!0!==e.hardDelete&&(e.filter=a(e.filter,i(s)),e.update=r(s),e.meta={...e.meta??{},softDelete:!0})}),e.beforeFindOneAndDelete(e=>{e.filter=a(e.filter,i(s)),!0!==e.hardDelete&&(e.update=r(s),e.meta={...e.meta??{},softDelete:!0})}),e.setSoftDeleteConfig({deletedAtField:s.deletedAtField,isDeletedField:s.isDeletedField}),e};const n={field:"deletedAt",deletedAtField:"deletedAt",deletedByField:"deletedBy",isDeletedField:"isDeleted",enabled:!0,excludeDeletedByDefault:!0};function i(e){return{$and:[{$or:[{[e.deletedAtField]:{$exists:!1}},{[e.deletedAtField]:null}]},{$or:[{[e.isDeletedField]:{$exists:!1}},{[e.isDeletedField]:!1}]}]}}function o(e){return{$or:[{[e.deletedAtField]:{$ne:null}},{[e.isDeletedField]:!0}]}}function a(e,t){return e&&0!==Object.keys(e).length?{$and:[e,t]}:t}function r(e){return{$set:{[e.deletedAtField]:new Date,[e.isDeletedField]:!0}}}},5303(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.runManualTransaction=async function(e,t){if(!(0,i.hasManualTransactionMethods)(e))throw new Error("Session does not implement manual transaction methods.");e.startTransaction();try{const n=await t(e);return await e.commitTransaction(),n}catch(t){throw await e.abortTransaction(),t}finally{await e.endSession()}};const i=n(7038)},5317(e){"use strict";e.exports=require("child_process")},5341(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.colorize=void 0,t.colorize=(e,t)=>{switch(t){case"red":return`[31m${e}[0m`;case"green":return`[32m${e}[0m`;case"magenta":return`[35m${e}[0m`;case"cyan":return`[36m${e}[0m`;case"yellow":return`[33m${e}[0m`;case"blue":return`[34m${e}[0m`}return`[36m${e}[0m`}},5381(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.MultiTenantManager=void 0;const i=n(2518);class o{static tenants=new Map;constructor(){}static hasTenant(e){return this.tenants.has(e)}static registerLazyTenant(e,t,n={}){this.validateTenantId(e),this.validateUri(t);const i=e.trim(),o={tenantId:i,uri:t.trim(),dbName:n.dbName?.trim()||this.extractDbNameFromUri(t)||i,client:void 0,lazy:!0,metadata:n.metadata};return this.tenants.set(i,o),o}static async registerTenant(e,t,n={}){this.validateTenantId(e),this.validateUri(t);const o=e.trim(),a=this.tenants.get(o);if(a?.client)return a.client;const r=n.client??new i.MongoClient(t);n.client||await r.connect();const s={tenantId:o,uri:t.trim(),dbName:n.dbName?.trim()||this.extractDbNameFromUri(t)||o,client:r,lazy:!1,metadata:n.metadata};return this.tenants.set(o,s),r}static async getClient(e){this.validateTenantId(e);const t=e.trim(),n=this.tenants.get(t);if(!n)return null;if(n.client)return n.client;if(n.lazy){const e=new i.MongoClient(n.uri);return await e.connect(),this.tenants.set(t,{...n,client:e,lazy:!1}),e}return null}static getTenant(e){return this.validateTenantId(e),this.tenants.get(e.trim())}static getTenantDbName(e){return this.getTenant(e)?.dbName}static getConnectedTenant(){const e=Array.from(this.tenants.values()).find(e=>!!e.client);return e?.tenantId||""}static getAllConnectedTenants(){return Array.from(this.tenants.values()).filter(e=>!!e.client).map(e=>e.tenantId)}static getAllTenants(){return Array.from(this.tenants.values())}static isEnabled(){return this.tenants.size>0}static removeTenant(e){return this.validateTenantId(e),this.tenants.delete(e.trim())}static clearTenants(){this.tenants.clear()}static validateTenantId(e){if(!e||"string"!=typeof e||!e.trim())throw new Error("Tenant ID is required.")}static validateUri(e){if(!e||"string"!=typeof e||!e.trim())throw new Error("MongoDB URI is required.");if(!e.startsWith("mongodb://")&&!e.startsWith("mongodb+srv://"))throw new Error(`Invalid MongoDB URI: ${e}`)}static extractDbNameFromUri(e){try{const t=e.split("?")[0].split("/"),n=t[t.length-1];if(!n||n.includes(":"))return;return n.trim()||void 0}catch{return}}}t.MultiTenantManager=o},5451(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5584(e){"use strict";e.exports=require("tslib")},5596(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.generateMainTS=function(e){return"import { run } from './core/initAmbiten';\n\nasync function main() {\n const app = await run();\n\n if (typeof app?.onConnect === 'function') {\n app.onConnect(() => {\n console.log('✅ Ambiten application initialized successfully.');\n });\n }\n\n return app;\n}\n\nmain().catch((error) => {\n console.error('❌ Failed to start application:', error);\n process.exit(1);\n});\n"}},5709(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.configureAmbitenContext=function(e){i.AmbitenContext.configureTransactionResolver({resolveClient:async(t,n)=>{if(t){const e=await o.MultiTenantManager.getClient(t);if(e)return e}if("function"==typeof e.client){const i={tenantId:t,dbName:n};return e.client(i)}}})};const i=n(8742),o=n(901)},5710(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenCache=void 0,t.createAmbitenCache=function(e=i.redis){return new a(e)};const i=n(3868),o=n(8742);class a{client;constructor(e=i.redis){this.client=e}buildKey(e,t={}){const n=o.AmbitenContext.get();return[t.prefix??"Ambiten",t.tenantId??n.tenantId??"default",t.namespace??"cache",e].filter(Boolean).join(":")}async get(e,t){const n=this.buildKey(e,t),i=await this.client.get(n);if(null==i)return this.emit("miss",n),null;try{return this.emit("hit",n),JSON.parse(i)}catch{return await this.client.del(n),this.emit("corrupt",n),null}}async set(e,t,n={}){const i=this.buildKey(e,n);await this.client.set(i,JSON.stringify(t),{EX:n.ttlSeconds??60}),this.emit("set",i)}async wrap(e,t,n={}){const i=await this.get(e,n);if(null!==i)return i;const o=await t();return await this.set(e,o,n),o}async invalidate(e,t){const n=this.buildKey(e,t);await this.client.del(n),this.emit("invalidate",n)}async invalidatePattern(e){if(!e||"string"!=typeof e)throw new Error("Pattern must be a non-empty string.");if(!this.client.scan)throw new Error("Cache client does not support scan().");let t=0,n=0;do{const i=await this.client.scan(t,{MATCH:e,COUNT:100}),o=Array.isArray(i)?Number(i[0]):i.cursor,a=Array.isArray(i)?i[1]:i.keys;a.length>0&&(await this.client.del(a),n+=a.length),t=o}while(0!==t);return n>0&&this.emit("invalidatePattern",e),n}emit(e,t){}}t.AmbitenCache=a},5711(e){"use strict";e.exports=require("ajv")},5963(e){"use strict";e.exports=require("@graphql-tools/schema")},6013(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.scheduleGarbageCollector=function(e="0 * * * *"){const t="string"==typeof e?e:e.cronExpr??"0 * * * *",n="string"==typeof e?void 0:e.ctx,s="string"==typeof e||(e.continueOnError??!0);return i.schedule(t,async()=>{try{if(0===a.AmbitenModelRegistry.getAllModels().length)return void console.warn((0,r.colorize)("[GC] Skipping GC: no registered models found.","yellow"));console.log((0,r.colorize)(`[GC] Running garbage collector at ${(new Date).toISOString()}`,"blue"));const e=await(0,o.runGarbageCollectorOnAllModels)({ctx:n,continueOnError:s});console.log((0,r.colorize)(`[GC] Completed. scanned=${e.scanned}, succeeded=${e.succeeded}, failed=${e.failed}`,e.failed>0?"yellow":"blue"))}catch(e){console.error((0,r.colorize)("[GC] Error running garbage collector","red"),e)}})};const i=n(5584).__importStar(n(2703)),o=n(3904),a=n(8686),r=n(960)},6178(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(1679),t),i.__exportStar(n(9493),t),i.__exportStar(n(6903),t),i.__exportStar(n(7743),t)},6438(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createSchema=void 0;const i=n(6178);t.createSchema=e=>new i.AmbitenSchema(e)},6562(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.initializeRedis=void 0;const i=n(5584),o=n(3868);console.log("Ambiten Core Library Loaded. \n (Node.js environment detected.)"),t.initializeRedis=async({useRedis:e=!1}={})=>{if(e){const e=o.RedisService.getInstance(),t=await e.getClient();t.isOpen||await t.connect()}},i.__exportStar(n(6178),t),i.__exportStar(n(7743),t),i.__exportStar(n(1349),t),i.__exportStar(n(3868),t),i.__exportStar(n(901),t),i.__exportStar(n(8742),t),i.__exportStar(n(1737),t),i.__exportStar(n(3907),t),i.__exportStar(n(9490),t),i.__exportStar(n(3100),t),i.__exportStar(n(4172),t),i.__exportStar(n(7803),t),i.__exportStar(n(7900),t),i.__exportStar(n(960),t),i.__exportStar(n(9729),t),i.__exportStar(n(8093),t),i.__exportStar(n(3292),t)},6570(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TenantContext=void 0;const i=new(n(6698).AsyncLocalStorage);t.TenantContext=class{static run(e,t){if(!e)throw new Error("tenantId is required to run tenant context");i.run({tenantId:e},t)}static setTenantId(e){const t=i.getStore();t&&(t.tenantId=e)}static getTenantId(){return i.getStore()?.tenantId}static clear(){const e=i.getStore();e&&(e.tenantId=void 0)}}},6698(e){"use strict";e.exports=require("node:async_hooks")},6720(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RedisService=t.redis=void 0,t.connectRedis=async function(){return{connect:async e=>t.redis.getClient(e)}},n(4469);const i=n(4835),o=e=>Math.min(50*e,1e3),a=process.env.REDIS_URI;let r=null;const s=()=>({isOpen:!1,connect:async()=>null,disconnect:async()=>null,publish:async()=>0,subscribe:async()=>null,duplicate:()=>s(),get:async()=>null,set:async()=>"OK",del:async()=>0,exists:async()=>0,scan:async()=>({cursor:0,keys:[]}),multi:()=>({incr(){return this},expire(){return this},exec:async()=>[]})});t.redis={async getClient(e){if(r&&r.isOpen)return r;const t=e||a;if(!t)return s();try{const e=(0,i.createClient)({url:t,socket:{reconnectStrategy:o}});return await e.connect(),r=e,e}catch{return s()}},async disconnect(){if(r)try{r.isOpen&&"function"==typeof r.disconnect?await r.disconnect():r.isOpen&&"function"==typeof r.quit&&await r.quit()}catch{}r=null},get isOpen(){return!!r?.isOpen},async get(e){const t=await this.getClient();return t.get?.(e)},async set(e,t,n){const i=await this.getClient();return i.set?.(e,t,n)},async del(...e){const t=await this.getClient();return t.del?.(e)},async exists(e){const t=await this.getClient();return t.exists?.(e)},async scan(e=0,t){const n=await this.getClient();return"function"!=typeof n.scan?{cursor:0,keys:[]}:n.scan(e,t)},async publish(e,t){const n=await this.getClient();return n.publish?.(e,t)},async subscribe(e,t){const n=await this.getClient();return n.subscribe?.(e,t)},duplicate:()=>r?.duplicate?r.duplicate():s(),multi:()=>r?.multi?r.multi():s().multi?.()};class l{static getInstance(){return new l}async connect(e){await t.redis.getClient(e)}getClient(){return t.redis.getClient()}async close(){await t.redis.disconnect()}}t.RedisService=l},6793(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.generateGCRunner=function(){return"/**\n * Garbage collector runner\n *\n * Replace the imports below with your actual bootstrap/model entry points.\n */\n\nimport { runGarbageCollector } from './gcManager';\n// import { UserModel } from '../models/UserModel';\n\nasync function main() {\n // Example:\n // await runGarbageCollector(UserModel, { retentionPeriod: 7 });\n console.log('⚠️ Update gcRunner.ts with your model imports before using it.');\n}\n\nmain().catch((error) => {\n console.error('❌ Garbage collector failed:', error);\n process.exit(1);\n});\n"}},6858(e){"use strict";e.exports=require("commander")},6880(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getEventOptions=function(e){const t=o[e]||e;return{[t]:!0}},t.getEventType=function(e){const t=Object.keys(e).find(e=>Object.values(o).includes(e));return t&&Object.keys(o).find(e=>o[e]===t)||null},t.describeEvent=a,t.logEvent=r,t.logDefaultEvent=function(e,t,n,o){return r((0,i.setupLogger)(),e,t,n,o),e};const i=n(9451),o={"pre-save":"save","post-save":"save","pre-update":"update","post-update":"update","pre-delete":"delete","post-delete":"delete",aggregate:"aggregate",disconnect:"disconnect",connect:"connect",dropDatabase:"dropDatabase",createIndex:"index",dropIndex:"index",create:"create",find:"find",findOne:"find",insertOne:"insertOne",insertMany:"insertMany",updateOne:"updateOne",updateMany:"updateMany",deleteOne:"deleteOne",deleteMany:"deleteMany","pre-bulkWrite":"bulkWrite","post-bulkWrite":"bulkWrite","pre-insertMany":"insertMany","post-insertMany":"insertMany","pre-updateMany":"updateMany","post-updateMany":"updateMany","pre-deleteMany":"deleteMany","post-deleteMany":"deleteMany",transaction:"transaction"};function a(e){return{"pre-save":"Before Save","post-save":"After Save","pre-update":"Before Update","post-update":"After Update","pre-delete":"Before Delete","post-delete":"After Delete",aggregate:"Aggregation",disconnect:"Disconnect",connect:"Connect",dropDatabase:"Drop Database",createIndex:"Create Index",dropIndex:"Drop Index",create:"Create",find:"Find",findOne:"Find One",insertOne:"Insert One",insertMany:"Insert Many",updateOne:"Update One",updateMany:"Update Many",deleteOne:"Delete One",deleteMany:"Delete Many"}[e]||e}function r(e,t,n,i="info",o){const r=a(t),s={level:i,message:n?`[Ambiten EVENT]: ${r}: ${n}`:`[Ambiten] Event: ${r}`,context:o};e.info(`${s.level}${s.message} ${s.context?JSON.stringify(s.context):""}`)}},6903(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Schema=t.AmbitenSchema=void 0;class n{schemaDefinition;indexes=[];virtuals={};validators={};relationships=[];gcConfig;middleware={pre:{},post:{}};constructor(e){this.schemaDefinition=e}getSchema(){return this.schemaDefinition}registerSchema(e){this.schemaDefinition=e,console.info("Schema registered:",this.schemaDefinition)}validator(e,t){this.validators[e]=t}validate(e){for(const[t,n]of Object.entries(this.validators)){const i=n(e[t],e);if(i instanceof Promise)throw new Error(`Validator for field "${t}" is async. Use validateAsync() instead.`);if(!i)throw console.log(`[error]: Validation failed for field: ${t}`),new Error(`Validation failed for field: ${t}`)}}async validateAsync(e){for(const[t,n]of Object.entries(this.validators))if(!await n(e[t],e))throw console.log(`[error]: Validation failed for field: ${t}`),new Error(`Validation failed for field: ${t}`)}index(e,t){this.indexes.push({fields:e,options:t})}async applyIndexes(e){for(const{fields:t,options:n}of this.indexes)await e.createIndex(t,n)}addRelationship(e,t){this.relationships.push({ref:e,localField:t})}getRelationships(){return this.relationships}virtual(e,t){this.virtuals[e]=t}applyVirtuals(e){for(const[t,n]of Object.entries(this.virtuals))Object.defineProperty(e,t,{get:()=>n(e),enumerable:!0})}pre(e,t){return this.middleware.pre[e]||(this.middleware.pre[e]=[]),this.middleware.pre[e].push(t),this}post(e,t){return this.middleware.post[e]||(this.middleware.post[e]=[]),this.middleware.post[e].push(t),this}getPreHooks(e){return this.middleware.pre[e]||[]}getPostHooks(e){return this.middleware.post[e]||[]}getHooks(e,t="pre"){return"pre"===t?this.getPreHooks(e):this.getPostHooks(e)}async executePre(e,t){const n=this.getPreHooks(e);for(const e of n)await e(t)}async executePost(e,t){const n=this.getPostHooks(e);for(const e of n)await e(t)}async executeMiddleware(e,t,n){const i=this.getHooks(t,e);for(const o of i)try{await o(n)}catch(n){throw console.error(`[error]: Error in ${e}:${t} middleware:`,n),n}}async triggerMiddleware(e,t,n){await this.executeMiddleware(e,t,n)}setGCConfig(e){return this.gcConfig=e,this}getGCConfig(){return this.gcConfig}}t.AmbitenSchema=n;class i extends n{constructor(e){super(e),this.registerSchema(e)}async create(e){await this.validateAsync(e);const t={operation:"create",collectionName:"schema-test",doc:e};await this.executePre("create",t);const n=e;this.applyVirtuals(n);const i={...t,result:n,doc:n};return await this.executePost("create",i),n}static create(e){return new i(e)}}t.Schema=i},6928(e){"use strict";e.exports=require("path")},6939(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.generateAppStructure=async function(e,t,n){const i=a.default.join(e,"src"),u=a.default.join(i,"core"),m=a.default.join(i,"utils"),h=a.default.join(i,"types"),p=a.default.join(i,"models"),f=a.default.join(i,"graphql"),g=a.default.join(i,"gc");await o.default.ensureDir(i),n?.addDir(i),await o.default.ensureDir(u),n?.addDir(u),await o.default.ensureDir(m),n?.addDir(m),await o.default.ensureDir(h),n?.addDir(h),await o.default.ensureDir(p),n?.addDir(p),t.graphql?.enabled&&(await o.default.ensureDir(f),n?.addDir(f)),t.advanced?.garbageCollector?.enabled&&(await o.default.ensureDir(g),n?.addDir(g));const b=a.default.join(i,"main.ts");await o.default.writeFile(b,(0,s.generateMainTS)(t)),n?.addFile(b);const w=a.default.join(u,"initAmbiten.ts");await o.default.writeFile(w,"import { AmbitenBootstrapFactory } from '@ambiten/core';\nimport type { AmbitenRuntime } from '@ambiten/core';\n\nexport async function run(): Promise<AmbitenRuntime> {\n return AmbitenBootstrapFactory.create();\n}\n"),n?.addFile(w);const y=a.default.join(m,"helper.ts");await o.default.writeFile(y,"export function noop(): void {}\n"),n?.addFile(y);const N=a.default.join(h,"config.ts");if(await o.default.writeFile(N,"export {};\n"),n?.addFile(N),t.graphql?.enabled){const e=a.default.join(f,"schema.gql");await o.default.writeFile(e,"type Query {\n hello: String\n}\n"),n?.addFile(e);const t=a.default.join(f,"resolvers.ts");await o.default.writeFile(t,"export const resolvers = {\n Query: {\n hello: () => 'Hello, world!',\n },\n};\n"),n?.addFile(t),await o.default.writeFile(a.default.join(f,"graphql.ts"),"/**\n * Optional GraphQL starter file.\n *\n * Use this file if you want to separate GraphQL setup from your bootstrap flow.\n * If your bootstrap already initializes GraphQL, this file can be removed.\n */\n\nexport {};\n")}if(t.advanced?.garbageCollector?.enabled){const e=a.default.join(g,"gcManager.ts");await o.default.writeFile(e,(0,c.generateGCManager)()),n?.addFile(e);const t=a.default.join(g,"gcRunner.ts");await o.default.writeFile(t,(0,d.generateGCRunner)()),n?.addFile(t)}const v=a.default.join(e,"ambiten.config.json");await o.default.writeFile(v,(0,l.DEFAULT_CONFIG_CONTENT)(t)),n?.addFile(v);const _=a.default.join(e,"package.json");await o.default.writeJson(_,function(e){const t={"@ambiten/core":"^1.0.0",mongodb:"^6.14.2"};return e.logger?.enabled&&(t["@ambiten/logger"]="^1.0.0"),e.graphql?.enabled&&(t.graphql="^16.11.0",t["@apollo/server"]="^5.1.0"),e.features?.useRedisCache&&(t.redis="^4.7.1"),{name:e.projectName??"my-ambiten-app",description:"A Ambiten-powered application",private:!0,version:"1.0.0",type:"commonjs",main:"dist/main.js",scripts:{dev:"ts-node src/main.ts",build:"tsc",start:"node dist/main.js"},license:"ISC",dependencies:t,devDependencies:{typescript:"^5.9.3","ts-node":"^10.9.2","@types/node":"^22.15.30"}}}(t),{spaces:2}),n?.addFile(_);const C=a.default.join(e,"tsconfig.json");await o.default.writeJson(C,{compilerOptions:{target:"ES2021",module:"commonjs",moduleResolution:"node",rootDir:"./src",outDir:"./dist",sourceMap:!0,declaration:!0,declarationMap:!0,esModuleInterop:!0,resolveJsonModule:!0,strict:!0,noImplicitAny:!0,noImplicitReturns:!0,noUncheckedIndexedAccess:!0,exactOptionalPropertyTypes:!0,forceConsistentCasingInFileNames:!0,skipLibCheck:!0,types:["node"],lib:["ES2021"]},include:["src/**/*"],exclude:["node_modules","dist"]},{spaces:2}),n?.addFile(C);const O=a.default.join(e,".gitignore");if(await o.default.writeFile(O,"node_modules\ndist\nlib\n.store\n.env\n"),n?.addFile(O),t.advanced?.autoInstall){const t=(0,r.detectPackageManager)(e);try{await(0,r.installPackages)([],e),console.log((0,r.colorize)(`[Installing dependencies]: Installed project dependencies using ${t}.`,"green"))}catch(e){console.log((0,r.colorize)("⚠️ Dependency installation failed or was interrupted. Skipping install.","yellow"),e)}}else{const t=(0,r.detectPackageManager)(e),n="npm"===t?"npm install":`${t} install`;console.log((0,r.colorize)("[Skipping install]: Set advanced.autoInstall=true to install dependencies automatically.","blue")),console.log((0,r.colorize)(`[Next steps]: cd ${e} && ${n}`,"blue"))}};const i=n(5584),o=i.__importDefault(n(4652)),a=i.__importDefault(n(6928)),r=n(960),s=n(5596),l=n(1299),c=n(7004),d=n(6793)},6941(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.rolePermissions=void 0,t.rolePermissions={admin:["create","read","update","delete"],user:["create","read","update"],viewer:["read"]}},7004(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.generateGCManager=function(){return"import { AmbitenModel } from '@ambiten/core';\nimport { ObjectId } from 'mongodb';\n\nexport interface GarbageCollectorOptions {\n /**\n * Retention period in days.\n */\n retentionPeriod?: number;\n dateField?: string;\n}\n\nexport async function runGarbageCollector(\n model: AmbitenModel<any>,\n options: GarbageCollectorOptions = {}\n): Promise<void> {\n const retentionPeriod = options.retentionPeriod ?? 7;\n const dateField = options.dateField ?? 'deletedAt';\n\n const cutoff = new Date(\n Date.now() - retentionPeriod * 24 * 60 * 60 * 1000\n );\n\n const expiredDocs = await model.find({\n [dateField]: { $lt: cutoff }\n });\n\n for (const doc of expiredDocs) {\n await model.deleteOne({ _id: new ObjectId(doc._id) });\n console.log(`🗑️ Deleted expired document: ${doc._id}`);\n }\n\n console.log('✅ Garbage collection completed.');\n}\n"}},7038(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.hasManualTransactionMethods=function(e){return"function"==typeof e.startTransaction&&"function"==typeof e.commitTransaction&&"function"==typeof e.abortTransaction}},7129(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7219(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.initMultiTenancy=void 0;const i=n(5381);t.initMultiTenancy=async(e,t={})=>{const{lazy:n=!1,config:o}=t;for(const[t,a]of Object.entries(e)){if(!a||"string"!=typeof a||!a.startsWith("mongodb"))throw new Error(`Invalid MongoDB URI for tenant "${t}": ${a}`);if(i.MultiTenantManager.hasTenant(t))o?.logger?.warn?.(`Tenant "${t}" is already registered. Skipping.`);else if(n){if(o?.enabled&&o.logger)return o.logger;i.MultiTenantManager.registerLazyTenant(t,a)}else await i.MultiTenantManager.registerTenant(t,a)}}},7221(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenGraphQL=void 0,n(4469);const i=n(5963),o=n(1684),a=n(2518),r=n(3868),s=n(960);t.AmbitenGraphQL=class{options;typeDefs=[];resolvers=[];useRedis;provider;subscriber=null;publisher=null;constructor(e){this.options=e,this.useRedis=!1!==e.useRedis,this.typeDefs=e.customTypeDefs??[],this.resolvers=e.customResolvers??[],this.provider=e.provider}customTypeDefs(e){return Array.isArray(e)?this.typeDefs.push(...e):this.typeDefs.push(e),this}customResolvers(e){return this.resolvers.push(e),this}toModelContext(e,t){return{tenantId:e.tenantId,dbName:e.dbName,collectionName:t??e.collectionName,session:e.session}}async getCollection(e,t){const n=this.toModelContext(e,t);return e.provider.collection(t,n)}async ensureRedis(){if(!this.useRedis)return;const e=await r.redis.get();e&&(e.isOpen||"function"!=typeof e.connect||await e.connect(),this.publisher||(this.publisher="function"==typeof e.duplicate?e.duplicate():e,this.publisher?.connect&&!this.publisher.isOpen&&await this.publisher.connect()),this.subscriber||(this.subscriber="function"==typeof e.duplicate?e.duplicate():e,this.subscriber?.connect&&!this.subscriber.isOpen&&await this.subscriber.connect()))}async publishEvent(e,t){if(!this.useRedis)return;await this.ensureRedis();const n=await r.redis.get();this.publisher?.publish?await this.publisher.publish(e,JSON.stringify(t)):n?.publish&&await n.publish(e,JSON.stringify(t))}defaultTypeDefs(){return o.gql`
|
|
3
|
+
scalar JSON
|
|
4
|
+
|
|
5
|
+
type Document {
|
|
6
|
+
_id: ID!
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type Query {
|
|
10
|
+
findOne(collection: String!, id: ID!): JSON
|
|
11
|
+
findAll(collection: String!): [JSON!]!
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type Mutation {
|
|
15
|
+
insertOne(collection: String!, data: JSON!): JSON
|
|
16
|
+
updateOne(collection: String!, id: ID!, data: JSON!): JSON
|
|
17
|
+
deleteOne(collection: String!, id: ID!): Boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type Subscription {
|
|
21
|
+
documentInserted(collection: String!): JSON
|
|
22
|
+
documentUpdated(collection: String!): JSON
|
|
23
|
+
documentDeleted(collection: String!): JSON
|
|
24
|
+
}
|
|
25
|
+
`}defaultResolvers(){return{Query:{findOne:async(e,{collection:t,id:n},i)=>(await this.getCollection(i,t)).findOne({_id:new a.ObjectId(n)}),findAll:async(e,{collection:t},n)=>(await this.getCollection(n,t)).find({}).toArray()},Mutation:{insertOne:async(e,{collection:t,data:n},i)=>{const o=await this.getCollection(i,t),a=await o.insertOne(n),r=await o.findOne({_id:a.insertedId});return await this.publishEvent(`${s.DB_CHANGE_EVENT}`,{documentInserted:{action:"insertOne",collectionName:t,doc:r,tenantId:i.tenantId}}),r},updateOne:async(e,{collection:t,id:n,data:i},o)=>{const r=await this.getCollection(o,t);await r.updateOne({_id:new a.ObjectId(n)},{$set:i});const l=await r.findOne({_id:new a.ObjectId(n)});return await this.publishEvent(`${s.DB_CHANGE_EVENT}`,{documentUpdated:{action:"updateOne",collectionName:t,doc:l,tenantId:o.tenantId}}),l},deleteOne:async(e,{collection:t,id:n},i)=>{const o=await this.getCollection(i,t);return 1===(await o.deleteOne({_id:new a.ObjectId(n)})).deletedCount&&(await this.publishEvent(`${s.DB_CHANGE_EVENT}`,{documentDeleted:{action:"deleteOne",collectionName:t,id:n,tenantId:i.tenantId}}),!0)}},Subscription:{documentInserted:{subscribe:async()=>this.useRedis?(await this.ensureRedis(),this.subscriber):null},documentUpdated:{subscribe:async()=>this.useRedis?(await this.ensureRedis(),this.subscriber):null},documentDeleted:{subscribe:async()=>{if(this.useRedis)return await this.ensureRedis(),this.subscriber}}}}}subscriptions(){return this.useRedis}async generateSchema(){return await this.ensureRedis(),(0,i.makeExecutableSchema)({typeDefs:[this.defaultTypeDefs(),...this.typeDefs],resolvers:[this.defaultResolvers(),...this.resolvers]})}}},7234(e,t){"use strict";var n;Object.defineProperty(t,"__esModule",{value:!0}),t.ErrorType=void 0,function(e){e.AmbitenError="AmbitenError",e.AmbitenErrorType="AmbitenErrorType",e.AmbitenErrorStack="AmbitenErrorStack",e.AmbitenErrorMessage="AmbitenErrorMessage",e.AmbitenErrorCause="AmbitenErrorCause",e.AmbitenCollectionError="CollectionError",e.AmbitenParseError="ParseError",e.AmbitenBulkWriteError="MongoBulkWriteError",e.AmbitenConnectionError="ConnectionError",e.AmbitenSchemaError="SchemaError",e.AmbitenModelError="ModelError",e.INITIALIZATION_ERROR="INITIALIZATION_ERROR",e.Ambiten_ERROR="Ambiten_ERROR",e.NULL_OR_UNDEFINED="NULL_OR_UNDEFINED",e.INVALID_SCHEME_ERROR="INVALID_SCHEME_ERROR",e.CONNECTION_ERROR="CONNECTION_ERROR",e.UNEXPECTED_ERROR="UNEXPECTED_ERROR",e.SCHEMA_ERROR="SCHEMA_ERROR",e.SCHEMA_VALIDATION_ERROR="SCHEMA_VALIDATION_ERROR",e.NOT_FOUND="NOT_FOUND",e.NO_DATABASE_FOUND="NO_DATABASE_FOUND",e.NOT_FOUND_IN_CACHE="NOT_FOUND_IN_CACHE",e.VALIDATION_ERROR="VALIDATION_ERROR",e.UNIQUE_CONSTRAINT_VIOLATION="UNIQUE_CONSTRAINT_VIOLATION"}(n||(t.ErrorType=n={}))},7499(e){"use strict";e.exports=JSON.parse('{"$schema":"http://json-schema.org/draft-07/schema#","title":"Ambiten Configuration Schema","type":"object","additionalProperties":false,"properties":{"projectName":{"type":"string","description":"The name of the project."},"connection":{"type":"object","description":"MongoDB connection configuration used when no external provider is supplied at runtime.","properties":{"uri":{"type":"string","description":"MongoDB connection URI."},"options":{"type":"object","description":"Additional MongoDB client options."}},"required":["uri"],"additionalProperties":true},"multiTenant":{"type":"object","description":"Multi-tenant runtime configuration.","properties":{"enabled":{"type":"boolean","default":false},"headerKey":{"type":"string","default":"x-tenant-id","description":"Header used to resolve the tenant ID."},"tenants":{"type":"object","description":"Mapping of tenant IDs to MongoDB URIs.","additionalProperties":{"type":"string"}},"initOptions":{"type":"object","description":"Initialization options for multi-tenancy.","properties":{"lazy":{"type":"boolean","default":false},"retryAttempts":{"type":"integer","default":3},"config":{"type":"object"}},"additionalProperties":true}},"additionalProperties":false},"logger":{"type":"object","description":"Logger configuration.","properties":{"level":{"type":"string","enum":["debug","info","warn","error","fatal","trace"]},"colorize":{"type":"boolean"},"json":{"type":"boolean"},"transportConfigs":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["console","file","rotating-file"]},"options":{"type":"object"}},"additionalProperties":false}},"formatOptions":{"type":"object"},"excludedSources":{"type":"array","items":{"type":"string"}},"circuitBreaker":{"type":"object","properties":{"enabled":{"type":"boolean","default":true},"retryAttempts":{"type":"integer","default":5}},"additionalProperties":false},"enableMetrics":{"type":"object","properties":{"enabled":{"type":"boolean","default":false},"logInterval":{"type":"integer","minimum":1000,"default":60000}},"additionalProperties":false,"default":{"enabled":false,"logInterval":60000}},"compress":{"type":"object","properties":{"enabled":{"type":"boolean","default":false}},"additionalProperties":false,"default":{"enabled":false}}},"additionalProperties":true},"graphql":{"type":"object","description":"Optional GraphQL auto-generation/bootstrap feature. Useful for playgrounds, prototyping, and generated GraphQL flows.","properties":{"enabled":{"type":"boolean","default":false},"subscriptions":{"type":"boolean","default":false},"playground":{"type":"boolean","default":true},"schemaOutputPath":{"type":"string","default":"./src/graphql/schema.gql"}},"additionalProperties":false},"features":{"type":"object","description":"Optional feature paths and integrations.","properties":{"models":{"type":"string","default":"./src/models"},"schemas":{"type":"string","default":"./src/schemas"},"typeDefs":{"type":"string","default":"./src/graphql/typeDefs"},"resolvers":{"type":"string","default":"./src/graphql/resolvers"},"useRedisCache":{"type":"boolean","default":false},"redisUri":{"type":"string","default":""}},"additionalProperties":false},"advanced":{"type":"object","description":"Advanced runtime configuration.","properties":{"autoInstall":{"type":"boolean","default":false},"circuitBreaker":{"type":"object","properties":{"enabled":{"type":"boolean","default":true},"retryAttempts":{"type":"integer","default":5}},"additionalProperties":false},"garbageCollector":{"type":"object","description":"Garbage collector configuration.","properties":{"enabled":{"type":"boolean","default":false},"retentionPeriod":{"type":"integer","minimum":1,"default":30},"logResults":{"type":"boolean","default":true}},"additionalProperties":false},"gcCron":{"type":"string","default":"0 * * * *"}},"additionalProperties":false},"configVersion":{"type":"string","default":"1.0.0","description":"Version of the Ambiten config format."}}}')},7503(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AuthService=void 0;const i=n(5584).__importDefault(n(829));n(4469);const o=process.env.JWT_SECRET,a=process.env.REFRESH_SECRET,r=process.env.REFRESH_EXPIRATION||"7d",s=process.env.JWT_EXPIRATION||"1d";t.AuthService=class{static generateToken(e){return i.default.sign(e,o,{expiresIn:s})}static generateRefreshToken(e){return i.default.sign(e,a,{expiresIn:r})}static verifyToken(e){return i.default.verify(e,o)}}},7584(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7624(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isValidObjectId=void 0,t.isObjectId=a,t.castId=function(e){if("string"==typeof e){const n=e;if(!(0,t.isValidObjectId)(n))throw new Error("Invalid ObjectId format in castId");if(!a(e))throw new Error("Invalid ObjectId in castId");return o.ObjectId.createFromHexString(n)}return e};const i=n(529),o=n(2518);function a(e){return null!=e&&"object"==typeof e&&e.constructor===o.ObjectId&&!0===e[i.objectIdSymbol]}Object.defineProperty(o.ObjectId.prototype,"_id",{configurable:!0,enumerable:!0,get:function(){return this.toHexString()}}),Object.prototype.hasOwnProperty.call(o.ObjectId.prototype,"valueOf")||(o.ObjectId.prototype.valueOf=function(){return this.toString()}),t.isValidObjectId=e=>/^[0-9a-fA-F]{24}$/.test(e),o.ObjectId.prototype.toJSON=function(){return this.toHexString()},o.ObjectId.prototype[i.objectIdSymbol]=!0},7743(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(5584).__exportStar(n(2999),t)},7803(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(2590),t),i.__exportStar(n(6941),t),i.__exportStar(n(8183),t)},7825(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ensureModelNameSafe=function(e){if(!e||"string"!=typeof e)throw new Error("Model name must be a non-empty string");const t=e.trim();if(0===t.length)throw new Error("Model name cannot be just whitespace");if(!/^[A-Za-z0-9_]+$/.test(t))throw new Error("Model name must only contain letters, numbers, and underscores");return t}},7858(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getModelFilesFromPath=r,t.loadModelsFromPath=async function(e){const t=r(e),i=[];for(const e of t)try{const t=await n(1077)(e);t.default?i.push(t.default):console.warn(`No default export found in ${e}`)}catch(t){console.error(`Error loading model from ${e}:`,t)}return i};const i=n(5584),o=i.__importDefault(n(9896)),a=i.__importDefault(n(6928));function r(e){const t=[];return o.default.readdirSync(e).forEach(n=>{const i=a.default.join(e,n);o.default.statSync(i).isDirectory()?t.push(...r(i)):/\.(ts|js)$/.test(n)&&t.push(i)}),t}},7900(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(5584).__exportStar(n(7221),t)},8093(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(8781),t),i.__exportStar(n(6013),t),i.__exportStar(n(3904),t),i.__exportStar(n(9001),t)},8183(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.authorize=function(e){return(t,n,o)=>{let a;const r=t.headers?.authorization||t.headers.Authorization;if("string"==typeof r&&r.startsWith("Bearer ")&&(a=r.split(" ")[1]),!a)return n.status(401).json({error:"Access token required"});try{const t=i.AuthService.verifyToken(a);return console.info(`Decoded token: ${JSON.stringify(t)}`),t?e.includes(t.role)?t:n.status(403).json({error:"Access Denied"}):n.status(401).json({error:"Unauthorized"})}catch{n.status(401).json({error:"Unauthorized"})}}};const i=n(7503)},8686(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenModelRegistry=void 0,t.clearModelRegistryForTests=function(){for(const e of i)t.AmbitenModelRegistry.unregisterModel(e);i.length=0};const n=new Set;t.AmbitenModelRegistry={registerModel(e){n.add(e)},getRegisteredModel:e=>n.has(e)?e:null,isModelRegistered:e=>n.has(e),unregisterModel(e){n.delete(e)},getAllModels:()=>[...n],clear(){n.clear()}};const i=[]},8742(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(3057),t),i.__exportStar(n(7038),t),i.__exportStar(n(5303),t)},8781(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenGC=void 0;const i=n(5584).__importStar(n(2703)),o=n(960),a=n(3904);t.AmbitenGC=class{options;enabled;intervalMs;intervalRef=null;cronTask=null;constructor(e={}){if(this.options=e,this.enabled=!1!==e.enabled,this.intervalMs=e.interval?this.parseInterval(e.interval):6e4,e.retentionPeriod&&(this.intervalMs=24*e.retentionPeriod*60*60*1e3),this.enabled)return e.cron?(this.cronTask=i.schedule(e.cron,()=>{this.runOnce()}),void this.log("info",`[AmbitenGC] Cron schedule set to: ${e.cron}`)):e.interval?(this.start(),void this.log("info",`[AmbitenGC] Interval set to: ${e.interval}`)):void this.log("info","[AmbitenGC] Initialized. Manual run mode enabled.");this.log("info","[AmbitenGC] Garbage Collector is disabled.")}start(){this.enabled&&(this.intervalRef||(this.intervalRef=setInterval(()=>{this.runOnce()},this.intervalMs),this.log("info",`[AmbitenGC] Started GC loop every ${this.intervalMs} ms`)))}stop(){this.intervalRef&&(clearInterval(this.intervalRef),this.intervalRef=null),this.cronTask&&(this.cronTask.stop(),this.cronTask=null),this.log("info","[AmbitenGC] Stopped.")}async runOnce(e){if(!this.enabled)return{scanned:0,succeeded:0,failed:0,models:[]};const t=await(0,a.runGarbageCollectorOnAllModels)({ctx:e??this.options.ctx,continueOnError:this.options.continueOnError??!0});return this.options.logResults&&this.log(t.failed>0?"warn":"info",`[AmbitenGC] Completed. scanned=${t.scanned}, succeeded=${t.succeeded}, failed=${t.failed}`),t}parseInterval(e){const t=e.match(/^(\d+)([smhd])$/);if(!t)throw new Error(`Invalid interval format: ${e}`);const[,n,i]=t,o=Number.parseInt(n,10);switch(i){case"s":return 1e3*o;case"m":return 60*o*1e3;case"h":return 60*o*60*1e3;case"d":return 24*o*60*60*1e3;default:throw new Error(`Unknown time unit: ${i}`)}}log(e,t,n){const i=this.options.logger;i?.[e]?i[e]?.(t,n):"error"!==e?"warn"!==e?console.log((0,o.colorize)(t,"blue"),n??""):console.warn((0,o.colorize)(t,"yellow"),n??""):console.error((0,o.colorize)(t,"red"),n??"")}}},8917(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.invalidateTenantCache=async function(e,t,n){const i=n?`ambiten:${t}:${n}:*`:`ambiten:${t}:*`,o=await e.keys(i);o.length&&(await e.del(o),console.info(`🔁 Cleared ${o.length} cache entries for ${t}${n?` (${n})`:""}`))}},8952(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.eventTypes=void 0,t.eventTypes=["pre-save","post-save","pre-update","post-update","pre-delete","post-delete","aggregate","disconnect","connect","dropDatabase","createIndex","dropIndex","create","find","findOne","insertOne","insertMany","updateOne","updateMany","deleteOne","deleteMany","transaction"]},9001(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.startGarbageCollector=void 0;const i=n(960);t.startGarbageCollector=()=>{console.warn((0,i.colorize)("[GC] Garbage collector is disabled in the browser.","red"))}},9228(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.measureQuery=async function(e,t){if(!o.AmbitenContext.hasActiveContext())throw new Error("[Ambiten] Missing runtime context.");const n=o.AmbitenContext.getLogger(),a=o.AmbitenContext.getObserver(),r=o.AmbitenContext.getLoggerMeta()??{},s=o.AmbitenContext.getTenantId(),l=o.AmbitenContext.getRequestId(),c=o.AmbitenContext.getDbName(),d=e.collectionName??o.AmbitenContext.getCollectionName(),u=o.AmbitenContext.incrementQueries(),m=i.performance.now();try{const h=await t(),p=Math.round(100*(i.performance.now()-m))/100,f=o.AmbitenContext.addQueryTime(p),g={operation:e.operation,collectionName:d,durationMs:p,status:"success",tenantId:s,requestId:l,dbName:c,filter:e.filter,update:e.update,pipeline:e.pipeline,documentCount:e.documentCount,queriesExecuted:u.queriesExecuted,maxQueries:u.maxQueries,totalBudgetUsed:f.totalTimeMs,...r,...e.extra??{}};return setImmediate(()=>{a?.onQuery?.(g),n?.info?n.info("[Ambiten Query]",g):o.AmbitenContext.isDebug()&&console.log("[Ambiten Query]",g)}),h}catch(t){const u=Math.round(100*(i.performance.now()-m))/100,h=o.AmbitenContext.addQueryTime(u),p={operation:e.operation,collectionName:d,durationMs:u,status:"error",tenantId:s,requestId:l,dbName:c,filter:e.filter,update:e.update,pipeline:e.pipeline,documentCount:e.documentCount,queriesExecuted:h.queriesExecuted,maxQueries:h.maxQueries,totalBudgetUsed:h.totalTimeMs,errorMessage:t?.message,errorName:t?.name,...r,...e.extra??{}};throw setImmediate(()=>{a?.onQueryError?.({...p,error:t}),n?.error?n.error("[Ambiten Query Error]",p):o.AmbitenContext.isDebug()&&console.error("[Ambiten Query Error]",p)}),t}};const i=n(2987),o=n(3057)},9451(e){"use strict";e.exports=require("@ambiten/logger")},9490(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(5584).__exportStar(n(1891),t)},9493(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AmbitenModel=void 0;const i=n(5584);n(4469);const o=n(2518),a=n(1679),r=n(6903),s=i.__importDefault(n(4434)),l=n(3946),c=n(901),d=n(3868),u=n(960),m=n(8742),h=n(3907),p=n(9490),f=new l.PubSub;class g{_provider;_collectionName;_collectionOverride;_schema;_initialized=!1;_defaultCtx;_modelGCConfig;_gcConfig;_gcTimer;eventEmitter=new s.default;beforeMiddlewares=new Map;afterMiddlewares=new Map;_softDeleteConfig;constructor(e){if(!e){const t="AmbitenModel options are required.";throw(0,u.createAmbitenError)(u.ErrorType.NULL_OR_UNDEFINED,t,{details:{providedOptions:e,typeError:u.ErrorType.AmbitenModelError}})}if(!e.collectionName){const t="collectionName is required.";throw(0,u.createAmbitenError)(u.ErrorType.NULL_OR_UNDEFINED,t,{details:{providedOptions:e,typeError:u.ErrorType.AmbitenModelError}})}if(this._collectionName=e.collectionName,this._schema=e.schema??new r.AmbitenSchema({}),this._provider=e.provider??a.AmbitenClient.init(),this._collectionOverride=e.collection,this._modelGCConfig=e.gcConfig,e.ctx?.db){const t=e.ctx.db;this._provider={db:async()=>t}}(e.ctx?.tenantId||e.ctx?.dbName||e.ctx?.collectionName)&&(this._defaultCtx={tenantId:e.ctx?.tenantId,dbName:e.ctx?.dbName,collectionName:e.ctx?.collectionName,db:e.ctx?.db,session:e.ctx?.session,config:e.ctx?.config});const t=this.resolveSchemaGCConfig();(this.isGCEnabled()||t)&&u.AmbitenModelRegistry.registerModel(this),this.initMiddleware()}mergeCtx(e){const t=m.AmbitenContext.get(),n={tenantId:e?.tenantId??this._defaultCtx?.tenantId??t.tenantId,dbName:e?.dbName??this._defaultCtx?.dbName??t.dbName,db:e?.db??this._defaultCtx?.db,collectionName:e?.collectionName??this._defaultCtx?.collectionName??t.collectionName,config:e?.config??this._defaultCtx?.config,session:e?.session??this._defaultCtx?.session??t.session,withDeleted:e?.withDeleted,onlyDeleted:e?.onlyDeleted,hardDelete:e?.hardDelete};return Object.values(n).some(e=>void 0!==e)?n:void 0}async runWithModelContext(e,t){if(m.AmbitenContext.hasActiveContext())return t();const n=this.mergeCtx(e);return m.AmbitenContext.run({tenantId:n?.tenantId,dbName:n?.dbName,collectionName:n?.collectionName??this._collectionName,session:n?.session},t)}isGCEnabled(){return!0===this._modelGCConfig?.enableGC}resolveSchemaGCConfig(){return this._schema.getGCConfig?.()}async getCollection(e){if(this._collectionOverride)return this._collectionOverride;this.ensureConfigured();const t=await this.resolveDb(e),n=this.resolveCollectionName(e);return(0,p.debugLog)("Resolved collection",{collectionName:n,dbName:t.databaseName,tenantId:this.mergeCtx(e)?.tenantId}),t.collection(n)}getResolvedTenant(e){const t=c.MultiTenantManager.getTenant(e);if(!t)throw new Error(`Tenant "${e}" is not registered.`);return{...t}}async resolveDb(e){const t=this.mergeCtx(e);if(t?.db)return t.db;if(t?.tenantId){const e=this.getResolvedTenant(t.tenantId),n=await c.MultiTenantManager.getClient(t.tenantId);if(!n)throw new Error(`MongoClient for tenant "${t.tenantId}" is not available.`);const i=t.dbName??e.dbName;if(!i)throw new Error(`No database name configured for tenant "${t.tenantId}".`);return n.db(i)}const n=await this._provider.db(t);if(!n||"function"!=typeof n.collection)throw new Error(`AmbitenModel: provider.db() did not return a valid Db instance for collection "${this._collectionName}".`);return n}resolveCollectionName(e){const t=this.mergeCtx(e),n=t?.collectionName??this._collectionName;if(!n||"string"!=typeof n||!n.trim())throw new Error("AmbitenModel: collectionName is not configured.");return n.trim()}resolveSession(e){return this.mergeCtx(e)?.session}resolveSessionStrict(e,t){return t??e?.session??m.AmbitenContext.getSession()}on(e,t){this.eventEmitter.on(e,t)}once(e,t){this.eventEmitter.once(e,t)}off(e,t){this.eventEmitter.off(e,t)}removeListener(e,t){this.eventEmitter.removeListener(e,t)}ensureConfigured(){if(!this._collectionName||"string"!=typeof this._collectionName)throw new Error("AmbitenModel: collectionName is not configured.");if(!this._provider||"function"!=typeof this._provider.db)throw new Error("AmbitenModel: provider is not configured. Provide a valid DbProvider with a db(ctx) method.")}async init(){if(!this._initialized)try{this.ensureConfigured(),this._schema||(this._schema=new r.AmbitenSchema({})),await this.getCollection(),this.isGCEnabled()&&this._modelGCConfig&&await this.ensureGCIndex(this._modelGCConfig),this._initialized=!0}catch(e){throw(0,u.createAmbitenError)(u.ErrorType.INITIALIZATION_ERROR,`Failed to initialize AmbitenModel: ${e?.message??String(e)}`,{details:{operation:"init",TypeError:u.ErrorType.INITIALIZATION_ERROR}})}}bind(e){const t=Object.create(this);return t._defaultCtx={...this._defaultCtx,...e},t}async registerModel(e){const{ctx:t,collectionName:n,schema:i,collection:o}=e;if(!n)throw new Error("Collection name is required.");this._collectionName=n,this._collectionOverride=o,this._schema=i??new r.AmbitenSchema({}),t&&(this._defaultCtx={...this._defaultCtx,...t}),this._initialized=!1,this.ensureConfigured(),await this.init()}async ensureGCIndex(e){if(!e.enableGC||!e.ttl)return;const t=await this.getCollection(),n=e.field??e.updatedAtField??e.createdAtField??"updatedAt";await t.createIndex({[n]:1},{expireAfterSeconds:e.ttl,name:e.indexName??`${this._collectionName}_${n}_ttl`,background:!0})}get schema(){return this._schema}getSchema(){return this.schema}validate(e){this._schema&&this._schema.validate(e)}async validateAsync(e){return this._schema&&await this._schema.validateAsync(e),e}initMiddleware(){this._schema&&(this._schema.pre("create",async e=>{const t=e.doc;if(!t)return;const n=this._schema.getRelationships()??[];for(const{ref:e,localField:i}of n){const n=(await this.getCollection()).db?.collection(e),o={[i]:t._id};await(n?.updateMany(o,{$set:{[i]:t._id}}))}}),this._schema.post("create",async e=>{const t=e.result??e.doc;if(!t)return;const n=this._schema.getRelationships()??[];for(const{ref:e,localField:i}of n){const n=(await this.getCollection()).db?.collection(e),o={[i]:t._id};await(n?.updateOne(o,{$set:{[i]:t._id}}))}await f.publish("DB_CHANGE",{dbChange:{action:"create",doc:t}})}),this._schema.post("updateOne",async e=>{const t=e.filter,n=e.update;if(!t||!n)return;const i=this._schema.getRelationships()??[];for(const{ref:e,localField:t}of i){const i=(await this.getCollection()).db?.collection(e),o={[t]:n.$set?._id};await(i?.updateOne(o,{$set:{[t]:n.$set?._id}}))}await f.publish("DB_CHANGE",{dbChange:{action:"updateOne",filter:t,update:n}})}),this._schema.pre("deleteOne",async e=>{const t=e.doc??e.result;if(!t)return;const n=this._schema.getRelationships()??[];for(const{ref:e,localField:i}of n){const n=(await this.getCollection()).db?.collection(e),o={[i]:t._id};await(n?.deleteOne(o))}}),this._schema.pre("aggregate",async e=>{const t=e.pipeline;if(!t)return;const n=this._schema.getRelationships()??[];for(const{ref:e,localField:i}of n)t.unshift({$lookup:{from:e,localField:i,foreignField:"_id",as:e}})}),this._schema.post("aggregate",async e=>{const t=e.result;if(!t)return;const n=this._schema.getRelationships()??[];for(const e of t)for(const{ref:t}of n)delete e[t];await f.publish("DB_CHANGE",{dbChange:{action:"aggregate",result:t}})}))}async create(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Document must be a valid object.");return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"create",collectionName:this.resolveCollectionName(t),documentCount:1},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a=this.buildMiddlewareContext("create",t,{doc:e});a.collectionName=a.collectionName??n,await this.runBeforeMiddlewares("create",a);const r=a.doc??e;a.doc=r,this.validate(r),await this.schema.executePre("create",this.buildHookPayload("create",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,doc:r,meta:a.meta}));const s=await o.insertOne(r,i?{session:i}:void 0),l={...r,_id:s.insertedId};await this.schema.executePost("create",this.buildHookPayload("create",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,doc:l,result:l,meta:a.meta}));const c=this.toModelResult(l);a.result=c,await this.runAfterMiddlewares("create",a);const d=a.result??c;return await this.invalidateCachePatterns("create",a),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentInserted:{action:"create",collectionName:a.collectionName,doc:d,meta:a.meta}}),d}))}async find(e={},t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"find",collectionName:this.resolveCollectionName(t),filter:e},async()=>{const i=this.resolveCollectionName(t),o=this.resolveSession(t),a=await this.getCollection(t),r=this.buildMiddlewareContext("find",t,{filter:e});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("find",r);const s=r.filter??e;r.filter=s;const l=n?.cache?this.resolveCache(n):null;await this.schema.executePre("find",this.buildHookPayload("create",t,{collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,meta:r.meta}));let c=null;if(l){c=this.buildCacheKey("find",{collectionName:r.collectionName,filter:s,tenantId:r.tenantId,dbName:r.dbName});const e=await l.get(c,{ttlSeconds:"object"==typeof n?.cache?n.cache.ttl:void 0,tenantId:r.tenantId,namespace:r.collectionName});if(e)return r.result=e,await this.schema.executePost("find",this.buildHookPayload("find",t,{collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,result:e,meta:{...r.meta??{},cacheHit:!0}})),await this.runAfterMiddlewares("find",r),r.result??e}const d=a.find(s,o?{session:o}:void 0),u=await d.toArray(),m=this.toModelResults(u);await this.schema.executePost("find",this.buildHookPayload("find",t,{collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,result:m,meta:r.meta})),r.result=m,await this.runAfterMiddlewares("find",r);const h=r.result??m;return l&&c&&await l.set(c,h,{ttlSeconds:"object"==typeof n?.cache?n.cache.ttl:void 0,tenantId:r.tenantId,namespace:r.collectionName}),h}))}async findOne(e,t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"findOne",collectionName:this.resolveCollectionName(t),filter:e},async()=>{const i=this.resolveCollectionName(t),o=this.resolveSession(t),a=await this.getCollection(t),r=this.buildMiddlewareContext("findOne",t,{filter:e});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("findOne",r);const s=r.filter??e;r.filter=s;const l=n?.cache?this.resolveCache(n):null;let c=null;if(await this.schema.executePre("findOne",this.buildHookPayload("findOne",t,{collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,meta:r.meta})),l){c=this.buildCacheKey("findOne",{collectionName:r.collectionName,filter:s,tenantId:r.tenantId,dbName:r.dbName});const e=await l.get(c,{ttlSeconds:"object"==typeof n?.cache?n.cache.ttl:void 0,tenantId:r.tenantId,namespace:r.collectionName});if(null!=e)return r.result=e,await this.schema.executePost("findOne",this.buildHookPayload("findOne",t,{collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,result:e,meta:{...r.meta??{},cacheHit:!0}})),await this.runAfterMiddlewares("findOne",r),r.result??e}const d=await a.findOne(s,o?{session:o}:void 0),u=d?this.toModelResult(d):null;await this.schema.executePost("findOne",{operation:"findOne",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,result:u,meta:r.meta}),r.result=u,await this.runAfterMiddlewares("findOne",r);const m=r.result??u;return l&&c&&null!==m&&await l.set(c,m,{ttlSeconds:"object"==typeof n?.cache?n.cache.ttl:void 0,tenantId:r.tenantId,namespace:r.collectionName}),m}))}async updateOne(e,t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");if(!t||"object"!=typeof t)throw new Error("Update must be a valid object.");return this.runWithModelContext(n,async()=>(0,h.measureQuery)({operation:"updateOne",collectionName:this.resolveCollectionName(n),filter:e,update:t},async()=>{const i=this.resolveCollectionName(n),o=this.resolveSession(n),a=await this.getCollection(n),r=this.buildMiddlewareContext("updateOne",n,{filter:e,update:t});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("updateOne",r);const s=r.filter??e,l=r.update??t;r.filter=s,r.update=l,await this.schema.executePre("updateOne",{operation:"updateOne",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,update:l,meta:r.meta});const c=await a.updateOne(s,l,o?{session:o}:void 0),d={acknowledged:c?.acknowledged,matchedCount:c?.matchedCount,modifiedCount:c?.modifiedCount,upsertedCount:c?.upsertedCount,upsertedId:c?.upsertedId};await this.schema.executePost("updateOne",{operation:"updateOne",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,update:l,result:d,meta:r.meta}),r.result=d,await this.runAfterMiddlewares("updateOne",r),await this.invalidateCachePatterns("updateOne",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentUpdated:{action:"updateOne",collectionName:r.collectionName,filter:s,update:l,result:d,meta:r.meta}})}))}async bulkInsert(e,t){if(await this.init(),Array.isArray(e)&&0!==e.length)return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"bulkInsert",collectionName:this.resolveCollectionName(t),documentCount:e.length},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a=this.buildMiddlewareContext("bulkInsert",t,{docs:e});a.collectionName=a.collectionName??n,await this.runBeforeMiddlewares("bulkInsert",a);const r=a.docs??e;if(a.docs=r,!Array.isArray(r)||0===r.length)return a.result=[],void await this.runAfterMiddlewares("bulkInsert",a);for(const e of r){if(!e||"object"!=typeof e)throw new Error("Each document must be a valid object.");this.validate(e)}const s=this.buildOperationMeta(a.meta,{bulkWrite:!0});await this.schema.executePre("bulkInsert",this.buildHookPayload("bulkInsert",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,docs:r,meta:s}));const l=await o.insertMany(r,{ordered:!1,...i?{session:i}:{}}),c=r.map((e,t)=>({...e,_id:l.insertedIds[t]}));await this.schema.executePost("bulkInsert",this.buildHookPayload("bulkInsert",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,docs:c,result:c,meta:s})),a.result=this.toModelResults(c),await this.runAfterMiddlewares("bulkInsert",a),await this.invalidateCachePatterns("bulkInsert",a),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentInserted:{action:"bulkInsert",collectionName:a.collectionName,docs:a.result,meta:s}})}))}async bulkUpdate(e,t){if(await this.init(),!Array.isArray(e))throw new Error("Updates must be a valid array.");if(0!==e.length)return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"bulkUpdate",collectionName:this.resolveCollectionName(t),documentCount:e.length},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a=this.buildMiddlewareContext("bulkUpdate",t,{bulkUpdates:e});a.collectionName=a.collectionName??n,await this.runBeforeMiddlewares("bulkUpdate",a);const r=a.bulkUpdates??e;a.bulkUpdates=r;const s=this.buildOperationMeta(a.meta,{bulkWrite:!0});if(a.meta=s,!Array.isArray(r)||0===r.length)return a.result={acknowledged:!0,matchedCount:0,modifiedCount:0,upsertedCount:0,insertedCount:0,deletedCount:0},void await this.runAfterMiddlewares("bulkUpdate",a);for(const e of r){if(!e||"object"!=typeof e)throw new Error("Each bulk update entry must be a valid object.");if(!e.filter||"object"!=typeof e.filter)throw new Error("Each bulk update filter must be a valid object.");if(!e.update||"object"!=typeof e.update)throw new Error("Each bulk update document must be a valid object.")}const l=r.map(({filter:e,update:t})=>({updateOne:{filter:e,update:{$set:t}}}));await this.schema.executePre("bulkUpdate",this.buildHookPayload("bulkUpdate",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,bulkUpdates:r,meta:s}));const c=await o.bulkWrite(l,{ordered:!1,...i?{session:i}:{}}),d={acknowledged:c?.isOk?.()??!0,matchedCount:c?.matchedCount,modifiedCount:c?.modifiedCount,upsertedCount:c?.upsertedCount,insertedCount:c?.insertedCount,deletedCount:c?.deletedCount};await this.schema.executePost("bulkUpdate",this.buildHookPayload("bulkUpdate",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,bulkUpdates:r,result:d,meta:s})),a.result=d,await this.runAfterMiddlewares("bulkUpdate",a),await this.invalidateCachePatterns("bulkUpdate",a),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentUpdated:{action:"bulkUpdate",collectionName:a.collectionName,bulkUpdates:r,result:d,meta:s}})}))}async deleteOne(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"deleteOne",collectionName:this.resolveCollectionName(t),filter:e},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a=this.buildMiddlewareContext("deleteOne",t,{filter:e});a.collectionName=a.collectionName??n,await this.runBeforeMiddlewares("deleteOne",a);const r=a.filter??e;a.filter=r;const s=await o.findOne(r,i?{session:i}:void 0);if(!s)return a.result=null,void await this.runAfterMiddlewares("deleteOne",a);const l=this.toModelResult(s);a.result=l;const c=this.buildOperationMeta(a.meta);if(a.meta=c,!0===c.softDelete){const e=a.update;if(!e)throw new Error("Soft delete is enabled but no soft delete update payload was provided.");await this.schema.executePre("updateOne",this.buildHookPayload("deleteOne",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,filter:r,update:e,result:l,meta:c})),await o.updateOne(r,e,i?{session:i}:void 0),await this.schema.executePost("updateOne",this.buildHookPayload("deleteOne",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,filter:r,update:e,result:l,meta:c}))}else await this.schema.triggerMiddleware("pre","deleteOne",{operation:"deleteOne",collectionName:a.collectionName,...l}),await this.schema.executePre("deleteOne",this.buildHookPayload("deleteOne",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,doc:l,result:l,meta:c})),await o.deleteOne(r,i?{session:i}:void 0),await this.schema.triggerMiddleware("post","deleteOne",{operation:"deleteOne",collectionName:a.collectionName,...l}),await this.schema.executePost("deleteOne",this.buildHookPayload("deleteOne",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,doc:l,result:l,meta:c}));await this.runAfterMiddlewares("deleteOne",a),await this.invalidateCachePatterns("deleteOne",a),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentDeleted:{action:c.softDelete?"softDelete":"deleteOne",collectionName:a.collectionName,filter:r,meta:a.meta}})}))}async deleteMany(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"deleteMany",collectionName:this.resolveCollectionName(t),filter:e},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a=this.buildMiddlewareContext("deleteMany",t,{filter:e});a.collectionName=a.collectionName??n,await this.runBeforeMiddlewares("deleteMany",a);const r=a.filter??e;a.filter=r;const s=this.buildOperationMeta(a.meta);a.meta=s;const l=await o.find(r,i?{session:i}:void 0).toArray();if(0===l.length)return a.result={deletedCount:0,docs:[]},void await this.runAfterMiddlewares("deleteMany",a);const c=this.toModelResults(l);if(!0===s.softDelete){const e=a.update;if(!e)throw new Error("Soft delete is enabled but no soft delete update payload was provided.");const n=this.buildOperationMeta(s,{softDelete:!0});await this.schema.executePre("updateMany",this.buildHookPayload("deleteMany",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,filter:r,update:e,docs:l,result:c,meta:n}));const d={deletedCount:(await o.updateMany(r,e,i?{session:i}:void 0)).modifiedCount,docs:c,softDeleted:!0};await this.schema.executePost("updateMany",this.buildHookPayload("deleteMany",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,filter:r,update:e,docs:l,result:d,meta:n})),a.result=d}else{await this.schema.triggerMiddleware("pre","deleteMany",{operation:"deleteMany",collectionName:a.collectionName,docs:l}),await this.schema.executePre("deleteMany",this.buildHookPayload("deleteMany",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,docs:l,result:c,meta:s}));const e=await o.deleteMany(r,i?{session:i}:void 0),n={deletedCount:e?.deletedCount??0,docs:c};await this.schema.triggerMiddleware("post","deleteMany",{operation:"deleteMany",collectionName:a.collectionName,docs:l}),await this.schema.executePost("deleteMany",this.buildHookPayload("deleteMany",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,docs:l,result:n,meta:s})),a.result=n}await this.runAfterMiddlewares("deleteMany",a),await this.invalidateCachePatterns("deleteMany",a),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentDeleted:{action:s.softDelete?"softDeleteMany":"deleteMany",collectionName:a.collectionName,filter:r,result:a.result,meta:a.meta}})}))}async populateOne(e,t,n){if(await this.init(),!e||"object"!=typeof e)return null;const i=e[t];if(null==i)return e;const o=await n.findOne({_id:i});return{...e,[t]:o}}async populateMany(e,t,n){if(await this.init(),!e||"object"!=typeof e)return null;const i=e[t];if(!Array.isArray(i)||0===i.length)return e;const o=await n.find({_id:{$in:i}});return{...e,[t]:o}}async createWithTransaction(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Document must be a valid object.");return this.runWithModelContext(t,async()=>this.withTransaction(async()=>(0,h.measureQuery)({operation:"create",collectionName:this.resolveCollectionName(t),documentCount:1},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a=this.buildMiddlewareContext("create",t,{doc:e,meta:{transactional:!0}});a.collectionName=a.collectionName??n,await this.runBeforeMiddlewares("create",a);const r=a.doc??e;a.doc=r;const s=this.buildOperationMeta(a.meta,{transactional:!0});this.validate(r),await this.schema.executePre("create",this.buildHookPayload("create",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,doc:r,meta:s}));const l=await o.insertOne(r,i?{session:i}:void 0),c={...r,_id:l.insertedId};await this.schema.executePost("create",this.buildHookPayload("create",t,{operation:"create",collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,doc:c,result:c,meta:s}));const d=this.toModelResult(c);a.result=d,await this.runAfterMiddlewares("create",a),await this.invalidateCachePatterns("create",a);const m=a.result??d;return await f.publish(`${u.DB_CHANGE_EVENT}`,{documentInserted:{action:"create",collectionName:a.collectionName,doc:m,meta:s}}),m}),t))}async bulkWriteWithTransaction(e,t={},n){if(await this.init(),!Array.isArray(e))throw new Error("Operations must be a valid array.");if(0===e.length)throw new Error("Operations array must not be empty.");return this.runWithModelContext(n,async()=>this.withTransaction(async()=>(0,h.measureQuery)({operation:"bulkWrite",collectionName:this.resolveCollectionName(n),documentCount:e.length,extra:{bulkWrite:!0}},async()=>{const i=this.resolveCollectionName(n),o=this.resolveSession(n),a=await this.getCollection(n),r=this.buildMiddlewareContext("bulkUpdate",n,{bulkOperations:e,meta:{transactional:!0,bulkWrite:!0}});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("bulkUpdate",r);const s=r.bulkOperations??e;r.bulkOperations=s;const l=this.buildOperationMeta(r.meta,{transactional:!0,bulkWrite:!0});r.meta=l,await this.schema.executePre("bulkUpdate",this.buildHookPayload("bulkUpdate",n,{collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,bulkOperations:s,meta:l}));const c=await a.bulkWrite(s,{...t,...o?{session:o}:{}}),d={acknowledged:c?.isOk?.()??!0,matchedCount:c?.matchedCount,modifiedCount:c?.modifiedCount,upsertedCount:c?.upsertedCount,insertedCount:c?.insertedCount,deletedCount:c?.deletedCount};return await this.schema.executePost("bulkUpdate",this.buildHookPayload("bulkUpdate",n,{collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,bulkOperations:s,result:d,meta:l})),r.result=d,await this.runAfterMiddlewares("bulkUpdate",r),await this.invalidateCachePatterns("bulkWrite",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{bulkWrite:{action:"bulkWrite",collectionName:r.collectionName,result:d,meta:l}}),c}),n))}async deleteWithTransaction(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");return this.runWithModelContext(t,async()=>this.withTransaction(async()=>(0,h.measureQuery)({operation:"deleteOne",collectionName:this.resolveCollectionName(t),filter:e},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a={transactional:!0},r=this.buildMiddlewareContext("deleteOne",t,{filter:e,meta:a});r.collectionName=r.collectionName??n,await this.runBeforeMiddlewares("deleteOne",r);const s=r.filter??e;r.filter=s;const l=await o.findOne(s,i?{session:i}:void 0);if(!l)return r.result=null,await this.runAfterMiddlewares("deleteOne",r),!1;const c=this.toModelResult(l);r.result=c,await this.schema.triggerMiddleware("pre","deleteOne",{operation:"deleteOne",collectionName:r.collectionName,...c}),await this.schema.executePre("deleteOne",{operation:"deleteOne",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:i,doc:l,result:c,meta:a});const d=await o.deleteOne(s,i?{session:i}:void 0);return await this.schema.triggerMiddleware("post","deleteOne",{operation:"deleteOne",collectionName:r.collectionName,...c}),await this.schema.executePost("deleteOne",{operation:"deleteOne",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:i,doc:l,result:c,meta:a}),await this.runAfterMiddlewares("deleteOne",r),await this.invalidateCachePatterns("deleteOne",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentDeleted:{action:"deleteOne",collectionName:r.collectionName,filter:s,meta:a}}),1===d.deletedCount}),t))}async updateWithTransaction(e,t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");if(!t||"object"!=typeof t)throw new Error("Update must be a valid object.");return this.runWithModelContext(n,async()=>this.withTransaction(async()=>(0,h.measureQuery)({operation:"updateOne",collectionName:this.resolveCollectionName(n),filter:e,update:t},async()=>{const i=this.resolveCollectionName(n),o=this.resolveSession(n),a=await this.getCollection(n),r={transactional:!0},s=this.buildMiddlewareContext("updateOne",n,{filter:e,update:t,meta:r});s.collectionName=s.collectionName??i,await this.runBeforeMiddlewares("updateOne",s);const l=s.filter??e,c=s.update??t;s.filter=l,s.update=c;const d=await a.findOne(l,o?{session:o}:void 0);if(!d)return s.result=null,await this.runAfterMiddlewares("updateOne",s),null;const m={...d,...c.$set??{}};this.validate(m),await this.schema.executePre("updateOne",{operation:"updateOne",collectionName:s.collectionName,tenantId:s.tenantId,dbName:s.dbName,session:o,filter:l,update:c,meta:r}),await a.updateOne(l,c,o?{session:o}:void 0);const h=await a.findOne(l,o?{session:o}:void 0),p=h?this.toModelResult(h):null;return await this.schema.executePost("updateOne",{operation:"updateOne",collectionName:s.collectionName,tenantId:s.tenantId,dbName:s.dbName,session:o,filter:l,update:c,result:p,meta:r}),s.result=p,await this.runAfterMiddlewares("updateOne",s),await this.invalidateCachePatterns("updateOne",s),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentUpdated:{action:"updateOne",collectionName:s.collectionName,filter:l,update:c,result:p,meta:r}}),s.result??p}),n))}async findOneAndUpdate(e,t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");if(!t||"object"!=typeof t)throw new Error("Update must be a valid object.");return this.runWithModelContext(n,async()=>(0,h.measureQuery)({operation:"findOneAndUpdate",collectionName:this.resolveCollectionName(n),filter:e,update:t},async()=>{const i=this.resolveCollectionName(n),o=this.resolveSession(n),a=await this.getCollection(n),r=this.buildMiddlewareContext("findOneAndUpdate",n,{filter:e,update:t});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("findOneAndUpdate",r);const s=r.filter??e,l=r.update??t;r.filter=s,r.update=l,await this.schema.executePre("updateOne",{operation:"findOneAndUpdate",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,update:l,meta:r.meta});const c=await a.findOneAndUpdate(s,l,{returnDocument:"after",...o?{session:o}:{}}),d=c&&"object"==typeof c&&"value"in c?c.value:c,m=d?this.toModelResult(d):null;return await this.schema.executePost("updateOne",{operation:"findOneAndUpdate",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,filter:s,update:l,result:m,meta:r.meta}),r.result=m,await this.runAfterMiddlewares("findOneAndUpdate",r),await this.invalidateCachePatterns("findOneAndUpdate",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentUpdated:{action:"findOneAndUpdate",collectionName:r.collectionName,filter:s,update:l,result:m,meta:r.meta}}),r.result??m}))}async findOneAndDelete(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"findOneAndDelete",collectionName:this.resolveCollectionName(t),filter:e},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a=this.buildMiddlewareContext("findOneAndDelete",t,{filter:e});a.collectionName=a.collectionName??n,await this.runBeforeMiddlewares("findOneAndDelete",a);const r=a.filter??e;a.filter=r;const s=this.buildOperationMeta(a.meta);a.meta=s;const l=await o.findOne(r,i?{session:i}:void 0);if(!l)return a.result=null,await this.runAfterMiddlewares("findOneAndDelete",a),null;const c=this.toModelResult(l);if(a.result=c,!0===s.softDelete){const e=a.update??this.buildSoftDeleteUpdate();a.update=e;const n=this.buildOperationMeta(s,{softDelete:!0});return await this.schema.executePre("updateOne",this.buildHookPayload("findOneAndDelete",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,filter:r,update:e,result:c,meta:n})),await o.updateOne(r,e,i?{session:i}:void 0),await this.schema.executePost("updateOne",this.buildHookPayload("findOneAndDelete",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,filter:r,update:e,result:c,meta:n})),await this.runAfterMiddlewares("findOneAndDelete",a),await this.invalidateCachePatterns("findOneAndDelete",a),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentDeleted:{action:"softDeleteOne",collectionName:a.collectionName,filter:r,meta:n}}),a.result??c}await this.schema.triggerMiddleware("pre","deleteOne",{operation:"findOneAndDelete",collectionName:a.collectionName,...c}),await this.schema.executePre("deleteOne",this.buildHookPayload("findOneAndDelete",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,doc:l,result:c,meta:s}));const d=i?{session:i}:{},m=await o.findOneAndDelete(r,d),h=m&&"object"==typeof m&&"value"in m?m.value:m,p=h?this.toModelResult(h):c;return await this.schema.triggerMiddleware("post","deleteOne",{operation:"findOneAndDelete",collectionName:a.collectionName,...p??{}}),await this.schema.executePost("deleteOne",this.buildHookPayload("findOneAndDelete",t,{collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,doc:l,result:p,meta:s})),a.result=p,await this.runAfterMiddlewares("findOneAndDelete",a),await this.invalidateCachePatterns("findOneAndDelete",a),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentDeleted:{action:"findOneAndDelete",collectionName:a.collectionName,filter:r,result:p,meta:s}}),a.result??p}))}async findOneAndReplace(e,t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");if(!t||"object"!=typeof t)throw new Error("Replacement document must be a valid object.");return this.runWithModelContext(n,async()=>(0,h.measureQuery)({operation:"findOneAndReplace",collectionName:this.resolveCollectionName(n),filter:e},async()=>{const i=this.resolveCollectionName(n),o=this.resolveSession(n),a=await this.getCollection(n),r=this.buildMiddlewareContext("findOneAndReplace",n,{filter:e,doc:t});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("findOneAndReplace",r);const s=r.filter??e,l=r.doc??t;r.filter=s,r.doc=l,this.validate(l),await this.schema.executePre("updateOne",{operation:"findOneAndReplace",collectionName:r.collectionName,filter:s,doc:l});const c=await a.findOneAndReplace(s,l,{returnDocument:"after",...o?{session:o}:{}}),d=c&&"object"==typeof c&&"value"in c?c.value:c,m=d?this.toModelResult(d):null;return await this.schema.executePost("updateOne",{operation:"findOneAndReplace",collectionName:r.collectionName,filter:s,doc:l,result:d}),r.result=m,await this.runAfterMiddlewares("findOneAndReplace",r),await this.invalidateCachePatterns("findOneAndReplace",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentUpdated:{action:"findOneAndReplace",filter:s,replacement:l}}),r.result??m}))}async findOneAndUpsert(e,t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");if(!t||"object"!=typeof t)throw new Error("Update must be a valid object.");return this.runWithModelContext(n,async()=>(0,h.measureQuery)({operation:"findOneAndUpsert",collectionName:this.resolveCollectionName(n),filter:e,update:t},async()=>{const i=this.resolveCollectionName(n),o=this.resolveSession(n),a=await this.getCollection(n),r=this.buildMiddlewareContext("findOneAndUpsert",n,{filter:e,update:t});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("findOneAndUpsert",r);const s=r.filter??e,l=r.update??t;r.filter=s,r.update=l,await this.schema.executePre("updateOne",{operation:"findOneAndUpsert",collectionName:r.collectionName,filter:s,update:l});const c=await a.findOneAndUpdate(s,l,{upsert:!0,returnDocument:"after",...o?{session:o}:{}}),d=c&&"object"==typeof c&&"value"in c?c.value:c,m=d?this.toModelResult(d):null;return await this.schema.executePost("updateOne",{operation:"findOneAndUpsert",collectionName:r.collectionName,filter:s,update:l,result:d}),r.result=m,await this.runAfterMiddlewares("findOneAndUpsert",r),await this.invalidateCachePatterns("findOneAndUpsert",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentUpdated:{action:"findOneAndUpsert",filter:s,update:l}}),r.result??m}))}async findOneAndUpsertWithTransaction(e,t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");if(!t||"object"!=typeof t)throw new Error("Update must be a valid object.");return this.runWithModelContext(n,async()=>this.withTransaction(async()=>{const i=this.resolveCollectionName(n),o=await this.getCollection(n),a=this.resolveSession(n),r=this.buildMiddlewareContext("findOneAndUpsert",n,{filter:e,update:t,meta:{transactional:!0}});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("findOneAndUpsert",r);const s=r.filter??e,l=r.update??t;r.filter=s,r.update=l,await this.schema.executePre("updateOne",{operation:"findOneAndUpsert",collectionName:r.collectionName,filter:s,update:l,meta:{transactional:!0}});const c=await o.findOneAndUpdate(s,l,{upsert:!0,returnDocument:"after",...a?{session:a}:{}}),d=c&&"object"==typeof c&&"value"in c?c.value:c,m=d?this.toModelResult(d):null;return await this.schema.executePost("updateOne",{operation:"findOneAndUpsert",collectionName:r.collectionName,filter:s,update:l,result:d,meta:{transactional:!0}}),r.result=m,await this.runAfterMiddlewares("findOneAndUpsert",r),await this.invalidateCachePatterns("findOneAndUpsert",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentUpdated:{action:"findOneAndUpsert",filter:s,update:l,meta:{transactional:!0}}}),r.result??m},n))}async findOneAndUpsertWithTransactionSecure(e,t,n,i){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");if(!t||"object"!=typeof t)throw new Error("Update must be a valid object.");if(!n)throw new Error("User is required.");return this.runWithModelContext(i,async()=>this.withTransaction(async()=>{if("admin"!==n.role)throw new Error("Unauthorized");const o={transactional:!0,secure:!0,userId:n.id,userRole:n.role},a=this.resolveCollectionName(i),r=await this.getCollection(i),s=this.resolveSession(i),l=this.buildMiddlewareContext("findOneAndUpsert",i,{filter:e,update:t,meta:o});l.collectionName=l.collectionName??a,await this.runBeforeMiddlewares("findOneAndUpsert",l);const c=l.filter??e,d=l.update??t;l.filter=c,l.update=d,await this.schema.executePre("updateOne",{operation:"findOneAndUpsert",collectionName:l.collectionName,filter:c,update:d,meta:o});const m=await r.findOneAndUpdate(c,d,{upsert:!0,returnDocument:"after",...s?{session:s}:{}}),h=m&&"object"==typeof m&&"value"in m?m.value:m,p=h?this.toModelResult(h):null;return await this.schema.executePost("updateOne",{operation:"findOneAndUpsert",collectionName:l.collectionName,filter:c,update:d,result:h,meta:o}),l.result=p,await this.runAfterMiddlewares("findOneAndUpsert",l),await this.invalidateCachePatterns("findOneAndUpsert",l),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentUpdated:{action:"findOneAndUpsert",filter:c,update:d,meta:o}}),l.result??p},i))}async deleteSecure(e,t,n){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");if(!t)throw new Error("User is required.");return this.runWithModelContext(n,async()=>(0,h.measureQuery)({operation:"deleteOne",collectionName:this.resolveCollectionName(n),filter:e},async()=>{if("admin"!==t.role)throw new Error("Unauthorized");const i={secure:!0,userId:t.id,userRole:t.role},o=this.resolveCollectionName(n),a=await this.getCollection(n),r=this.resolveSession(n),s=this.buildMiddlewareContext("deleteOne",n,{filter:e,meta:i});s.collectionName=s.collectionName??o,await this.runBeforeMiddlewares("deleteOne",s);const l=s.filter??e;s.filter=l;const c=await a.findOne(l,r?{session:r}:void 0);if(!c)return s.result=null,void await this.runAfterMiddlewares("deleteOne",s);const d=this.toModelResult(c);s.result=d,await this.schema.executePre("deleteOne",{operation:"deleteOne",collectionName:s.collectionName,...c,meta:i}),await a.deleteOne(l,r?{session:r}:void 0),await this.schema.executePost("deleteOne",{operation:"deleteOne",collectionName:s.collectionName,...c,meta:i}),await this.runAfterMiddlewares("deleteOne",s),await this.invalidateCachePatterns("deleteOne",s),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentDeleted:{action:"deleteOne",filter:l,meta:i}})}))}async aggregate(e,t={},n,i,o){if(await this.init(),!Array.isArray(e))throw new Error("Pipeline must be a valid array.");return this.runWithModelContext(i,async()=>(0,h.measureQuery)({operation:"aggregate",collectionName:this.resolveCollectionName(i),pipeline:e},async()=>{const a=this.resolveCollectionName(i),r=await this.getCollection(i),s=this.resolveSessionStrict(i,n),l=this.buildMiddlewareContext("aggregate",i,{pipeline:e});l.collectionName=l.collectionName??a,await this.runBeforeMiddlewares("aggregate",l);const c=l.pipeline??e;l.pipeline=c;const d=o?.cache?this.resolveCache(o):null;await this.schema.executePre("aggregate",{operation:"aggregate",collectionName:l.collectionName,tenantId:l.tenantId,dbName:l.dbName,session:s,pipeline:c,meta:l.meta});let m=null;if(d){m=this.buildCacheKey("aggregate",{collectionName:l.collectionName,pipeline:c,options:t,tenantId:l.tenantId,dbName:l.dbName});const e=await d.get(m,{ttlSeconds:"object"==typeof o?.cache?o.cache.ttl:void 0,tenantId:l.tenantId,namespace:l.collectionName});if(e)return l.result=e,await this.runAfterMiddlewares("aggregate",l),l.result??e}const h=r.aggregate(c,{...t,...s?{session:s}:{}}),p=await h.toArray();await this.schema.executePost("aggregate",{operation:"aggregate",collectionName:l.collectionName,tenantId:l.tenantId,dbName:l.dbName,session:s,pipeline:c,result:p,meta:l.meta}),l.result=p,await this.runAfterMiddlewares("aggregate",l);const g=l.result??p;return d&&m&&await d.set(m,g,{ttlSeconds:"object"==typeof o?.cache?o.cache.ttl:void 0,tenantId:l.tenantId,namespace:l.collectionName}),await f.publish(`${u.DB_CHANGE_EVENT}`,{dbChange:{action:"aggregate",pipeline:c}}),g}))}async aggregateWithTransaction(e,t={},n){if(await this.init(),!Array.isArray(e))throw new Error("Pipeline must be a valid array.");return this.runWithModelContext(n,async()=>this.withTransaction(async()=>(0,h.measureQuery)({operation:"aggregate",collectionName:this.resolveCollectionName(n),pipeline:e},async()=>{const i=this.resolveCollectionName(n),o=await this.getCollection(n),a=this.resolveSession(n),r=this.buildMiddlewareContext("aggregate",n,{pipeline:e,meta:{transactional:!0}});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("aggregate",r);const s=r.pipeline??e;r.pipeline=s,await this.schema.executePre("aggregate",{operation:"aggregate",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:a,pipeline:s,meta:{...r.meta??{},transactional:!0}});const l=o.aggregate(s,{...t,...a?{session:a}:{}}),c=await l.toArray();await this.schema.executePost("aggregate",{operation:"aggregate",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:a,pipeline:s,result:c,meta:{...r.meta??{},transactional:!0}}),r.result=c,await this.runAfterMiddlewares("aggregate",r);const d=r.result??c;return await f.publish(`${u.DB_CHANGE_EVENT}`,{dbChange:{action:"aggregate",pipeline:s,meta:{transactional:!0}}}),d}),n))}async withTransaction(e,t){const n=this.mergeCtx(t)??{},i=n.collectionName??this._collectionName,o=n.session,a={tenantId:n.tenantId,dbName:n.dbName,collectionName:i};if(o)return m.AmbitenContext.run({...a,session:o},async()=>e(o));if(this._provider?.startSession){const t=await this.getSession(n);return await m.AmbitenContext.run({...a,session:t},async()=>(0,m.runManualTransaction)(t,e))}return m.AmbitenContext.run(a,async()=>m.AmbitenContext.withTransaction(e))}async runInTransaction(e,t){if(await this.init(),"function"!=typeof e)throw new Error("Operation must be a valid function.");return this.runWithModelContext(t,async()=>this.withTransaction(async t=>e(t),t))}async getSession(e){if(!this._provider?.startSession)throw new Error("Transaction support is not available. Provider does not implement startSession().");return this._provider.startSession(this.mergeCtx(e))}async streamAggregation(e,t={},n){if(await this.init(),!Array.isArray(e))throw new Error("Pipeline must be a valid array.");return this.runWithModelContext(n,async()=>(0,h.measureQuery)({operation:"aggregate",collectionName:this.resolveCollectionName(n),pipeline:e,extra:{streaming:!0}},async()=>{const i=this.resolveCollectionName(n),o=this.resolveSession(n),a=await this.getCollection(n),r=this.buildMiddlewareContext("aggregate",n,{pipeline:e,meta:{streaming:!0}});r.collectionName=r.collectionName??i,await this.runBeforeMiddlewares("aggregate",r);const s=r.pipeline??e;r.pipeline=s;const l={...r.meta??{},streaming:!0};await this.schema.triggerMiddleware("pre","aggregate",{operation:"aggregate",collectionName:r.collectionName,pipeline:s,meta:l}),await this.schema.executePre("aggregate",{operation:"aggregate",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,pipeline:s,meta:l});const c=a.aggregate(s,{...t,...o?{session:o}:{}}).stream();return await this.schema.triggerMiddleware("post","aggregate",{operation:"aggregate",collectionName:r.collectionName,result:c,meta:l}),await this.schema.executePost("aggregate",{operation:"aggregate",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:o,pipeline:s,result:c,meta:l}),r.result=c,await this.runAfterMiddlewares("aggregate",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{dbChange:{action:"aggregateStream",collectionName:r.collectionName,pipeline:s,meta:l}}),c}))}async aggregateWithCache(e,t,n=300){if(await this.init(),!Array.isArray(e))throw new Error("Pipeline must be an array of objects.");const i=await d.redis.get(t);if(i)return console.info(`[info]: Cache hit: ${t}`),JSON.parse(i);if("string"!=typeof t)throw new Error("Cache key must be a string.");console.info(`[info]: Cache miss: ${t}`);const o=await this.getCollection(),a=await o.aggregate(e).toArray();return await d.redis.set(t,JSON.stringify(a)||""),await d.redis.expire(t,n),console.info("Cache set:",t),this.schema.triggerMiddleware("post","aggregate",{operation:"aggregate",collectionName:this.resolveCollectionName(o),result:[a]}),await f.publish("DB_CHANGE",{dbChange:{action:"aggregate",result:a}}),a||[]}async paginatedFind(e,t,n){await this.init();const i=e;n&&(i._id={$gt:new o.ObjectId(n)});const a=await this.getCollection();return(await a.find(i).limit(t).toArray()).map(({_id:e,...t})=>t)}async watchChanges(e,t){if(await this.init(),"function"!=typeof e)throw new Error("Callback must be a valid function.");return this.runWithModelContext(t,async()=>{const n=this.resolveCollectionName(t),i=(await this.getCollection(t)).watch();return i.on("change",e),await f.publish(`${u.DB_CHANGE_EVENT}`,{dbChange:{action:"watchChanges",collectionName:n}}),i})}async createIndex(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Index fields must be a valid object.");const n=Object.entries(e);if(0===n.length)throw new Error("Index fields must contain at least one entry.");for(const[,e]of n)if(1!==e&&-1!==e)throw new Error("Index direction must be either 1 or -1.");return this.runWithModelContext(t,async()=>{const n=await this.getCollection(t);await n.createIndex(e)})}async dropIndex(e){await this.init();const t=await this.getCollection();await t.dropIndex(e)}async invalidateCachePatterns(e,t){const n=t.tenantId??"default",i=t.dbName??"default",o=t.collectionName??this._collectionName,a=[...[`Ambiten:${n}:${i}:${o}:find:*`,`Ambiten:${n}:${i}:${o}:findOne:*`],`Ambiten:${n}:${i}:${o}:aggregate:*`];await Promise.all([...new Set(a)].map(e=>g.invalidatePattern(e)))}static async invalidatePattern(e){if("string"!=typeof e||0===e.trim().length)throw new Error("Pattern must be a non-empty string.");const t=e.trim();let n=0,i=0;try{do{const e=await d.redis.scan(i,{MATCH:t,COUNT:100}),o=Array.isArray(e)?Number(e[0]):0,a=Array.isArray(e)?e[1]:[];if(Array.isArray(a)&&a.length>0){const e=d.redis.multi();for(const t of a)e.del(t);const t=await e.exec();Array.isArray(t)&&(n+=t.filter(e=>{if(Array.isArray(e)){const[t,n]=e;return!t&&1===n}return 1===e}).length)}i=o}while(0!==i);return n}catch(e){const n=e instanceof Error?e.message:String(e);throw new Error(`Failed to invalidate cache pattern "${t}": ${n}`)}}getContext(){return{ctx:{}}}async invalidateModelPattern(e,t){if(await this.init(),"string"!=typeof e||0===e.trim().length)throw new Error("Pattern must be a non-empty string.");return this.runWithModelContext(t,async()=>{const n=`Ambiten:${t?.tenantId??"default"}:${t?.dbName??"default"}:${t?.collectionName??this._collectionName}:${e.trim()}`;return g.invalidatePattern(n)})}async invalidateDocumentCache(e,t){if(await this.init(),!e||"object"!=typeof e||!("_id"in e)||!e._id)throw new Error("Document must contain a valid _id.");return this.runWithModelContext(t,async()=>{const n=this.mergeCtx(t),i=`Ambiten:${n?.tenantId??"default"}:${n?.dbName??"default"}:${n?.collectionName??this._collectionName}:*${String(e._id)}*`;return g.invalidatePattern(i)})}static async getCacheStats(e){try{const t=await d.redis.info("memory"),n=await d.redis.info("keyspace"),i=Array.from(n.matchAll(/db\d+:keys=(\d+)/g)).reduce((e,t)=>e+Number(t[1]??0),0),o=t.match(/used_memory:(\d+)/),a=o?Number(o[1]):0,r=await d.redis.get("Ambiten:cache:stats:hits")??"0",s=await d.redis.get("Ambiten:cache:stats:misses")??"0",l=Number.parseInt(r,10)||0,c=Number.parseInt(s,10)||0,u=l+c,m=u>0?Math.round(l/u*100):0,h=u>0?Math.round(c/u*100):0;let p;if(e){const t=`Ambiten:${e}:*`;let n=0,i=0;do{const e=await d.redis.scan(n,{MATCH:t,COUNT:100}),o=Array.isArray(e)?Number(e[0]):0,a=Array.isArray(e)?e[1]:[];Array.isArray(a)&&(i+=a.length),n=o}while(0!==n);p=i}return{totalKeys:i,tenantKeys:p,memoryUsageMb:Math.round(a/1024/1024),memoryUsageBytes:a,hitRate:m,missRate:h,totalHits:l,totalMisses:c,totalRequests:u,tenantId:e??null,timestamp:(new Date).toISOString()}}catch(e){const t=e instanceof Error?e.message:String(e);throw new Error(`Failed to get cache stats: ${t}`)}}async runCommand(e,...t){await this.init();const n={[e]:1,...t};return(await this.getCollection()).db.command(n)}async runGC(e){await this.init();const t=this.resolveSchemaGCConfig();if(t&&t.ttlField&&t.expiresIn)return this.runWithModelContext(e,async()=>(0,h.measureQuery)({operation:"runGC",collectionName:this.resolveCollectionName(e)},async()=>{const n=this.resolveCollectionName(e),i=this.resolveSession(e),o=await this.getCollection(e),a=this.buildMiddlewareContext("runGC",e,{meta:{gc:!0}});a.collectionName=a.collectionName??n,await this.runBeforeMiddlewares("runGC",a);const r=new Date(Date.now()-Number(t.expiresIn)),s={[t.ttlField]:{$lt:r}},l=a.filter??s;a.filter=l;const c=await o.find(l,i?{session:i}:void 0).toArray();if(0===c.length)return a.result={scanned:0,affected:0,archived:0,deleted:0,softDeleted:0},void await this.runAfterMiddlewares("runGC",a);let d=0,m=0,h=0;if(t.softDelete){const e={$set:{deletedAt:new Date,isDeleted:!0}};await this.schema.executePre("updateMany",{operation:"runGC",collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,filter:l,update:e,docs:c,meta:{...a.meta??{},gc:!0,softDelete:!0}}),h=(await o.updateMany(l,e,i?{session:i}:void 0)).modifiedCount,await this.schema.executePost("updateMany",{operation:"runGC",collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,filter:l,update:e,docs:c,result:{scanned:c.length,affected:h,archived:0,deleted:0,softDeleted:h},meta:{...a.meta??{},gc:!0,softDelete:!0}})}else{if(t.archiveBeforeDelete){const e=c.map(e=>({...e,_archivedAt:new Date,_from:o.collectionName}));await o.db.collection("Ambiten_archives").insertMany(e,i?{session:i}:void 0),d=e.length}await this.schema.triggerMiddleware("pre","deleteMany",{operation:"runGC",collectionName:a.collectionName,docs:c}),await this.schema.executePre("deleteMany",{operation:"runGC",collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,docs:c,result:this.toModelResults(c),meta:{...a.meta??{},gc:!0}}),m=(await o.deleteMany(l,i?{session:i}:void 0)).deletedCount??0,await this.schema.triggerMiddleware("post","deleteMany",{operation:"runGC",collectionName:a.collectionName,docs:c}),await this.schema.executePost("deleteMany",{operation:"runGC",collectionName:a.collectionName,tenantId:a.tenantId,dbName:a.dbName,session:i,docs:c,result:{scanned:c.length,affected:m,archived:d,deleted:m,softDeleted:0},meta:{...a.meta??{},gc:!0}})}const p={scanned:c.length,affected:h||m,archived:d,deleted:m,softDeleted:h};a.result=p,await this.runAfterMiddlewares("runGC",a),await this.invalidateCachePatterns("runGC",a),await f.publish(`${u.DB_CHANGE_EVENT}`,{garbageCollection:{action:"runGC",collectionName:a.collectionName,...p,meta:{...a.meta??{},gc:!0}}})}))}startAutoGC(e=36e5){setInterval(()=>this.runGC().catch(console.error),e)}resolveInstrumentationContext(e){const t=m.AmbitenContext.get(),n=this.mergeCtx(e);return{tenantId:n?.tenantId,dbName:n?.dbName,collectionName:n?.collectionName??this._collectionName,session:n?.session,requestId:t.requestId}}buildOperationMeta(e,t){return{...e??{},...t??{},extra:{...e?.extra??{},...t?.extra??{}}}}buildHookPayload(e,t,n={}){const i=this.resolveInstrumentationContext(t);return{operation:e,collectionName:n.collectionName??i.collectionName,tenantId:n.tenantId??i.tenantId,dbName:n.dbName??i.dbName,session:n.session??i.session,filter:n.filter,update:n.update,doc:n.doc,docs:n.docs,pipeline:n.pipeline,result:n.result,meta:n.meta}}resolveCache(e){return e?.cache?{get:async(e,t)=>{try{const t=await d.redis.get(e);if(!t)return await g.trackCacheMiss(),null;const n=JSON.parse(t);return await g.trackCacheHit(),n}catch{return null}},set:async(e,t,n)=>{try{const i=n?.ttlSeconds??300;await d.redis.set(e,JSON.stringify(t),{EX:i})}catch{}}}:null}buildCacheKey(e,t){const n=String(t.tenantId??"default"),i=String(t.dbName??"default"),o=String(t.collectionName??this._collectionName),{tenantId:a,dbName:r,collectionName:s,...l}=t,c=this.sortObjectDeep(l);return`Ambiten:${n}:${i}:${o}:${e}:${JSON.stringify(c)}`}static async trackCacheMiss(){try{const e=(new Date).toISOString().slice(0,10),t=604800,n=d.redis.multi();n.incr("Ambiten:cache:stats:misses"),n.incr(`Ambiten:cache:stats:misses:${e}`),n.expire(`Ambiten:cache:stats:misses:${e}`,t),await n.exec()}catch{}}static async trackCacheHit(){try{const e=(new Date).toISOString().slice(0,10),t=604800,n=d.redis.multi();n.incr("Ambiten:cache:stats:hits"),n.incr(`Ambiten:cache:stats:hits:${e}`),n.expire(`Ambiten:cache:stats:hits:${e}`,t),await n.exec()}catch{}}static async cacheResult(e,t,n=3600){if("string"!=typeof e||0===e.trim().length)throw new Error("Cache key must be a non-empty string.");if(!Number.isFinite(n)||n<=0)throw new Error("TTL must be a positive number.");try{await d.redis.set(e,JSON.stringify(t)),await d.redis.expire(e,n)}catch{}}static async clearCache(e){if(!e||"string"!=typeof e)throw new Error("Cache key must be a non-empty string");try{await d.redis.del(e)}catch(t){throw console.error("Error clearing cache:",t),new Error(`Failed to clear cache for key "${e}": ${t}`)}}async warmCache(e,t=3600,n){if(await this.init(),!Number.isFinite(t)||t<=0)throw new Error("Default TTL must be a positive number.");return this.runWithModelContext(n,async()=>{const i=this.resolveCache({cache:{ttl:t}});if(!i)return;const o=this.resolveInstrumentationContext(n),a=await this.getCollection(n),r=this.resolveSession(n),s=e&&e.length>0?e:[{filter:{},ttl:t}];if(e&&0!==e.length||!(await a.countDocuments({},r?{session:r}:void 0)>1e3))for(const e of s){const n=e.filter??{},s=e.ttl??t,l=await a.find(n,r?{session:r}:void 0).toArray(),c=this.toModelResults(l),d=this.buildCacheKey("find",{collectionName:o.collectionName,filter:n,tenantId:o.tenantId,dbName:o.dbName});await i.set(d,c,{ttlSeconds:s,tenantId:o.tenantId,namespace:o.collectionName})}})}sortObjectDeep(e){return Array.isArray(e)?e.map(e=>this.sortObjectDeep(e)):e instanceof Date?e.toISOString():e&&"object"==typeof e?Object.keys(e).sort().reduce((t,n)=>(t[n]=this.sortObjectDeep(e[n]),t),{}):e}toModelResult(e){const{_id:t,...n}=e;return{...n,_id:t.toString()}}toModelResults(e=[]){return e.map(e=>this.toModelResult(e))}async restoreOne(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"restoreOne",collectionName:this.resolveCollectionName(t),filter:e},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a={restore:!0},r=this.buildMiddlewareContext("restoreOne",t,{filter:e,meta:a});r.collectionName=r.collectionName??n,await this.runBeforeMiddlewares("restoreOne",r);const s=r.filter??e;r.filter=s;const l=this.buildRestoreUpdate();if(!await o.findOne(s,i?{session:i}:void 0))return r.result=null,void await this.runAfterMiddlewares("restoreOne",r);await this.schema.executePre("restoreOne",{operation:"restoreOne",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:i,filter:s,update:l,meta:a});const c=await o.updateOne(s,l,i?{session:i}:void 0),d=await o.findOne(s,i?{session:i}:void 0),m={acknowledged:c.acknowledged,matchedCount:c.matchedCount,modifiedCount:c.modifiedCount,upsertedCount:c.upsertedCount,upsertedId:c.upsertedId,restored:d?this.toModelResult(d):null};await this.schema.executePost("restoreOne",{operation:"restoreOne",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:i,filter:s,update:l,result:m,meta:a}),r.result=m,await this.runAfterMiddlewares("restoreOne",r),await this.invalidateCachePatterns("restoreOne",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentRestored:{action:"restoreOne",collectionName:r.collectionName,filter:s,result:m,meta:a}})}))}async restoreMany(e,t){if(await this.init(),!e||"object"!=typeof e)throw new Error("Filter must be a valid object.");return this.runWithModelContext(t,async()=>(0,h.measureQuery)({operation:"restoreMany",collectionName:this.resolveCollectionName(t),filter:e},async()=>{const n=this.resolveCollectionName(t),i=this.resolveSession(t),o=await this.getCollection(t),a={restore:!0},r=this.buildMiddlewareContext("restoreMany",t,{filter:e,meta:a});r.collectionName=r.collectionName??n,await this.runBeforeMiddlewares("restoreMany",r);const s=r.filter??e;r.filter=s;const l=this.buildRestoreUpdate(),c=await o.find(s,i?{session:i}:void 0).toArray();if(0===c.length)return r.result={restoredCount:0,docs:[]},void await this.runAfterMiddlewares("restoreMany",r);await this.schema.executePre("updateMany",{operation:"restoreMany",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:i,filter:s,update:l,docs:c,meta:a});const d=await o.updateMany(s,l,i?{session:i}:void 0),m=await o.find(s,i?{session:i}:void 0).toArray(),h={acknowledged:d.acknowledged,matchedCount:c.length,modifiedCount:d.modifiedCount,restoredCount:d.modifiedCount,docs:this.toModelResults(m)};await this.schema.executePost("updateMany",{operation:"restoreMany",collectionName:r.collectionName,tenantId:r.tenantId,dbName:r.dbName,session:i,filter:s,update:l,docs:m,result:h,meta:a}),r.result=h,await this.runAfterMiddlewares("restoreMany",r),await this.invalidateCachePatterns("restoreMany",r),await f.publish(`${u.DB_CHANGE_EVENT}`,{documentRestored:{action:"restoreMany",collectionName:r.collectionName,filter:s,result:h,meta:a}})}))}buildRestoreUpdate(){const e=this._softDeleteConfig?.deletedAtField??"deletedAt",t=this._softDeleteConfig?.isDeletedField??"isDeleted";return{$set:{[e]:null,[t]:!1}}}buildMiddlewareContext(e,t,n={}){const i=this.mergeCtx(t);return{operation:e,modelName:this.constructor.name,collectionName:n.collectionName??i?.collectionName??this._collectionName,tenantId:n.tenantId??i?.tenantId,dbName:n.dbName??i?.dbName,session:n.session??i?.session,withDeleted:n.withDeleted??i?.withDeleted,onlyDeleted:n.onlyDeleted??i?.onlyDeleted,hardDelete:n.hardDelete??i?.hardDelete,filter:n.filter,update:n.update,doc:n.doc,docs:n.docs,pipeline:n.pipeline,bulkUpdates:n.bulkUpdates,bulkOperations:n.bulkOperations,result:n.result,meta:n.meta}}setSoftDeleteConfig(e){this._softDeleteConfig=e}buildSoftDeleteUpdate(){const e=this._softDeleteConfig?.deletedAtField??"deletedAt",t=this._softDeleteConfig?.isDeletedField??"isDeleted";return{$set:{[e]:new Date,[t]:!0}}}async runBeforeMiddlewares(e,t){const n=this.beforeMiddlewares.get(e)??[];for(const e of n)await e(t)}async runAfterMiddlewares(e,t){const n=this.afterMiddlewares.get(e)??[];for(const e of n)await e(t)}before(e,t){const n=this.beforeMiddlewares.get(e)??[];return n.push(t),this.beforeMiddlewares.set(e,n),this}after(e,t){const n=this.afterMiddlewares.get(e)??[];return n.push(t),this.afterMiddlewares.set(e,n),this}beforeFind(e){return this.before("find",e)}afterFind(e){return this.after("find",e)}beforeFindOne(e){return this.before("findOne",e)}afterFindOne(e){return this.after("findOne",e)}beforeSave(e){return this.before("create",e)}afterSave(e){return this.after("create",e)}beforeUpdateOne(e){return this.before("updateOne",e)}afterUpdateOne(e){return this.after("updateOne",e)}beforeDeleteOne(e){return this.before("deleteOne",e)}afterDeleteOne(e){return this.after("deleteOne",e)}beforeDeleteMany(e){return this.before("deleteMany",e)}afterDeleteMany(e){return this.after("deleteMany",e)}beforeBulkInsert(e){return this.before("bulkInsert",e)}afterBulkInsert(e){return this.after("bulkInsert",e)}beforeBulkUpdate(e){return this.before("bulkUpdate",e)}afterBulkUpdate(e){return this.after("bulkUpdate",e)}beforeAggregate(e){return this.before("aggregate",e)}afterAggregate(e){return this.after("aggregate",e)}beforeFindOneAndUpdate(e){return this.before("findOneAndUpdate",e)}afterFindOneAndUpdate(e){return this.after("findOneAndUpdate",e)}beforeFindOneAndDelete(e){return this.before("findOneAndDelete",e)}afterFindOneAndDelete(e){return this.after("findOneAndDelete",e)}beforeFindOneAndReplace(e){return this.before("findOneAndReplace",e)}afterFindOneAndReplace(e){return this.after("findOneAndReplace",e)}beforeFindOneAndUpsert(e){return this.before("findOneAndUpsert",e)}afterFindOneAndUpsert(e){return this.after("findOneAndUpsert",e)}}t.AmbitenModel=g},9528(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9647(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9729(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(1332),t),i.__exportStar(n(6438),t),i.__exportStar(n(3803),t)},9831(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9881(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(5584);i.__exportStar(n(2992),t),i.__exportStar(n(7234),t)},9896(e){"use strict";e.exports=require("fs")}},t={};function n(i){var o=t[i];if(void 0!==o)return o.exports;var a=t[i]={id:i,loaded:!1,exports:{}};return e[i](a,a.exports,n),a.loaded=!0,a.exports}n.c=t,n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),n(n.s=3206)})();
|
|
26
|
+
//# sourceMappingURL=index-cli.js.map
|