@ambiten/core 1.0.0 → 1.0.1

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/dist/index-cli.js CHANGED
@@ -1,5 +1,5 @@
1
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`${e}`;case"green":return`${e}`;case"magenta":return`${e}`;case"cyan":return`${e}`;case"yellow":return`${e}`;case"blue":return`${e}`}return`${e}`}},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`
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`${e}`;case"green":return`${e}`;case"magenta":return`${e}`;case"cyan":return`${e}`;case"yellow":return`${e}`;case"blue":return`${e}`}return`${e}`}},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.measureQueryForBrowser=t.AmbitenBootstrapFactory=t.AmbitenSchema=t.AmbitenModel=t.createAmbitenClientModule=t.AmbitenClient=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);var a=n(1679);Object.defineProperty(t,"AmbitenClient",{enumerable:!0,get:function(){return a.AmbitenClient}}),Object.defineProperty(t,"createAmbitenClientModule",{enumerable:!0,get:function(){return a.createAmbitenClientModule}});var r=n(9493);Object.defineProperty(t,"AmbitenModel",{enumerable:!0,get:function(){return r.AmbitenModel}});var s=n(6903);Object.defineProperty(t,"AmbitenSchema",{enumerable:!0,get:function(){return s.AmbitenSchema}});var l=n(2999);Object.defineProperty(t,"AmbitenBootstrapFactory",{enumerable:!0,get:function(){return l.AmbitenBootstrapFactory}});var c=n(3907);Object.defineProperty(t,"measureQueryForBrowser",{enumerable:!0,get:function(){return c.measureQueryForBrowser}})},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 C=a.default.join(e,"package.json");await o.default.writeJson(C,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(C);const _=a.default.join(e,"tsconfig.json");await o.default.writeJson(_,{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(_);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
3
  scalar JSON
4
4
 
5
5
  type Document {